91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

DotNetCore三大Redis客戶端對比和使用心得是什么

發布時間:2022-01-04 15:53:07 來源:億速云 閱讀:191 作者:柒染 欄目:大數據

本篇文章為大家展示了DotNetCore三大Redis客戶端對比和使用心得是什么,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。 

前言

稍微復雜一點的互聯網項目,技術選型都會涉及Redis,.NetCore的生態越發完善,支持.NetCore的Redis客戶端越來越多,

下面三款常見的Redis客戶端,相信大家平時或多或少用到一些,結合三款客戶端的使用經歷,有些心得體會。

先比較宏觀的背景:

DotNetCore三大Redis客戶端對比和使用心得是什么  
 

使用心得

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

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

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

  • 高性能的核心在于:     多路復用連接(允許有效使用來自多個調用線程的共享連接), 服務器端操作使用ConnectionMultiplexer類
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("server1:6379,server2:6379");
// 日常應用的核心類庫是IDatabase
IDatabase db = redis.GetDatabase();

// 支持Pub/Sub
ISubscriber sub = redis.GetSubscriber();
sub.Subscribe("messages", (channel, message) => {
   Console.WriteLine((string)message);
});
---
sub.Publish("messages", "hello");
 

也正是因為多路復用,StackExchange.Redis唯一不支持的Redis特性是 "blocking pops",這個特性是RedisMQ的關鍵理論。如果你需要blocking pops, StackExchange.Redis官方推薦使用pub/sub模型模擬實現。

  • 日常操作API請關注IDatabase接口,支持異步方法,這里我對【客戶端操作Redis盡量不要使用異步方法】的說法不敢茍同,對于異步方法我認為還是遵守微軟最佳實踐:對于IO密集的操作,能使用異步盡量使用異步
// 對應redis自增api:DECR mykey
_redisDB0.StringDecrementAsync("ProfileUsageCap", (double)1)
// 對應redis api:HGET KEY field1
_redisDB0.HashGetAsync(profileUsage, eqidPair.ProfileId))           
// 對應redis哈希自增api:HINCRBY myhash field -1
_redisDB0.HashDecrementAsync(profileUsage, eqidPair.ProfileId, 1)
 
  • ConnectionMultiplexer 方式支持隨時切換Redis DB,對于多個Redis DB的操作,我封裝了一個常用的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];
               else
                  return DataBases[0];
           }
       }
   }
   
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的形式存儲DotNetCore三大Redis客戶端對比和使用心得是什么

 
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 Message
               else
                   await 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更為有效。

上述內容就是DotNetCore三大Redis客戶端對比和使用心得是什么,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

石柱| 泰宁县| 宜章县| 堆龙德庆县| 新田县| 漠河县| 建湖县| 土默特右旗| 莱州市| 梧州市| 玉山县| 白河县| 台州市| 济阳县| 柞水县| 永丰县| 凯里市| 青州市| 凌海市| 彭水| 澄迈县| 中宁县| 富蕴县| 凤庆县| 麻阳| 随州市| 宁远县| 晴隆县| 温州市| 甘孜| 宝兴县| 德江县| 中宁县| 呼图壁县| 卢龙县| 门源| 阜平县| 页游| 馆陶县| 柳江县| 韶山市|