日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

DotNetCore三大Redis客户端对比和使用心得

發(fā)布時(shí)間:2023/12/4 数据库 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DotNetCore三大Redis客户端对比和使用心得 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

稍微復(fù)雜一點(diǎn)的互聯(lián)網(wǎng)項(xiàng)目,技術(shù)選型都會(huì)涉及Redis,.NetCore的生態(tài)越發(fā)完善,支持.NetCore的Redis客戶端越來越多,

下面三款常見的Redis客戶端,相信大家平時(shí)或多或少用到一些,結(jié)合三款客戶端的使用經(jīng)歷,有些心得體會(huì)。

先比較宏觀的背景:

使用心得

三款客戶端Redis支持的連接字符串配置基本相同

"connectionstrings": {"redis": "localhost:6379,password=abcdef,connectTimeout=5000,writeBuffer=40960"}
1. StackExchange.Redis

定位是高性能、通用的Redis .Net客戶端;方便地應(yīng)用Redis全功能;支持Redis Cluster

  • 高性能的核心在于:多路復(fù)用連接(允許有效使用來自多個(gè)調(diào)用線程的共享連接), 服務(wù)器端操作使用ConnectionMultiplexer類

ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("server1:6379,server2:6379"); // 日常應(yīng)用的核心類庫是IDatabase IDatabase db = redis.GetDatabase();// 支持Pub/Sub ISubscriber sub = redis.GetSubscriber(); sub.Subscribe("messages", (channel, message) => {Console.WriteLine((string)message); }); --- sub.Publish("messages", "hello");

也正是因?yàn)槎嗦窂?fù)用,StackExchange.Redis唯一不支持的Redis特性是 "blocking pops",這個(gè)特性是RedisMQ的關(guān)鍵理論。如果你需要blocking pops, StackExchange.Redis官方推薦使用pub/sub模型模擬實(shí)現(xiàn)。

  • 日常操作API請(qǐng)關(guān)注IDatabase接口,支持異步方法,這里我對(duì)【客戶端操作Redis盡量不要使用異步方法】的說法不敢茍同,對(duì)于異步方法我認(rèn)為還是遵守微軟最佳實(shí)踐:對(duì)于IO密集的操作,能使用異步盡量使用異步

// 對(duì)應(yīng)redis自增api:DECR mykey _redisDB0.StringDecrementAsync("ProfileUsageCap", (double)1) // 對(duì)應(yīng)redis api:HGET KEY field1 _redisDB0.HashGetAsync(profileUsage, eqidPair.ProfileId))        // 對(duì)應(yīng)redis哈希自增api:HINCRBY myhash field -1 _redisDB0.HashDecrementAsync(profileUsage, eqidPair.ProfileId, 1)
  • ConnectionMultiplexer 方式支持隨時(shí)切換Redis DB,對(duì)于多個(gè)Redis DB的操作,我封裝了一個(gè)常用的Redis DB 操作客戶端。

public class RedisStore{private static Lazy<ConnectionMultiplexer> LazyConnection;private static string connectionRedis = "localhost:6379";public RedisStore(string connectiontring){connectionRedis = connectiontring ?? "localhost:6379";LazyConnection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(connectionRedis));}public static ConnectionMultiplexer Connection => LazyConnection.Value;public RedisDatabase RedisCache => new RedisDatabase(Connection);}public class RedisDatabase{private Dictionary<int, IDatabase> DataBases = new Dictionary<int, IDatabase>();public ConnectionMultiplexer RedisConnection { get; }public RedisDatabase(ConnectionMultiplexer Connection){DataBases = new Dictionary<int, IDatabase>{ };for(var i=0;i<16;i++){DataBases.Add(i, Connection.GetDatabase(i));}RedisConnection = Connection;}public IDatabase this[int index]{get{if (DataBases.ContainsKey(index))return DataBases[index];elsereturn DataBases[0];}}}
2. Microsoft.Extensions.Caching.StackExchangeRedis

從nuget doc可知,該組件庫依賴于 StackExchange.Redis 客戶端;是.NetCore針對(duì)分布式緩存提供的客戶端,側(cè)重點(diǎn)在Redis的緩存特性

該庫是基于 IDistributedCache 接口實(shí)現(xiàn)的,該接口為實(shí)現(xiàn)分布式緩存的通用性,緩存內(nèi)容將以byte[] 形式讀寫 ;另外能使用的函數(shù)簽名也更傾向于【通用的 增、查操作】

// 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連接字符串一次性配置項(xiàng)目要使用哪個(gè)Redis DB

② 會(huì)在指定DB(默認(rèn)為0)生成key = SampleInstancecachedTimeUTC 的redis緩存項(xiàng)

③ 通用接口只支持bytes[] 形式傳值,以上byte[] 實(shí)際是以Hash的形式存儲(chǔ)

3. CSRedisCore

該組件是基于連接池模型,默認(rèn)配置會(huì)預(yù)熱50個(gè)redis連接。功能更靈活,針對(duì)實(shí)際Redis應(yīng)用場(chǎng)景有更多玩法。

  • 普通模式

  • 官方集群模式 redis cluster

  • 分區(qū)模式(作者實(shí)現(xiàn))

普通模式使用方法極其簡(jiǎn)單,這里要提示的是:該客戶端也不支持隨意切換Redis DB, 但是原作者給出一種緩解的方式:構(gòu)造多客戶端。

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);

內(nèi)置的靜態(tài)操作類RedisHelper, 與Redis-Cli 命令完全一致, 故能原生支持”blocking pops”。

// 實(shí)現(xiàn)后臺(tái)服務(wù),持續(xù)消費(fèi)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 需要實(shí)現(xiàn)的后臺(tái)任務(wù)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")}";// 阻塞式從右側(cè)讀取List首消息var eqidpair = RedisHelper.BRPop(5, key);// TODO Handler Messageelseawait Task.Delay(1000, stoppingToken);}}}-----RedisMQ 生產(chǎn)者--- // 將一個(gè)或多個(gè)msg插入List頭部 RedisHelper.LPush(redisKey, eqidPairs.ToArray());

以上三大客戶端,Microsoft.Extensions.Caching.StackExchangeRedis 與其他兩者的定位還是有很大差距的,單純使用Redis緩存特性, 有微軟出品,必屬精品情結(jié)的可使用此客戶端;
StackExchange.Redis、CSRedisCore 對(duì)于Redis全功能特性支持的比較全

Redis的一點(diǎn)小經(jīng)驗(yàn)

  • 對(duì)要使用的Redis API 的時(shí)間復(fù)雜度心里要有數(shù),盡量不要使用長時(shí)間運(yùn)行的命令如keys *,可通過redis.io SlowLog命令觀測(cè)哪些命令耗時(shí)較長

  • Redis Key可按照“:”分隔定義成有業(yè)務(wù)意義的字符串,如NewUsers:202004:666(某些Redis UI可直觀友好查看該鍵值)

  • 合適確定Key-Value的大小:Redis對(duì)于small value更友好, 如果值很大,考慮劃分到多個(gè)key

  • 關(guān)于緩存穿透,面試的時(shí)候會(huì)問,自行搜索布隆過濾器。

  • redis雖然有持久化機(jī)制,但在實(shí)際中會(huì)將key-value持久化到關(guān)系型數(shù)據(jù)庫,因?yàn)閷?duì)于某些結(jié)構(gòu)化查詢,SQL更為有效。

推薦閱讀

●?這么香的Chrome插件,你都安裝了嗎?

●?一文掌握Cookies前世今生

●?ASP.NET Core跨平臺(tái)技術(shù)內(nèi)幕

●?TPL Dataflow組件應(yīng)對(duì)高并發(fā),低延遲要求

●?實(shí)例解讀Docker Swarm

●?基于docker-compose的Gitlab CI/CD實(shí)踐&排坑指南

總結(jié)

以上是生活随笔為你收集整理的DotNetCore三大Redis客户端对比和使用心得的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。