.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,一经查实,立即删除!

相关文章

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

猕猴桃品种有很多&#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…

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

大家好&#xff0c;我在介绍一下我的全新编程语言&#xff0d;卓语言。小卓编程是卓语言的一个开发工具&#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;也…

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

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

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

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

Docker(二)-在Docker中部署Nginx实现负载均衡【完整教程】

一、前言【查看完整视频教程&#xff08;免费&#xff09;&#xff0c;请拉直文尾】在前面的文章中我们已经介绍了如何在Centos7系统中安装Docker以及利用Docker进行Asp.Net Core应用的部署。在本文中&#xff0c;我们将继续介绍利用Docker部署Nginx服务实现负载均衡。文章最后…

设置ABP默认使用中文

ABP提供的启动模板, 默认使用是英文:虽然可以通过右上角的菜单切换成中文, 但是对于国内项目来说, 默认使用中文是很正常的需求.前期准备使用ABP CLI创建一个名为AbpStudy的ASP.NET MVC项目:abp new AbpStudy关于MVC的启动模板可以看文档, 这里就不赘述.使用ABP版本的是当前最新…

基础篇--Java IO--概览

字符流、字节流、输入流、输出流 Java 中使用IO&#xff08;输入输出&#xff09;来读取和写入&#xff0c;读写磁盘文件、内存、网络数据。输入输出是相对内存而言&#xff0c;往内存中读数据就为输入流&#xff0c;从内存中往外写就是输出流。 根据处理类型分为字符流、字节…

.NET轻松写博客园爬虫

爬虫&#xff0c;是一种按照一定的规则&#xff0c;自动地抓取网站的程序或者脚本。.NET写爬虫非常简单&#xff0c;并能轻松优化性能。今天我将分享一段简短的代码&#xff0c;爬出博客园前200页精华内容&#xff0c;然后通过微小的改动&#xff0c;将代码升级为多线程爬虫&am…

kettle同步数据中文乱码问题解决

最近在使用kettle进行数据同步的时候&#xff0c;发现同步来的中文数据产生了乱码。试了下网上的解决方案&#xff0c;最终解决了这个问题。步骤如下&#xff1a; 1&#xff1a;kettle中配置源数据库、目标数据库编码 2&#xff1a;编辑“表输入”&#xff0c;去掉勾选“允许建…

WTM重磅更新,LayuiAdmin免费用 and more

从善如登&#xff0c;从恶如崩。对于一个开发人员来说&#xff0c;那就是做一个好的系统不容易&#xff0c;想搞砸一个系统很简单&#xff0c;删库跑路会还不会么。对于我们开源框架的作者来说&#xff0c;做一个好的框架就像登山&#xff08;也许是登天&#xff09;&#xff0…

kettle数据库操作OPTION SQL_SELECT_LIMIT=DEFAULT问题解决

今天在使用kettle配置数据库映射的时候&#xff0c;有如下报错&#xff1a; Couldnt get field info from [select * from pre_user_base_bak]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax …

.netcore 分布式事务CAP2.6 快速入门

CAP介绍&#xff1a;CAP是一个用来解决微服务或者分布式系统中分布式事务问题的一个开源项目解决方案。可以解决跨服务器的数据一致性问题。一个简单的列子&#xff0c;如&#xff1a;订单系统创建订单后需要通知邮件通知用户下单成功&#xff0c;解决方案有下面几种&#xff1…

#3601. 一个人的数论

#3601. 一个人的数论 首先这个转化还是很巧妙的&#xff0c;或者很套路的&#xff0c;直接莫比乌斯反演&#xff0c;然后看到了自然数幂之和的形式&#xff0c;那么我们就可以转化为多项式处理&#xff0c;项数就减少到了d1&#xff0c;然后看到题目给出的都是质因数分解结果&a…

2019-03-5-算法-进化(最长公共前缀)

题目描述 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 “”。 示例 1: 输入: ["flower","flow","flight"] 输出: "fl"示例 2: 输入: ["dog","racecar","…

自然数幂之和

自然数幂之和 https://blog.csdn.net/suncongbo/article/details/97622131 这个文章的整理非常全面。

从你的全世界路过—一群程序员的稻城亚丁游记

转眼之间又即将到九月&#xff0c;又到了这个适合去川西旅游的最佳季节。最近有一些朋友问我稻城亚丁的旅游情况&#xff0c;因此我将去年写的这一篇游记再次发出来&#xff0c;希望对那些有计划去川西旅游的朋友们有帮助&#xff01;温馨提示&#xff1a;本文图片较多&#xf…

P2303 [SDOI2012] Longge(数论/欧拉函数)

P2303 [SDOI2012] Longge 一道看似非常基础的数论题&#xff0c;但是蕴含了非常多的知识&#xff0c;求解 ∑i1ngcd(i,n)\sum_{i1}^ngcd(i,n) i1∑n​gcd(i,n) 这个东西我们轻松地就能化简成id∗φid*\varphiid∗φ的形式&#xff0c;然后考虑如何快速求解&#xff0c;那么可以…