.NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐
作者:依乐祝
原本链接:https://www.cnblogs.com/yilezhu/p/9947905.html
引子
为什么写这篇文章呢?因为.NET Core的生态越来越好了!之前玩转.net的时候操作Redis相信大伙都使用过一些组件,但都有一些缺点,如ServiceStack.Redis 是商业版,免费版有限制;StackExchange.Redis 是免费版,但是内核在 .NETCore 运行时经常有 Timeout的问题,暂无法解决(据农码一生大佬说:https://github.com/StackExchange/StackExchange.Redis/issues/871 试试StackExchange.Redis 2.0 呢,超时问题好像解决了。但还是有朋友说,2.0也还是会出现超时的问题)有兴趣的可以试试;csredis作者在 2014 年以后就没有更新了,它不支持 .net core,但是它的源码可读性很强非常干净,几乎无任何依赖。但是随着.NET Core生态的越来越好,又涌现了一批我们国内大牛开发的支持.Net Core的Redis组件,供我们选择。
- NewLife.Redis 他是NewLife团队开发的,已经在ZTO大数据实时计算中广泛应用,200多个Redis实例稳定工作一年多,每天处理近1亿包裹数据,日均调用量80亿次。 
- CSRedis (这里我更喜欢把它叫做CSRedisCore)这是另一个国内大牛nicye 开发的,为人很低调,所以了解他的人很少!目前我项目中广泛使用的也是这个。作者前不久刚做了一个几大Redis组件的性能测试.net core 2.0 redis驱动性能比拼 有兴趣的可以打开链接看一下。 - 注:此CSRedis(今天本文的主角CSRedisCore) 非彼CSRedis(.net 时代的组件,很久没更新了,不支持.net core) 
NewLife.Redis的使用方法在前两天的Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南)文章中已经分享了!文章也有视频教程。所以今天的文章将介绍另一个玩转Redis的神器-CSRedis了!
基本使用
CSRedisCore的使用很简单,就需要实例化一个CSRedisClient(集群连接池)对象然后初始化一下RedisHelper就可以了,他的方法名与redis-cli基本保持一致。所以说你可以像使用redis-cli命令一样来使用它。作者最近也支持了Pipeline功能以及MGet,MSet等提高效率的功能!话不多少下面我们将通过一个个实例来看下他的操作吧。
简单使用
- 获取Nuget包(目前版本3.0.18)!哈,没错,使用前要通过Nuget来安装下引用,什么?你不知道怎么使用Nuget包?对不起,右上角点下“X” 关掉网页就可以了。 - nuget Install-Package CSRedisCore
 
- 几种启动模式介绍: - 普通模式: - var csredis = new CSRedis.CSRedisClient("127.0.0.1:6379,password=123,defaultDatabase=13,poolsize=50,ssl=false,writeBuffer=10240,prefix=key前辍");
 
- 官方集群模式:假设你已经配置好 redis-trib 集群,定义一个【普通模式】的 CSRedisClient 对象,它会根据 redis-server 返回的 MOVED | ASK 错误记录slot,自动增加节点 Nodes 属性。 - 127.0.0.1:6379,password=123,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix= - 其他节点在运行过程中自动增加,确保每个节点密码一致。 - 警告:本模式与【分区模式】同时使用时,切记不可设置“prefix=key前辍”(或者全部设置成一样),否则会导致 keySlot 计算结果与服务端不匹配,无法记录 slotCache。 - 注意:官方集群不支持多 keys 的命令、【管道】、Eval(脚本)等众多杀手级功能。 
- 分区模式:本功能实现多个服务节点分担存储(作者自己实现的一种方式),与官方的分区、集群、高可用方案不同。 - 例如:缓存数据达到500G,如果使用一台redis-server服务器光靠内存存储将非常吃力,使用硬盘又影响性能。 
 可以使用此功能自动管理N台redis-server服务器分担存储,每台服务器只需约 (500/N)G 内存,且每台服务器匀可以配置官方高可用架构。- var csredis = new CSRedis.CSRedisClient(null,
 "127.0.0.1:6371,password=123,defaultDatabase=11,poolsize=10,ssl=false,writeBuffer=10240,prefix=key前辍",
 "127.0.0.1:6372,password=123,defaultDatabase=12,poolsize=11,ssl=false,writeBuffer=10240,prefix=key前辍",
 "127.0.0.1:6373,password=123,defaultDatabase=13,poolsize=12,ssl=false,writeBuffer=10240,prefix=key前辍",
 "127.0.0.1:6374,password=123,defaultDatabase=14,poolsize=13,ssl=false,writeBuffer=10240,prefix=key前辍");
 //实现思路:根据key.GetHashCode() % 节点总数量,确定连向的节点
 //也可以自定义规则(第一个参数设置)
 
 
- 今天我只给大家演示怎么来进行使用,所以采用了普通模式,代码如下所示: - static void Main(string[] args)
 {
 //普通模式
 var csredis = new CSRedis.CSRedisClient("127.0.0.1:6379,password=123,defaultDatabase=1,poolsize=50,ssl=false,writeBuffer=10240");
 //初始化 RedisHelper
 RedisHelper.Initialization(csredis);
 //Install-Package Caching.CSRedis (本篇不需要)
 //注册mvc分布式缓存
 //services.AddSingleton<IDistributedCache>(new Microsoft.Extensions.Caching.Redis.CSRedisCache(RedisHelper.Instance));
 Test();
 Console.ReadKey();
 } static void Test()
 { RedisHelper.Set("name", "祝雷");//设置值。默认永不过期
 //RedisHelper.SetAsync("name", "祝雷");//异步操作
 Console.WriteLine(RedisHelper.Get<String>("name")); RedisHelper.Set("time", DateTime.Now, 1);
 Console.WriteLine(RedisHelper.Get<DateTime>("time"));
 Thread.Sleep(1100);
 Console.WriteLine(RedisHelper.Get<DateTime>("time")); // 列表
 RedisHelper.RPush("list", "第一个元素");
 RedisHelper.RPush("list", "第二个元素");
 RedisHelper.LInsertBefore("list", "第二个元素", "我是新插入的第二个元素!");
 Console.WriteLine($"list的长度为{RedisHelper.LLen("list")}");
 //Console.WriteLine($"list的长度为{RedisHelper.LLenAsync("list")}");//异步
 Console.WriteLine($"list的第二个元素为{RedisHelper.LIndex("list",1)}");
 //Console.WriteLine($"list的第二个元素为{RedisHelper.LIndexAsync("list",1)}");//异步
 // 哈希
 RedisHelper.HSet("person","name", "zhulei");
 RedisHelper.HSet("person", "sex", "男");
 RedisHelper.HSet("person", "age", "28");
 RedisHelper.HSet("person", "adress", "hefei");
 Console.WriteLine($"person这个哈希中的age为{RedisHelper.HGet<int>("person","age")}");
 //Console.WriteLine($"person这个哈希中的age为{RedisHelper.HGetAsync<int>("person", "age")}");//异步 // 集合
 RedisHelper.SAdd("students","zhangsan", "lisi");
 RedisHelper.SAdd("students", "wangwu");
 RedisHelper.SAdd("students", "zhaoliu");
 Console.WriteLine($"students这个集合的大小为{RedisHelper.SCard("students")}");
 Console.WriteLine($"students这个集合是否包含wagnwu:{RedisHelper.SIsMember("students", "wangwu")}");
 }- 通过上面的代码大家可以看到对于Redis的操作都是使用RedisHelper这个类来实现的。而且,对Redis的所有操作名称都跟Redis-Cli命令高度一致!这样就会方便很多!同时对所有的方法在实现上都有同步异步的操作!这里建议进行Redis操作的话都尽量使用同步操作。原因在上篇也进行了介绍!这里就不再次进行介绍了!。 
- 执行的结果如下所示:  
大#家可以摘录代码然后拷贝到一个新的控制台程序中运行即可!
高级使用
上面给大家介绍了一些通用的使用方法,接下来呢我们进行一些高级方法的使用。包括订阅/发布,PipeLine,缓存壳等等。
订阅与发布
//普通订阅
RedisHelper.Subscribe(
  ("chan1", msg => Console.WriteLine(msg.Body)),
  ("chan2", msg => Console.WriteLine(msg.Body)));
//模式订阅(通配符)
RedisHelper.PSubscribe(new[] { "test*", "*test001", "test*002" }, msg => {
  Console.WriteLine($"PSUB   {msg.MessageId}:{msg.Body}    {msg.Pattern}: chan:{msg.Channel}");
});
//模式订阅已经解决的难题:
//1、分区的节点匹配规则,导致通配符最大可能匹配全部节点,所以全部节点都要订阅
//2、本组 "test*", "*test001", "test*002" 订阅全部节点时,需要解决同一条消息不可执行多次
//发布
RedisHelper.Publish("chan1", "123123123");
//无论是分区或普通模式,RedisHelper.Publish 都可以正常通信
//不加缓存的时候,要从数据库查询
var t1 = Test.Select.WhereId(1).ToOne();
//一般的缓存代码,如不封装还挺繁琐的
var cacheValue = RedisHelper.Get("test1");
if (!string.IsNullOrEmpty(cacheValue)) {
	try {
		return JsonConvert.DeserializeObject(cacheValue);
	} catch {
		//出错时删除key
		RedisHelper.Remove("test1");
		throw;
	}
}
var t1 = Test.Select.WhereId(1).ToOne();
RedisHelper.Set("test1", JsonConvert.SerializeObject(t1), 10); //缓存10秒
//使用缓存壳效果同上,以下示例使用 string 和 hash 缓存数据
var t1 = RedisHelper.CacheShell("test1", 10, () => Test.Select.WhereId(1).ToOne());
var t2 = RedisHelper.CacheShell("test", "1", 10, () => Test.Select.WhereId(1).ToOne());
var t3 = RedisHelper.CacheShell("test", new [] { "1", "2" }, 10, notCacheFields => new [] {
  ("1", Test.Select.WhereId(1).ToOne()),
  ("2", Test.Select.WhereId(2).ToOne())
});
Pipeline及MGet,MSet
使用管道模式,打包多条命令一起执行,从而提高性能。
var ret1 = RedisHelper.StartPipe().Set("a", "1").Get("a").EndPipe();
var ret2 = RedisHelper.StartPipe(p => p.Set("a", "1").Get("a"));
var ret3 = RedisHelper.StartPipe().Get("b").Get("a").Get("a").EndPipe();
//与 RedisHelper.MGet("b", "a", "a") 性能相比,经测试差之毫厘
压力测试对比
到这里你可能要问了,CSRedisCore性能如何呢?跟其他的Redis组件相比又如何呢、这里给出一个链接.net core 2.0 redis驱动性能比拼?.net core 2.0 redis驱动性能比拼,上面有作者做的测试,大伙可以看下,我也做个截图分享

作者交流群
作者交流QQ群:8578575
总结
今天给大家介绍了.NET Core玩转Redis的又一傻瓜式神器CSRedisCore的使用,由于篇幅有限,所以还有很多方法没有进行演示。大伙可以按照本文的方法自行进行测试!(基本RedisCli里面有的命令,都有对应的方法实现!)看到.net core的生态越来越好!有很多优秀的工具以及框架在开源!作为.net Corer的你开森嘛?
.NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐的更多相关文章
- [翻译] C# 8.0 新特性 Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南)  【由浅至深】redis 实现发布订阅的几种方式  .NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐
		[翻译] C# 8.0 新特性 2018-11-13 17:04 by Rwing, 1179 阅读, 24 评论, 收藏, 编辑 原文: Building C# 8.0[译注:原文主标题如此,但内容 ... 
- ASP.NET Core开发者成长路线图
		目录 ASP.NET Core开发者路线图RoadMap 免责声明 请给一个星星! ⭐ 路线图 资源 总结 贡献 许可协议 ASP.NET Core开发者路线图RoadMap 来源: MoienTaj ... 
- ASP.NET Core开发者指南
		ASP.NET Core开发者指南 2019年ASP.NET Core开发者指南: 你可以在下面找到一张图,该图展示了你可以选取的路径及你想学习的库,从而成为一名 ASP.NET Core 开发者.“ ... 
- 一个.NET Core开发者的Linux入门学习笔记
		用.NET Core开发也有一段时间了,但是由于工作原因一直都是在Windows系统上进行的开发,一直想学习Linux然后把.NET Core开发的程序跑在Linux上,然后把心得体会记录一下发布再博 ... 
- 强大的jupyter,python开发者的福音
		jupyter是一种交互式计算和开发环境的笔记,ipython命令行比原生的python命令行更加友好和高效,还可以运行web版的界面,支持多语言,输出图形.音频.视频等功能. 一.安装 pip3 i ... 
- 超简单让.NET Core开发者快速拥有CI/CD的能力-Docker版本
		超简单让.NET Core开发者快速拥有CI/CD的能力-Docker版本 前言 上一篇自动化测试,全面且详细的介绍了从零开始到发布版本的步骤,这是传统的方式,本次为大家带来的是如何在5分钟内使用上d ... 
- ASP.NET Core开发者指南()
		你可以在下面找到一张图,该图展示了你可以选取的路径及你想学习的库,从而成为一名 ASP.NET Core 开发者.“作为 ASP.NET Core 开发者,我接下来应该学习什么?”,我把这张图作为建议 ... 
- ASP.NET Core开发者指南(转发)
		ASP.NET Core开发者指南 2019年ASP.NET Core开发者指南: 你可以在下面找到一张图,该图展示了你可以选取的路径及你想学习的库,从而成为一名 ASP.NET Core 开发者.& ... 
- 把旧系统迁移到.Net Core 2.0 日记 (15) --Session 改用Redis
		安装Microsoft.Extensions.Caching.Redis.Core NuGet中搜索Microsoft.Extensions.Caching.Redis.Core并安装,此NuGet包 ... 
随机推荐
- 从group by 展开去
			一.概念 "Group By"从字面意义上理解就是根据"By"指定的规则对数据进行分组,所谓的分组就是将一个"数据集"划分成若干个" ... 
- heartbeat.go
			body: %s", resp.StatusCode, body) } return nil } 
- http_server.go
			, fmt.Sprintf("%s: closing %s", proto, listener.Addr())) } 
- Hibernate用注解生成表
			User.java实体来 package com.tao.pojo; import javax.persistence.Column; //用注解的方式生成表 import javax.persist ... 
- vue iview UPload,但文件上传是,clearFiles的使用方法
			<template> <div> <button @click="clearUploadedImage">重新上传</button> ... 
- 大数据小视角2:ORCFile与Parquet,开源圈背后的生意
			上一篇文章聊了聊基于PAX的混合存储结构的RCFile,其实这里笔者还了解一些八卦,RCfile的主力团队都是来自中科院的童鞋在Facebook完成的,算是一个由华人主导的编码项目.但是RCfile仍 ... 
- Flask导入静态文件问题
			然而如果使用flask开发web,并且需要在本地导入已经写好的css js 文件或者image一系列,这些文件是静态文件,需要另外建一个文件夹static;并且在html文件修改导入方法,exampl ... 
- Apache Mina-1
			一.mina基础知识: Mina 官方网站:(http://mina.apache.org/) 1.1.Apache Mina是一个能够帮助用户开发高性能和高伸缩性网络应用程序的框架.它通过Java ... 
- js十大排序算法
			排序算法说明: (1)对于评述算法优劣术语的说明 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面:不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面: 内排序:所有排 ... 
- 解决eclipse svn 转 maven web 项目中遇到找不到maven managed dependencies的问题
			我们在使用eclipse从svn上check项目下来,然后转成maven web 项目的时候,经常会遇到一个问题,就是找不到maven依赖(maven managed dependencies),从而 ... 
