<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      .NET性能優化-使用內存+磁盤混合緩存

      我們回顧一下上一篇文章中的內容,有一個朋友問我這樣一個問題:

      我的業務依賴一些數據,因為數據庫訪問慢,我把它放在Redis里面,不過還是太慢了,有什么其它的方案嗎?

      其實這個問題比較簡單的是吧?Redis其實屬于網絡存儲,我對照下面的這個表格,可以很容易的得出結論,既然網絡存儲的速度慢,那我們就可以使用內存RAM存儲,把放Redis里面的數據給放內存里面就好了。

      操作 速度
      執行指令 1/1,000,000,000 秒 = 1 納秒
      從一級緩存讀取數據 0.5 納秒
      分支預測失敗 5 納秒
      從二級緩存讀取數據 7 納秒
      使用Mutex加鎖和解鎖 25 納秒
      從主存(RAM內存)中讀取數據 100 納秒
      在1Gbps速率的網絡上發送2Kbyte的數據 20,000 納秒
      從內存中讀取1MB的數據 250,000 納秒
      磁頭移動到新的位置(代指機械硬盤) 8,000,000 納秒
      從磁盤中讀取1MB的數據 20,000,000 納秒
      發送一個數據包從美國到歐洲然后回來 150 毫秒 = 150,000,000 納秒

      提出這個方案以后,接下來就遇到了另外一個問題:

      但是數據比我應用的內存大,這怎么辦呢?

      在上篇文章中,我們提到了使用FASTER作為內存+磁盤混合緩存的方案,但是由于FASTER的API比較難使用,另外在純內存場景中表現不如ConcurrentDictionary,所以最后得出的結論也是僅供參考。

      經過一段時間的研究,筆者實現了一個基于微軟FasterKv封裝的進程內混合緩存庫(內存+磁盤),它有著更加易用的API,接下來就和大家討論討論它。

      FasterKvCache架構

      這里需要簡單的說一說FasterKvCache的架構,它核心使用的FasterKv,所以架構實際上和FasterKv一致,其原理比較復雜,所以筆者簡化了原理圖,大概就如下所示:

      FasterKv的熱數據會在內存中,而全量的數據會持久化在磁盤中。這中間有一些緩存淘汰算法,所以大家看到這張圖就能明白FasterKvCache適用和不適用哪些場景了。

      如何使用它

      筆者之前給EasyCaching提交了FasterKv的實現,但是由于有一些EasyCaching的高級功能在FasterKv上目前無法高性能的實現,所以單獨創建了這個庫,提供高性能和最基本的API實現;如果大家已經使用了EasyCaching,那么可以直接使用EasyCaching.FasterKv這個NuGet包。

      如果使用需要FasterKvCache的話,只需要安裝Nuget包,Nuget包不同的功能如下所示,其中序列化包可以只安裝自己需要的即可。

      軟件包名 版本 備注
      FasterKv.Cache.Core 1.0.0-rc1 緩存核心包,包含FasterKvCache主要的API
      FasterKv.Cache.MessagePack 1.0.0-rc1 基于MessagePack的磁盤序列化包,它具有著非常好的性能,但是需要注意它稍微有一點使用門檻,大家可以看它的文檔。
      FasterKv.Cache.SystemTextJson 1.0.0-rc1 基于System.Text.Json的磁盤序列化包,它是.NET平臺上性能最好JSON序列化封裝,但是比MessagePack差。不過它易用性非常好,無需對緩存實體進行單獨配置。

      使用

      直接使用

      我們可以直接通過new FasterKvCache(...)的方式使用它,目前它只支持基本的三種操作GetSetDelete。為了方便使用和性能的考慮,我們將FasterKvCache分為兩種API風格,一種是通用對象風格,一種是泛型風格。

      • 通用對象:直接使用new FasterKvCache(...)創建,可以存放任意類型的Value。它底層使用object類型存儲,所以內存緩沖內訪問值類型對象會有裝箱和拆箱的開銷。
      • 泛型:需要使用new FasterKvCache<T>(...)創建,只能存放T類型的Value。它底層使用T類型存儲,所以內存緩沖內不會有任何開銷。

      當然如果內存緩沖不夠,對應的Value被淘汰到磁盤上,那么同樣都會有讀寫磁盤、序列化和反序列化開銷。

      通用對象版本

      代碼如下所示,同一個cache實例可以添加任意類型:

      using FasterKv.Cache.Core;
      using FasterKv.Cache.Core.Configurations;
      using FasterKv.Cache.MessagePack;
      
      // create a FasterKvCache
      var cache = new FasterKv.Cache.Core.FasterKvCache("MyCache",
          new DefaultSystemClock(),
          new FasterKvCacheOptions(),
          new IFasterKvCacheSerializer[]
          {
              new MessagePackFasterKvCacheSerializer
              {
                  Name = "MyCache"
              }
          },
          null);
      
      var key = Guid.NewGuid().ToString("N");
      
      // sync 
      // set key and value with expiry time
      cache.Set(key, "my cache sync", TimeSpan.FromMinutes(5));
      
      // get
      var result = cache.Get<string>(key);
      Console.WriteLine(result);
      
      // delete
      cache.Delete(key);
      
      // async
      // set
      await cache.SetAsync(key, "my cache async");
      
      // get
      result = await cache.GetAsync<string>(key);
      Console.WriteLine(result);
      
      // delete
      await cache.DeleteAsync(key);
      
      // set other type object
      cache.Set(key, new DateTime(2022,2,22));
      Console.WriteLine(cache.Get<DateTime>(key));
      

      輸出結果如下所示:

      my cache sync
      my cache async
      2022/2/22 0:00:00
      
      泛型版本

      泛型版本的話性能最好,但是它只允許添加一個類型,否則代碼將編譯不通過:

      // create a FasterKvCache<T> 
      // only set T type value
      var cache = new FasterKvCache<string>("MyTCache",
          new DefaultSystemClock(),
          new FasterKvCacheOptions(),
          new IFasterKvCacheSerializer[]
          {
              new MessagePackFasterKvCacheSerializer
              {
                  Name = "MyTCache"
              }
          },
          null);
      

      Microsoft.Extensions.DependencyInjection

      當然,我們也可以直接使用依賴注入的方式使用它,用起來也非常簡單。按照通用和泛型版本的區別,我們使用不同的擴展方法即可:

      var services = new ServiceCollection();
      // use AddFasterKvCache
      services.AddFasterKvCache(options =>
      {
          // use MessagePack serializer
          options.UseMessagePackSerializer();
      }, "MyKvCache");
      
      var provider = services.BuildServiceProvider();
      
      // get instance do something
      var cache = provider.GetService<FasterKvCache>();
      

      泛型版本需要調用相應的AddFasterKvCache<T>方法:

      var services = new ServiceCollection();
      // use AddFasterKvCache<string>
      services.AddFasterKvCache<string>(options =>
      {
          // use MessagePack serializer
          options.UseMessagePackSerializer();
      }, "MyKvCache");
      
      var provider = services.BuildServiceProvider();
      
      // get instance do something
      var cache = provider.GetService<FasterKvCache<string>>();
      

      配置

      FasterKvCache構造函數

      public FasterKvCache(
          string name,	// 如果存在多個Cache實例,定義一個名稱可以隔離序列化等配置和磁盤文件
          ISystemClock systemClock,	// 當前系統時鐘,new DefaultSystemClock()即可
          FasterKvCacheOptions? options,	// FasterKvCache的詳細配置,詳情見下文
          IEnumerable<IFasterKvCacheSerializer>? serializers,	// 序列化器,可以直接使用MessagePack或SystemTextJson序列化器
          ILoggerFactory? loggerFactory)	// 日志工廠 用于記錄FasterKv內部的一些日志信息
      

      FasterKvCacheOptions 配置項

      對于FasterKvCache,有著和FasterKv差不多的配置項,更詳細的信息大家可以看FasterKv-Settings,下方是FasterKvCache的配置:

      • IndexCount:FasterKv會維護一個hash索引池,IndexCount就是這個索引池的hash槽數量,一個槽為64bit。需要配置為2的次方。如1024(2的10次方)、 2048(2的11次方)、65536(2的16次方) 、131072(2的17次方)。默認槽數量為131072,占用1024kb的內存。
      • MemorySizeBit: FasterKv用來保存Log的內存字節數,配置為2的次方數。默認為24,也就是2的24次方,使用16MB內存。
      • PageSizeBit:FasterKv內存頁的大小,配置為2的次方數。默認為20,也就是2的20次方,每頁大小為1MB內存。
      • ReadCacheMemorySizeBit:FasterKv讀緩存內存字節數,配置為2的次方數,緩存內的都是熱點數據,最好設置為熱點數據所占用的內存數量。默認為20,也就是2的20次方,使用16MB內存。
      • ReadCachePageSizeBit:FasterKv讀緩存內存頁的大小,配置為2的次方數。默認為20,也就是2的20次方,每頁大小為1MB內存。
      • LogPath:FasterKv日志文件的目錄,默認會創建兩個日志文件,一個以.log結尾,一個以obj.log結尾,分別存放日志信息和Value序列化信息,注意,不要讓不同的FasterKvCache使用相同的日志文件,會出現不可預料異常默認為{當前目錄}/FasterKvCache/{進程Id}-HLog/{實例名稱}.log
      • SerializerName:Value序列化器名稱,需要安裝序列化Nuget包,如果沒有單獨指定Name的情況下,可以使用MessagePackSystemTextJson默認無需指定
      • ExpiryKeyScanInterval:由于FasterKv不支持過期刪除功能,所以目前的實現是會定期掃描所有的key,將過期的key刪除。這里配置的就是掃描間隔。默認為5分鐘
      • CustomStore:如果您不想使用自動生成的實例,那么可以自定義的FasterKv實例。默認為null

      所以FasterKvCache所占用的內存數量基本就是(IndexCount*64)+(MemorySize)+ReadCacheMemorySize,當然如果Key的數量過多,那么還有加上OverflowBucketCount * 64

      容量規劃

      從上面提到的內容大家可以知道,FasterKvCache所占用的內存字節基本就是(IndexCount * 64)+(MemorySize) + ReadCacheMemorySize + (OverflowBucketCount * 64)。磁盤的話就是保存了所有的數據+對象序列化的數據,由于不同的序列化協議有不同的大小,大家可以先進行測試。

      內存數據存儲到FasterKv存儲引擎,每個key都會額外元數據信息,存儲空間占用會有一定的放大,建議在磁盤空間選擇上,留有適當余量,按實際存儲需求的 1.2 - 1.5倍預估。

      如果使用內存存儲 100GB 的數據,總的訪問QPS不到2W,其中80%的數據都很少訪問到。那么可以使用 【32GB內存 + 128GB磁盤】 存儲,節省了近 70GB 的內存存儲,內存成本可以下降50%+。

      性能

      目前作者還沒有時間將FasterKvCache和其它主流的緩存庫進行比對,現在只對FasterKvCache、EasyCaching.FasterKv和EasyCaching.Sqlite做的比較。下面是FasterKVCache的配置,總占用約為2MB。

      services.AddFasterKvCache<string>(options =>
      {
          options.IndexCount = 1024;
          options.MemorySizeBit = 20;
          options.PageSizeBit = 20;
          options.ReadCacheMemorySizeBit = 20;
          options.ReadCachePageSizeBit = 20;
          // use MessagePack serializer
          options.UseMessagePackSerializer();
      }, "MyKvCache");
      

      由于作者筆記本性能不夠,使用Sqlite無法在短期內完成100W、1W個Key的性能測試,所以我們在默認設置下將數據集大小設置為1000個Key,設置50%的熱點Key。進行100%讀、100%寫和50%讀寫隨機比較。

      可以看到無論是讀、寫還是混合操作FasterKvCache都有著不俗的性能,在8個線程情況下,TPS達到了驚人的1600w/s

      緩存 類型 線程數 Mean(us) Error(us) StdDev(us) Gen0 Gen1 Allocated
      fasterKvCache Read 8 59.95 3.854 2.549 1.5259 7.02 NULL
      fasterKvCache Write 8 63.67 1.032 0.683 0.7935 3.63 NULL
      fasterKvCache Random 4 64.42 1.392 0.921 1.709 8.38 NULL
      fasterKvCache Read 4 64.67 0.628 0.374 2.5635 11.77 NULL
      fasterKvCache Random 8 64.80 3.639 2.166 1.0986 5.33 NULL
      fasterKvCache Write 4 65.57 3.45 2.053 0.9766 4.93 NULL
      fasterKv Read 8 92.15 10.678 7.063 5.7373 - 26.42 KB
      fasterKv Write 4 99.49 2 1.046 10.7422 - 49.84 KB
      fasterKv Write 8 108.50 5.228 3.111 5.6152 - 25.93 KB
      fasterKv Read 4 109.37 1.476 0.772 10.9863 - 50.82 KB
      fasterKv Random 8 119.94 14.175 9.376 5.7373 - 26.18 KB
      fasterKv Random 4 124.31 6.191 4.095 10.7422 - 50.34 KB
      fasterKvCache Read 1 207.77 3.307 1.73 9.2773 43.48 NULL
      fasterKvCache Random 1 208.71 1.832 0.958 6.3477 29.8 NULL
      fasterKvCache Write 1 211.26 1.557 1.03 3.418 16.13 NULL
      fasterKv Write 1 378.60 17.755 11.744 42.4805 - 195.8 KB
      fasterKv Read 1 404.57 17.477 11.56 43.457 - 199.7 KB
      fasterKv Random 1 441.22 14.107 9.331 42.9688 - 197.75 KB
      sqlite Read 8 7450.11 260.279 172.158 54.6875 7.8125 357.78 KB
      sqlite Read 4 14309.94 289.113 172.047 109.375 15.625 718.9 KB
      sqlite Read 1 56973.53 1,774.35 1,173.62 400 100 2872.18 KB
      sqlite Random 8 475535.01 214,015.71 141,558.14 - - 395.15 KB
      sqlite Random 4 1023524.87 97,993.19 64,816.43 - - 762.46 KB
      sqlite Write 8 1153950.84 48,271.47 28,725.58 - - 433.7 KB
      sqlite Write 4 2250382.93 110,262.72 72,931.96 - - 867.7 KB
      sqlite Write 1 4200783.08 43,941.69 29,064.71 - - 3462.89 KB
      sqlite Random 1 5383716.10 195,085.96 129,037.28 - - 2692.09 KB

      總結

      可以看到FasterKvCache有著不俗的性能,目前也在筆者朋友的項目使用上了,反饋不錯,解決了他的緩存問題。由于現在還只是1.0.0-rc1版本,還有很多特性沒有實現。可能有一些BUG還存在,歡迎大家試用和反饋問題。

      Github開源地址:
      https://github.com/InCerryGit/FasterKvCache

      參考鏈接

      https://developer.aliyun.com/article/740811

      posted @ 2022-11-22 09:29  InCerry  閱讀(4121)  評論(19)    收藏  舉報
      主站蜘蛛池模板: 九九久久自然熟的香蕉图片| 国产普通话对白刺激| 丰满少妇69激情啪啪无| 沈阳市| 性欧美VIDEOFREE高清大喷水| 动漫av网站免费观看| 日韩欧美在线综合网另类| 精品粉嫩国产一区二区三区| 日韩丝袜欧美人妻制服| 黄网站色视频免费观看| 精品一区二区亚洲国产| 熟女少妇精品一区二区| 国产午夜亚洲精品一区| 人摸人人人澡人人超碰97| 国产伦精品一区二区亚洲| 亚洲精品中文字幕第一页| 99国产欧美另类久久久精品| 俺来也俺去啦最新在线| 成人免费亚洲av在线| 亚洲成人精品在线伊人网| 东京热大乱系列无码| 国产日韩精品一区在线不卡| 成年入口无限观看免费完整大片| 乱人伦人妻中文字幕在线| 亚洲另类无码一区二区三区| 午夜成人性爽爽免费视频| 国产精品无遮挡又爽又黄| 丰满人妻熟妇乱精品视频| aa性欧美老妇人牲交免费| 久久精品夜色国产亚洲av| 男人狂桶女人高潮嗷嗷| 峡江县| 亚洲日本va午夜中文字幕久久| 精品无码老熟妇magnet| 亚洲欧美日韩国产四季一区二区三区| 7878成人国产在线观看| 国内不卡的一区二区三区| 亚洲国产成人综合精品| 国产中年熟女大集合| 91精品蜜臀国产综合久久| 亚洲一区二区精品极品|