@[toc]
一、Redis的核心概念
- 概念
Redis就是分布式缓存,也可以理解成进程外的缓存。
如图:
【Redis(一)原理与基本使用】
文章图片
- 应用场景
主要是应用在集群系统中。
- 单体项目就没必要用分布式缓存,使用本地缓存就可以;如图:
文章图片
- 单体项目就没必要用分布式缓存,使用本地缓存就可以;如图:
当客户端发起请求到系统,系统先去到本地缓存查询数据,没有查询到数据则到数据库查询,将查到的数据保存到本地缓存在返回到客户端;当第二次请求到系统,系统先去到本地缓存查询数据,则将缓存中的数据返回到客户端【第一次请求已经将数据保存到本地缓存中】;那他本地缓存的命中率为 50%;
- 使用本地缓存做分布式会有缓存命中率下降缺陷;如图:
文章图片
客户端发起请求到Nginx,Nginx将请求代理到系统1,系统1查看本地缓存没有符合条件的数据,再到数据库获取数据存到本地缓存再返回到客户端;当客户端在一次发起请求到Nginx,Nginx将请求代理到系统2,系统2查看本地缓存没有符合条件的数据,再到数据库获取数据存到本地缓存再返回到客户端,那么发起了两次请求都没有到本地缓存中获取到数据,那它缓存命中率为 0/2=0;缓存命中率下降那就表明整体查询性能下降。
- 解决缓存命中率的方案
将缓存数据集中到一起,使用Redis分布式缓存,如图:
文章图片
- 条件
- Demo项目
- Redis 【在linux中部署】
- Linux安装
#安装 wget 命令 yum -y install wget #下载 wget http://download.redis.io/releases/redis-6.2.6.tar.gz #解压 tar xzf redis-6.2.6.tar.gz #进入解压文件夹 cd redis-6.2.6 #安装 gcc yum install gcc #编译 make #进入解压后的src目录,运行服务 src/redis-server
- Linux安装
- Demo 项目配置
- 步骤
- 安装Redis Nuget包
StackExchange.Redis
- 定义一个扩展类
public static IServiceCollection AddRedis(this IServiceCollection serviceCollection) { ConnectionMultiplexer connectionMultiplexer = ConnectionMultiplexer.Connect("IP:端口"); serviceCollection.AddSingleton(connectionMultiplexer); return serviceCollection; }
- StateUp类注册【写了个扩展方法】
services.AddRedis();
- Redis 存储和获取
//注入 public readonly ConnectionMultiplexer connectionMultiplexer; public HomeController(ConnectionMultiplexer _connectionMultiplexer) { connectionMultiplexer = _connectionMultiplexer; } // 获取Redis值 obj = connectionMultiplexer.GetDatabase(0).StringGet(Key).ToString(); //存储Redis值Key:Value connectionMultiplexer.GetDatabase(0).StringSet(Key, Value);
- Redis 存储集合
//获取Redis是否存在 RedisValue[] redisValues = connectionMultiplexer.GetDatabase(0).SetMembers("list"); //Redis中不存在此数据 if (redisValues.Length == 0) { //数据库中获取 list = demoDbContext.Set
().ToList(); List rvList = new List (); foreach (User user in list) { obj = JsonConvert.SerializeObject(user); rvList.Add(obj); } //将数据添加到Redis中 connectionMultiplexer.GetDatabase(0).SetAdd("list", rvList.ToArray()); }
- Redis Hash字典存储
使用场景:对数据库某个字段做修改或者某个int字段数据加一
//获取HASH字段中的数据 connectionMultiplexer.GetDatabase(0).HashGet(类型, key).ToString(); if (string.IsNullOrEmpty(obj)) { //到数据库获取数据 u = demoDbContext.Set
().Where(p => p.useid == useid).FirstOrDefault(); //将数据添加到Redis Hash字典中 connectionMultiplexer.GetDatabase(0).HashSet(类型, key,Value); //设置过期时间 connectionMultiplexer.GetDatabase(0).KeyExpire(类型,TimeSpan.FromSeconds(10)); } //字典中的Value值加1 connectionMultiplexer.GetDatabase(0).HashIncrement(类型, key);
- Redis 事务
//查询获取值 connectionMultiplexer.GetDatabase(0).HashGet(类型, key).ToString(); //创建事务 ITransaction transaction = connectionMultiplexer.GetDatabase(0).CreateTransaction(); //添加值 transaction.HashSetAsync(类型, key, value); //修改值 // transaction.HashSetAsync(类型, key,修改后Value); //提交事务 bool commit = transaction.Execute();
- Redis 批量存储数据
//创建批量对象 var bach = connectionMultiplexer.GetDatabase(0).CreateBatch(); //获取数据 List
list = new List (); list = demoDbContext.user.ToList(); //批量添加 for (int i = 0; i < list.Count; i++) { bach.HashSetAsync("bach_User_"+i, "state", list[i].usestate); } //数据提交 bach.Execute();
- Redis集合排序
//获取数据 RedisValue[] rv = connectionMultiplexer.GetDatabase(0).SetMembers("User"); if (rv.Length == 0) { list = demoDbContext.Set
().ToList(); List rvList = new List (); //批量添加数据 foreach (User u in list) { vardata = https://www.it610.com/article/JsonConvert.SerializeObject(u); rvList.Add(data); //数据排序 connectionMultiplexer.GetDatabase(0).SortedSetAdd("User", data, u.usestate); // User :keydata:Value值u.usestate:排序字段升序 }
- Redis分页查询
List
list = new List (); //获取分页数据100为行数,1为页数 RedisValue[] rv = connectionMultiplexer.GetDatabase(0).SetScan("User",100,0,1).ToArray(); if (rv.Length == 0) { list = demoDbContext.Set ().ToList(); List rvList = new List (); foreach (User u in list) { vardata = https://www.it610.com/article/JsonConvert.SerializeObject(u); rvList.Add(data); } //添加数据到Redis中 connectionMultiplexer.GetDatabase(0).SetAdd("User", rvList.ToArray()); }
- 安装Redis Nuget包
- 步骤
- 原理
默认通过Socket协议建立连接的,服务端通过Socket的经过四层,在通过链路层再经过四层到达Redis建立连接;链路层【硬件层面】收到请求后,操作系统【生产者】通过同步转换成异步将请求发给事件收集器【MQ】然后Redis【订阅者】用一个线程通过轮询的方式处理事件,这就是多路复用机制。
Redis做的三件事:
1、建立连接
2、存储数据到本地缓存
3、持久化数据到文件中(开启新线程)
如图:
文章图片
- 原理
Redis 建立连接后,通过接口将数据存储到内存中。
如图:
文章图片
- 数据持久化
- 目的
为了防止数据丢失。默认存放在AOP 文件中。
- 目的
- Redis Set原理图
数组+HASH表,如图:
文章图片
- Redis HASH字典原理
数组+HASH表+单项列表。
- 原理
字典存储的字段经过hash得到一个数组的索引,根据索引将key \ value存储到数组中,如果得到的索引已经存在key\value 了,不会覆盖掉,会形成一个单项链表的形式继续存储。
如图:
- 原理
![在这里插入图片描述](https://img-blog.csdnimg.cn/3e4a1a23c7a34ef1b8c2c16e34abf72d.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQEDnpZ7lhpzlhpnku6PnoIE=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
- 缺陷
完全基于内存,会导致内存溢出。不适合存储海量数据。
推荐阅读
- 【Redis 系列】redis 学习九,Redis 的发布和订阅是咋玩的
- redis客户端发送键消息流程
- 【Redis 系列】redis 学习八,redis 持久化 RDB 和 AOF
- lua|Redis Lua 沙盒逃逸漏洞(CVE-2022-0543)
- Yii2.0 redis的配置和使用
- redis|redis数据类型list总结
- redis|redis数据类型hash总结
- 设置Redis最大占用内存
- javaWeb|redis错误总结