内存缓存主要有两种,一种是应用服务自己的memcache,类似于 webapi的session 其实都是服务自己的应用级内存,另外一种是分布式的缓存服务,此服务在另外的机器上,耗费的都是此机器的内存资源。
分布式缓存服务,在.Net技术栈下,我所知的有两种,第一个是Redis支持内存又支持保存到本地。第二个是Memcached 应该只支持内存服务。
所以,这种内存型的缓存,内存是越大越好,我是见过几百G的内存做的缓存服务,更大的,目前我还没有见到。
网上有教程,可以参考,安装地址 : https://github.com/MicrosoftArchive/redis/releases
也可以注册官网的 https://redis.com/try-free/ 免费资源,大概一百M左右好像,支持的功能多,测试用很方便。
我安装此类服务直接就是Docker Desktop ,直接就部署了。方便的很。
所以,建议,可以搜一下,安装个Docker Desktop,安装,卸载都很方便。
Docker命令如下:
docker run --name redis -p 6379:6379 -d redis
就一行代码,就可以了,大致如下图,下载完就OK,直接自己启动服务了
可以看到 服务已经启动了。
接下来,就是连接到服务,看看效果如何
现在此服务是收费的,果然好的东西,就会收费。
但是可以下载早期版本。
https://github.com/uglide/RedisDesktopManager/releases/tag/0.9.3
下载后,直接安装
基本都是下一步,下一步。
直接打开就是这个样子
然后,把刚才的redis的服务地址给搞上去,我这边都是默认就可以用了。
也可以点击测试连接,我这边直接就连上了。
双击连接,就看到了我们的16个redis的数据库了
至此,redis的服务安装完毕,也能看到里面是啥子了。
这个 Redis Desktop Manager 就能做很多的操作,读啊,写数据,但是,我们还是用程序来搞,更加的深入。
新建一个控制台项目
Nuget包
Install-Package StackExchange.Redis -Version 2.6.45
只需要一个包就可以了,也挺方便的
挺简单的
var _connMultiplexer = ConnectionMultiplexer.Connect("127.0.0.1");
Console.WriteLine($"redis连接状态:{_connMultiplexer.IsConnected}");
var _db = _connMultiplexer.GetDatabase(1);//可以选择指定的db,0-15
就获取了服务的状态,以及获取了指定的db 了。
默认的db 为 第0个db ,如果是集群模式(1主多从,基本都用的第0个DB)
其实我们不仅仅可以从官网了解到,还可以从这个_db对象上看到有哪些类型的
而我们常用的有
下面就基于常见类型与不常见类型,来一个案例
//String
db.StringSet("str1", "123");
var stringValue = db.StringGet("str1");
Console.WriteLine($"获取到string 类型的值:{stringValue}");
可以清晰的看到它的结构,简单明了的 key,value 结构
//hash 就是一个key 下面 有一个集合的hash key,value
db.HashSet("hash", 123, 123);
db.HashSet("hash", 123, 456);
var HashValue = db.HashGet("hash", 123);
Console.WriteLine($"获取到hash 类型的值:{HashValue}");
// List ,就是一个有序的集合,可以选择push和pop,左右都可以
db.KeyDelete("list");
db.ListLeftPush("list", "123");
db.ListLeftPush("list", "456");
var listValue = db.ListLeftPop("list");
Console.WriteLine($"获取到list 类型的值:{listValue}");
listValue = db.ListLeftPop("list");
Console.WriteLine($"获取到list 类型的值:{listValue}");
// Set 一个无序不重复集合
db.SetAdd("set", 123);
db.SetAdd("set", 456);
db.SetAdd("set", 789);
db.SetAdd("set", 789);
var setValue = db.SetScan("set");
Console.WriteLine($"获取到set 类型的值:{string.Join(",",setValue)}");
// Zset(SortedSet)
db.SortedSetAdd("SortedSet", 123, 1);
db.SortedSetAdd("SortedSet", 123, 2);
db.SortedSetAdd("SortedSet", 456, 2);
var sortedSetValue = db.SortedSetScan("SortedSet");
Console.WriteLine($"获取到sortedSetValue 类型的值:{string.Join(",", sortedSetValue)}");
// geo
db.GeoAdd("geo", 104.056257, 30.651897, "成都锦里");
db.GeoAdd("geo", 104.063684, 30.663607, "成都人民公园");
var Distance = db.GeoDistance("geo", "成都锦里", "成都人民公园");
Console.WriteLine($"获取到 geo 地理类型 距离{Distance}");
这样的类型存储
还挺准的。
// HyperLogLog 它是一种算法
db.HyperLogLogAdd("HyperLogLog1", 123);
db.HyperLogLogAdd("HyperLogLog1", 123);
db.HyperLogLogAdd("HyperLogLog1", 456);
var HyperLogLogLength = db.HyperLogLogLength("HyperLogLog1");
Console.WriteLine($"HyperLogLogLength 长度:{HyperLogLogLength}");
db.HyperLogLogAdd("HyperLogLog2", 789);
db.HyperLogLogAdd("HyperLogLog2", 789);
db.HyperLogLogAdd("HyperLogLog2", 123);
//可以合并集合
db.HyperLogLogMerge("HyperLogLog3", "HyperLogLog1", "HyperLogLog2");
HyperLogLogLength = db.HyperLogLogLength("HyperLogLog3");
Console.WriteLine($"HyperLogLogLength 长度:{HyperLogLogLength}");
存储的是个二进制。好吧,也看不到是啥玩意儿
但是功能是记录 去重后的数据量,用极少的内存存储大数据量的数据。对比set来讲,降低了set的重复性,
hash存的话好点,但是,没有这个算法好,毕竟是二进制的,也类似于bitmap算法,求交集。
// Stream 新版消息队列
db.StreamDeleteConsumerGroup("stream", "消费者组");
//消费者组创建
var result = db.StreamCreateConsumerGroup("stream", "消费者组");
if (result)
{
Console.WriteLine("创建消费者组成功");
}
else
{
Console.WriteLine("创建消费者1失败");
}
//生产者
Task.Run(() =>
{
int i = 0;
while (true)
{
var result = db.StreamAdd("stream", "123", i.ToString());
Thread.Sleep(1000);
i++;
}
});
//消费者1
Task.Run(() =>
{
while (true)
{
var result = db.StreamReadGroup("stream", "消费者组", "消费者1");
if (result?.Any() == true)
{
foreach (var item in result)
{
Console.WriteLine($"消费者1:{item.Id} {item["123"]}");
}
}
}
});
//消费者2
Task.Run(() =>
{
while (true)
{
var result = db.StreamReadGroup("stream", "消费者组", "消费者2");
if (result?.Any() == true)
{
foreach (var item in result)
{
Console.WriteLine($"消费者2:{item.Id} {item["123"]}");
}
}
}
});
Redis Desktop Manager 里看不到,是个二进制
我们基于redis来了一个从入门到熟练,现在各种类型都已熟悉。还学习了一些新的类型,以前我都没搞过。
用到特殊地方肯定有奇效。
https://github.com/kesshei/redisDemo.git
https://gitee.com/kesshei/redisDemo.git