DotNetCore三大Redis客户端对比和使用心得
前言
稍微復雜一點的互聯網項目,技術選型都會涉及Redis,.NetCore的生態越發完善,支持.NetCore的Redis客戶端越來越多,
下面三款常見的Redis客戶端,相信大家平時或多或少用到一些,結合三款客戶端的使用經歷,有些心得體會。
先比較宏觀的背景:
使用心得
三款客戶端Redis支持的連接字符串配置基本相同
"connectionstrings": {"redis": "localhost:6379,password=abcdef,connectTimeout=5000,writeBuffer=40960"}1. StackExchange.Redis
定位是高性能、通用的Redis .Net客戶端;方便地應用Redis全功能;支持Redis Cluster
高性能的核心在于:多路復用連接(允許有效使用來自多個調用線程的共享連接), 服務器端操作使用ConnectionMultiplexer類
也正是因為多路復用,StackExchange.Redis唯一不支持的Redis特性是 "blocking pops",這個特性是RedisMQ的關鍵理論。如果你需要blocking pops, StackExchange.Redis官方推薦使用pub/sub模型模擬實現。
日常操作API請關注IDatabase接口,支持異步方法,這里我對【客戶端操作Redis盡量不要使用異步方法】的說法不敢茍同,對于異步方法我認為還是遵守微軟最佳實踐:對于IO密集的操作,能使用異步盡量使用異步
ConnectionMultiplexer 方式支持隨時切換Redis DB,對于多個Redis DB的操作,我封裝了一個常用的Redis DB 操作客戶端。
2. Microsoft.Extensions.Caching.StackExchangeRedis
從nuget doc可知,該組件庫依賴于 StackExchange.Redis 客戶端;是.NetCore針對分布式緩存提供的客戶端,側重點在Redis的緩存特性。
該庫是基于 IDistributedCache 接口實現的,該接口為實現分布式緩存的通用性,緩存內容將以byte[] 形式讀寫 ;另外能使用的函數簽名也更傾向于【通用的 增、查操作】
// add Redis cache service services.AddStackExchangeRedisCache(options => {options.Configuration = Configuration.GetConnectionString("redis");options.InstanceName = "SampleInstance"; });// Set Cache Item (by byte[])lifetime.ApplicationStarted.Register(() => {var currentTimeUTC = DateTime.UtcNow.ToString();byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);var options = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(20));cache.Set("cachedTimeUTC", encodedCurrentTimeUTC, options); });// Retrieve Cache Item [HttpGet] [Route("CacheRedis")] public async Task<string> GetAsync() {var ret = "";var bytes = await _cache.GetAsync("cachedTimeUTC");if (bytes != null){ret = Encoding.UTF8.GetString(bytes);_logger.LogInformation(ret);}return await Task.FromResult(ret); }① 很明顯,該Cache組件并不能做到自由切換 Redis DB, 目前可在redis連接字符串一次性配置項目要使用哪個Redis DB
② 會在指定DB(默認為0)生成key = SampleInstancecachedTimeUTC 的redis緩存項
③ 通用接口只支持bytes[] 形式傳值,以上byte[] 實際是以Hash的形式存儲
3. CSRedisCore
該組件是基于連接池模型,默認配置會預熱50個redis連接。功能更靈活,針對實際Redis應用場景有更多玩法。
普通模式
官方集群模式 redis cluster
分區模式(作者實現)
普通模式使用方法極其簡單,這里要提示的是:該客戶端也不支持隨意切換Redis DB, 但是原作者給出一種緩解的方式:構造多客戶端。
var redisDB = new CSRedisClient[16]; // 多客戶端 for (var a = 0; a < redisDB.Length; a++)redisDB[a] = new CSRedisClient(Configuration.GetConnectionString("redis") + ",defaultDatabase=" + a); services.AddSingleton(redisDB); // ---------------------------- _redisDB[0].IncrByAsync("ProfileUsageCap", -1) _redisDB[0].HGetAsync(profileUsage, eqidPair.ProfileId.ToString()) _redisDB[0].HIncrByAsync(profileUsage, eqidPair.ProfileId.ToString(), -1);內置的靜態操作類RedisHelper, 與Redis-Cli 命令完全一致, 故能原生支持”blocking pops”。
// 實現后臺服務,持續消費MQ消息 public class BackgroundJob : BackgroundService{private readonly CSRedisClient[] _redisDB;private readonly IConfiguration _conf;private readonly ILogger _logger;public BackgroundJob(CSRedisClient[] csRedisClients,IConfiguration conf,ILoggerFactory loggerFactory){_redisDB = csRedisClients;_conf = conf;_logger = loggerFactory.CreateLogger(nameof(BackgroundJob));}// Background 需要實現的后臺任務protected override async Task ExecuteAsync(CancellationToken stoppingToken){_redisDB[0] = new CSRedisClient(_conf.GetConnectionString("redis") + ",defualtDatabase=" + 0);RedisHelper.Initialization(_redisDB[0]);while (!stoppingToken.IsCancellationRequested){var key = $"eqidpair:{DateTime.Now.ToString("yyyyMMdd")}";// 阻塞式從右側讀取List首消息var eqidpair = RedisHelper.BRPop(5, key);// TODO Handler Messageelseawait Task.Delay(1000, stoppingToken);}}}-----RedisMQ 生產者--- // 將一個或多個msg插入List頭部 RedisHelper.LPush(redisKey, eqidPairs.ToArray());以上三大客戶端,Microsoft.Extensions.Caching.StackExchangeRedis 與其他兩者的定位還是有很大差距的,單純使用Redis緩存特性, 有微軟出品,必屬精品情結的可使用此客戶端;
StackExchange.Redis、CSRedisCore 對于Redis全功能特性支持的比較全
Redis的一點小經驗
對要使用的Redis API 的時間復雜度心里要有數,盡量不要使用長時間運行的命令如keys *,可通過redis.io SlowLog命令觀測哪些命令耗時較長
Redis Key可按照“:”分隔定義成有業務意義的字符串,如NewUsers:202004:666(某些Redis UI可直觀友好查看該鍵值)
合適確定Key-Value的大小:Redis對于small value更友好, 如果值很大,考慮劃分到多個key
關于緩存穿透,面試的時候會問,自行搜索布隆過濾器。
redis雖然有持久化機制,但在實際中會將key-value持久化到關系型數據庫,因為對于某些結構化查詢,SQL更為有效。
推薦閱讀
●?這么香的Chrome插件,你都安裝了嗎?
●?一文掌握Cookies前世今生
●?ASP.NET Core跨平臺技術內幕
●?TPL Dataflow組件應對高并發,低延遲要求
●?實例解讀Docker Swarm
●?基于docker-compose的Gitlab CI/CD實踐&排坑指南
總結
以上是生活随笔為你收集整理的DotNetCore三大Redis客户端对比和使用心得的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解析“60k”大佬的19道C#面试题(下
- 下一篇: (译)创建.NET Core多租户应用程