本章我们将围绕Redis6.0的几个新特性进行讲解,主要是面向网络处理的多IO线程,客户端缓存,细粒度权限控制,以及RESP3协议,也是分为如上几个模块
1.网络处理的多IO线程
Redis一开始被熟知是因为其单线程架构,其网络IO处理到实际的读写命令处理,都是单个线程完成的
对于此架构,必然会出现单个线程处理网络请求的速度跟不上网卡处理速度的情况
对于Redis,采用了多个IO线程来处理网络请求,提高网络请求的处理并行度,Redis 6.0采用的就是这种方法,Redis对于网络请求处理,交给了多个IO线程处理,对于实际的命令操作,还是单线程操作,保证了Lua脚本,事务的原子性
整体流程如下,首先是服务端和客户端建立Socket链接,分配处理线程
然后IO线程读取并解析请求,主线程一旦把Socket分配给了IO线程,就等待客户端请求读取完成
之后就是主线程执行请求操作,并写回Socket
整体流程说完了,看一下在Redis 6.0,是如何开启多线程的,需要开启两个设置
1.设置io-thread-do-reads配置项为yes,表示启用多线程
io-threads-do-reads yes 2.设置线程个数,线程个数小于Redis实例所在机器的CPU个数 io-threads 6 |
2.实现服务端协助客户端的缓存
Redis6.0还新增了服务端协助的客户端缓存功能,也被称为跟踪 Tracking 功能,有了这个功能,业务应用中的Redis客户端就可以将数据缓存在业务应用本地了,应用直接在本地快速读取数据
不过数据缓存在客户端本地,会面临一个问题,数据被修改了或者失效了,如何和客户端保持一致?
6.0实现的Tracking功能实现了两个模式,解决了这个问题
一种是普通模式,实例会在服务端记录客户端读取过的key,监测key是否被修改,一旦key的值发生了变化,服务端会给客户端发送invalidate消息,通知客户端缓存失效
使用普通模式,需要注意,服务端只会对记录的key报告一次invalidate消息,服务端再给客户端发送一次invalidate消息,如果key再次被修改,就不会再次发送invalidate消息
这种模式下的配置管理如下
CLIENT TRACKING ON|OFF
另一种是广播模式,服务端会给客户端广播所有失效的key,不过如果读写频繁,那么会发送大量的失效广播消息,消耗了大量网络带宽资源
所以在实际应用中,客户端只需要订阅需要跟踪的key的前缀,如果有匹配的key被修改的话,服务端就会将失效消息广播给注册的客户端
就好比,我们在客户端执行了下面的注册命令,如果服务端更新了user:id:1003这个key,就会收到invalidate消息
CLIENT TRACKING ON BCAST PREFIX user
3.更为细粒度的权限控制
Redis 6.0提供了全新的访问权限控制列表功能 Access Control List,ACL
提供了诸如创建子用户,以及给子用户设置可执行的权限范围
对于子用户的创建,可以使用ACL SETUSER命令,例如下面的命令,创建一个用户normaluser,密码设置为abc
ACL SETUSER normaluser on > abc
其次是关于可执行的范围 ,包含如下的命令列表
假如要设置用户normaluser只能使用Hash类型的命令操作,不能调用String类型,可以执行如下的命令
ACL SETUSER normaluser +@hash -@string
除了设置某个命令或者某类命令的访问控制权限,6.0版本还支持以key为粒度设置权限
具体的使用就是
ACL SETUSER normaluser ~user:*+@all
这样就是基于某些用户的细粒度控制
4.启用RESP 3的协议
Redis 6.0实现了RESP 3通信协议,使用RESP 2,在其中客户端和服务器端的通信内容是以字节数组形式进行编码的,客户端要根据操作的命令或者数据类型自行对传输的数据进行加解密,增加了客户端的开发复杂度
RESP3直接支持多种数据类型的区分编码,包含空值,浮点数,布尔值,有序的字典集合,无序的集合等
区分编码,也就是根据不同的开头字符,区分不同的数据类型,客户端可以直接根据消息的开头字符,实现数据转换,提升了客户端的效率,RESP3 还支持客户端以普通模式和广播模式实现客户端缓存
总结一下,我们介绍了Redis 6.0的特性,分为IO线程 客户端缓存 访问权限控制, RESP 3协议,整体如下一张表