.Net Core 三大Redis客户端对比和使用心得

前言

  稍微复杂一点的互联网项目,技术选型都可能会涉及Redis,.NetCore的生态越发完善,支持.NetCore的Redis客户端越来越多,

下面三款常见的Redis客户端,相信大家平时或多或少用到一些,结合平时对三款客户端的使用,有些心得体会。

先比较宏观的背景: 

使用心得

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

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

StackExchange.Redis

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

  • 高性能的核心在于 多路复用器(支持在多个调用线程高效共享Redis连接), 服务器端操作使用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");

如果你需要blocking pops, StackExchange.Redis官方推荐使用pub/sub模型模拟实现。

  • 日常操作的API请关注IDatabase接口,支持异步方法,这里我对【客户端操作Redis尽量不要使用异步方法】的说法不敢苟同,对于异步方法我认为还是遵守微软最佳实践:对于IO密集的操作,能使用异步尽量使用异步

 _redisDB0.StringDecrementAsync("ProfileUsageCap", (double)1)      // 对应redis自增api:DECR mykey
_redisDB0.HashGetAsync(profileUsage, eqidPair.ProfileId))   // 对应redis api:hget key field1
_redisDB0.HashDecrementAsync(profileUsage, eqidPair.ProfileId, 1) // 对应redis哈希自增api:HINCRBY myhash field -1
  • ConnectionMultiplexer 方式支持随时切换Redis DB,对于多个Redis DB的操作,我封装了一个常用的Redis DB 操作客户端。

Microsoft.Extensions.Caching.StackExchangeRedis

    从nuget doc可知,该组件库依赖于 StackExchange.Redis 客户端;是.NetCore针对分布式缓存提供的客户端,侧重点在 Redis的缓存特性。

另外能使用的函数签名也更倾向于【通用的 增、查操作】

// 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缓存项

③ Redis并不支持bytes[] 形式的存储值,以上byte[] 实际是以Hash的形式存储

 640?wx_fmt=png

CSRedisCore

该组件的功能更为强大,针对实际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") + ",defualtDatabase=" + 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”。

Redis的一点小经验:

  • 对自己要使用的Redis API 的时间复杂度心里要有数,尽量不要使用长时间运行的命令如keys *,可通过redis.io SlowLog命令观测 哪些命令耗费较长时间

  • Redis Key可按照“:”分隔定义成有业务意义的字符串,如NewUsers:201909:666666(某些Redis UI可直观友好查看该业务)

  • 合适确定Key-Value的大小:Redis对于small value更友好, 如果值很大,考虑划分到多个key

  • 关于缓存穿透,面试的时候会问,自行搜索布隆过滤器。

  • redis虽然有持久化机制,但在实际中会将key-value 持久化到关系型数据库,因为对于某些结构化查询,SQL更为有效。

----- update 多说两句-------

以上三大客户端,Microsoft.Extensions.Caching.StackExchangeRedis 与其他两者的定位还是有很大差距的,单纯 使用Redis 缓存特性, 有微软出品,必属精品情结的可使用此客户端;

StackExchange.Redis、CSRedisCore 对于Redis全功能特性支持的比较全,但是我也始终没有解决StackExchange.Redis :RedisTimeoutException 超时的问题,换成CSRedisCore 确实没有出现Redis相关异常。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314107.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2020第十一届蓝桥杯软件类省赛第二场C/C++ 大学 B 组(题解)

试题 A: 门牌制作 问题描述 小蓝要为一条街的住户制作门牌号。 这条街一共有 2020 位住户&#xff0c;门牌号从 1 到 2020 编号。 小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符&#xff0c;最后根据需要将字 符粘贴到门牌上&#xff0c;例如门牌 1017 需要依次粘贴字符 …

队长开卖自家产“翠香”猕猴桃

猕猴桃品种有很多&#xff0c;但不是所有的果子都叫翠香。这两天我在公众号里卖了这个翠香猕猴桃&#xff0c;可能是有同学以为是做广告卖水果&#xff0c;其实是家里的亲戚猕猴桃成熟了&#xff0c;辛苦一年下来地里一共结了3000斤猕猴桃&#xff0c;遇到了一个难题就是如何把…

Java修炼之路——基础篇——Java集合类

集合类的全景图 常用集合类特性 1. Collection&#xff1a;每个位置对应一个元素1.1: List 存放有序元素&#xff0c;允许重复元素&#xff0c;允许元素为null1.1.1: ArrayList&#xff1a;内部结构为数组&#xff1b;初始容量为10&#xff1b;插入、删除的移动速度慢&#x…

1575 Gcd and Lcm

1575 Gcd and Lcm ∑i1n∑j1i∑k1ilcm(gcd(i,j),gcd(i,k))设f(n)∑i1n∑j1nlcm(gcd(i,n),gcd(j,n))f(p)3p2−3p1f(pk)(2k1)(p2k−p2k−1)pk−1\sum_{i 1} ^{n} \sum_{j 1} ^{i} \sum_{k 1} ^{i} lcm(gcd(i, j), gcd(i, k))\\ 设f(n) \sum_{i 1} ^{n} \sum_{j 1} ^{n} lcm…

UVA12298 Super Poker II(多项式/背包问题)

UVA12298 Super Poker II 这应该是最水的背包问题了吧 然后有一个小问题就是这道题没有给模数&#xff0c;然后答案会爆int&#xff0c;所以我们需要MTT&#xff0c;然后开long long就好了&#xff0c;或者直接fft&#xff0c;有可能会爆精度。

Java修炼之路——基础篇——Java集合类详解1

SynchronizedList和Vector的区别 java.util.Vector java.util.Collections.$SynchronizedList Vector用同步方法&#xff0c;SynchronizedList用同步代码块&#xff0c;SynchronizedList可以指定锁定的对象 SynchronizedList有很好的扩展和兼容功能&#xff0c;能把所有List的子…

小卓.NET中文编程特点介绍

大家好&#xff0c;我在介绍一下我的全新编程语言&#xff0d;卓语言。小卓编程是卓语言的一个开发工具&#xff0c;可以在里面实现绘图、动画、事件响应等等功能。关于中文编程&#xff0c;一直以来都有争议。我针对以往中文编程的缺点而开发了一种全新的编程语言。首先 &…

P5748 集合划分计数(贝尔数/多项式)

P5748 集合划分计数 求解从1到1e5的所有贝尔数&#xff0c;我们可以利用生成函数求解&#xff0c;就是利用指数型生成函数求解 代码细节&#xff1a; 首先虽然exe^xex代表全是1&#xff0c;但是多项式下面还有阶乘逆元的系数&#xff0c;然后乘完之后&#xff0c;我们还有乘…

2019-02-28-算法-进化(盛最多水的容器)

题目描述 给定 n 个非负整数 a1&#xff0c;a2&#xff0c;…&#xff0c;an&#xff0c;每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线&#xff0c;垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以…

CAP 2.6 版本发布通告

前言今天&#xff0c;我们很高兴宣布 CAP 发布 2.6 版本正式版。同时我们也很高兴的告诉你 CAP 在 GitHub 已经突破了3000 Star.自从上次 CAP 2.5 版本发布 以来&#xff0c;已经过去了几个月的时间&#xff0c;关注的朋友可能知道&#xff0c;在这几个月的时间里&#xff0c;也…

皮克定理(题目)

Area 皮克定理&#xff1a;皮克定理是指一个计算点阵中顶点在格点上的多边形面积公式&#xff0c;该公式可以表示为Sab2&#xff0d;1&#xff0c;其中a表示多边形内部的点数&#xff0c;b表示多边形落在格点边界上的点数&#xff0c;S表示多边形的面积。 /*Author : lifehap…

随机算法

概率论基础知识 期望的线性性 马尔可夫不等式 条件概率 独立事件 独立随机变量 随机算法 Las Vegas型随机算法 随机快速排序 随机选择 随机n皇后放置 将确定性算法的某一步修改为随机选择&#xff0c;有可能可以优化算法平均时间下的算法复杂度。 Monte Carlo型算法 主元…

求助:现在有一个可以进体制“养老”的坑,我该不该跳?

对不起&#xff0c;在当下互联网人生活的环境中&#xff0c;并没有可以“养老”的坑。对不起&#xff0c;在当下互联网人生活的环境中&#xff0c;也没有绝对”稳定“的企业。技术人的职业发展&#xff0c;以”适者生存“为核心原则&#xff0c;每一种职业环境都有相应的职业成…

Java修炼之路——基础篇——Java集合类详解2

Set和List区别&#xff1f;Set如何保证元素不重复&#xff1f; Set、List都实现了Collection接口&#xff0c;List是有序的列表&#xff0c;Set是无序的集合&#xff08;TreeSet有序&#xff09; List实现类&#xff1a; ArrayList &#xff1a;基于数组&#xff0c;可动态扩…

Legacy(线段树优化建边跑Dijkstra)

Legacy 线段树优化建边&#xff0c;开两颗线段树&#xff1a; 对于线段树1&#xff0c;自顶向下连边。对于线段树2&#xff0c;自底向上连边。 然后对于op1我们直接连边即可。 对于op2&#xff08;u -> [l, r] cost w&#xff09;&#xff0c;这个操作在线段树1上完成即可…

P5273 【模板】多项式幂函数 (加强版)

P5273 【模板】多项式幂函数 (加强版) 这道题和原来的题目唯一区别就在于这道题没有限制F[0]1&#xff0c;所以我们就不能直接取ln了&#xff0c;但是我们实际上有办法转换一下&#xff0c;让它最低次项为1&#xff0c;只需要除以最后一个非0项即可&#xff0c;然后最后再乘回…

给 asp.net core 写个中间件来记录接口耗时

给 asp.net core 写个中间件来记录接口耗时Intro写接口的难免会遇到别人说接口比较慢&#xff0c;到底慢多少&#xff0c;一个接口服务器处理究竟花了多长时间&#xff0c;如果能有具体的数字来记录每个接口耗时多少&#xff0c;别人再说接口慢的时候看一下接口耗时统计&#x…

2019-03-1-算法-进化(整数转罗马数字)

题目描述 罗马数字包含以下七种字符&#xff1a; I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M …

brz的函数(mobius)

brz的函数 ∑i1n∑j1nμ(ij)假设i,j不互质&#xff0c;一定有μ(ij)0所以上式∑i1n∑j1nμ(ij)[gcd(i,j)1]积性函数性质有μ(ij)μ(i)μ(j)∑i1n∑j1nμ(i)μ(j)[gcd(i,j)1]∑i1n∑j1nμ(i)μ(j)∑d∣gcd(i,j)μ(d)这里我们按照套路把d给提前去&#xff0c;因为i,j都要是d的倍数…

CF1251F Red-White Fence(多项式/背包问题/组合数学)

CF1251F Red-White Fence 现在给出了n个白板&#xff0c;m个红板&#xff0c;然后将其按照题目要求放成一排&#xff0c;要求最终周长为qi的方案数。 首先因为有高度的单调性&#xff0c;所以我们可以直接把周长转化为红板的高度和白板的数量&#xff0c;然后因为红板数量很少…