希尔顿酒店网站建设的优点,广告片精彩花絮,北京微信网站制作,北京市违法建设投诉网站2020年5月份#xff0c;6.0版本。
面向网络处理的多IO线程可以提高网络请求处理的速度#xff0c;而客户端缓存可以让应用直接在客户端本地读取数据#xff0c;这两个特性可以提升Redis的性能。
细粒度权限控制让Redis可以按照命令粒度控制不同用户的访问权限#xff0c;…2020年5月份6.0版本。
面向网络处理的多IO线程可以提高网络请求处理的速度而客户端缓存可以让应用直接在客户端本地读取数据这两个特性可以提升Redis的性能。
细粒度权限控制让Redis可以按照命令粒度控制不同用户的访问权限加强了Redis的安全保护。
RESP 3协议则增强客户端的功能可以让应用更加方便地使用Redis的不同数据类型。
1 从单线程处理网络请求到多线程处理
Redis单线程架构虽有些命令操作可用后台线程或子进程执行如数据删除、快照生成、AOF重写但从网络IO处理到实际的读写命令处理都是由单线程完成。
随着网络硬件的性能提升Redis性能瓶颈有时会出现在网络I/O处理即单个主线程处理网络请求的速度跟不上底层网络硬件的速度。 一般有两种方法
用用户态网络协议栈例如DPDK取代内核网络协议栈让网络请求的处理不用在内核里执行直接在用户态完成处理就行。 让Redis避免频繁让内核进行网络请求处理可很好地提升请求处理效率。但这个方法要求在Redis的整体架构中添加对用户态网络协议栈的支持需修改Redis源码中和网络相关的部分例如修改所有的网络收发请求函数这会带来很多开发工作量。而且新增代码还可能引入新Bug导致系统不稳定。采用多个IO线程来处理网络请求提高网络请求处理的并行度。Redis 6.0采用 Redis的多I/O线程只是用来处理网络请求对于读写命令Redis仍使用单线程处理。因为Redis处理请求时网络处理经常是瓶颈通过多个I/O线程并行处理网络操作可提升实例的整体处理性能。而继续使用单线程执行命令操作无需为了保证Lua脚本、事务的原子性额外开发多线程互斥机制了。这样Redis线程模型实现就简单了。 6.0中主线程和IO线程具体是怎么协作完成请求处理的 可将主线程和多I/O线程的协作分成如下阶段
服务端和客户端建立Socket连接并分配处理线程
主线程负责接收建立连接请求。当有客户端请求和实例建立Socket连接时主线程会创建和客户端的连接并把 Socket 放入全局等待队列中。 紧接着主线程通过轮询方法把Socket连接分配给IO线程。
IO线程读取并解析请求
主线程一旦把Socket分配给IO线程就会进入阻塞状态等待IO线程完成客户端请求读取和解析。因为有多个IO线程在并行处理所以这个过程很快就可以完成。
主线程执行请求操作
等到IO线程解析完请求主线程还是会以单线程的方式执行这些命令操作 IO线程回写Socket和主线程清空全局队列
当主线程执行完请求操作后会把需要返回的结果写入缓冲区然后主线程会阻塞等待IO线程把这些结果回写到Socket中并返回给客户端。
和IO线程读取和解析请求一样IO线程回写Socket时也是有多个线程在并发执行所以回写Socket的速度也很快。等到IO线程回写Socket完毕主线程会清空全局队列等待客户端的后续请求。 该阶段主线程和IO线程的操作
2 启用多线程
6.0多线程机制默认关闭要启用需在redis.conf中完成两个设置
1.设置io-threads-do-readsyes表示启用多线程。
io-threads-do-reads yes2.设置线程个数。线程个数一般小于Redis实例所在机器的CPU核数。如8核机器Redis官方建议6个IO线程。
io-threads 6若你在实际应用中发现Redis实例CPU开销不大吞吐量却没提升可考虑使用Redis 6.0的多线程机制加速网络处理提升实例吞吐量。
3 实现服务端协助的客户端缓存
6.0实现了服务端协助的客户端缓存功能也称跟踪Tracking功能。业务应用中的Redis客户端就能将读取的数据缓存在业务应用本地应用就能直接在本地快速读取数据。
问题也来了若数据被修改或失效如何通知客户端对缓存的数据做失效处理6.0实现的Tracking功能提供两种模式解决这问题。
3.1 普通模式
实例会在服务端记录客户端读取过的key并监测key是否有修改。一旦key值变化服务端会给客户端发送invalidate消息通知客户端缓存失效
服务端对记录的key只会报告一次invalidate消息也就是说服务端在给客户端发送过一次invalidate消息后如果key再被修改此时服务端就不会再次给客户端发送invalidate消息。
只有当客户端再次执行读命令时服务端才会再次监测被读取的key并在key修改时发送invalidate消息。这样设计的考虑是节省有限的内存空间。毕竟如果客户端不再访问这个key了而服务端仍然记录key的修改情况就会浪费内存资源。
我们可以通过执行下面的命令打开或关闭普通模式下的Tracking功能。
CLIENT TRACKING ON|OFF3.2 广播模式
服务端会给客户端广播所有key的失效情况但这样做后若K被频繁修改服务端会发送大量失效广播消息消耗大量网络带宽资源。
实际应用时会让客户端注册希望跟踪的key的前缀当带有注册前缀的K被修改时服务端会把失效消息广播给所有注册的客户端。和普通模式不同在广播模式下即使客户端还没读取过K但只要它注册了要跟踪的K服务端都会把K失效消息通知给这客户端。
案例 -客户端如何使用广播模式接收key失效消息
当我们在客户端执行下面的命令后如果服务端更新了user1003这个key那么客户端就会收到invalidate消息。
CLIENT TRACKING ON BCAST PREFIX user这种监测带有前缀的key的广播模式和我们对key的命名规范非常匹配。我们在实际应用时会给同一业务下的key设置相同的业务名前缀所以我们就可以非常方便地使用广播模式。
普通模式和广播模式需要客户端使用RESP 3协议RESP 3协议是6.0新启用的通信协议。
对于使用RESP 2协议的客户端来说就需要使用另一种模式
重定向模式redirect
想获得失效消息通知的客户端需执行订阅命令SUBSCRIBE专门订阅用于发送失效消息的频道_redis_:invalidate。同时使用另外一个客户端执行CLIENT TRACKING设置服务端将失效消息转发给使用RESP 2协议的客户端。
案例
如何让使用RESP 2协议的客户端也能接受失效消息
假设客户端B想获取失效消息但客户端B只支持RESP 2协议客户端A支持RESP 3协议。我们可以分别在客户端B和A上执行SUBSCRIBE和CLIENT TRACKING如下所示
//客户端B执行客户端B的ID号是303
SUBSCRIBE _redis_:invalidate//客户端A执行
CLIENT TRACKING ON BCAST REDIRECT 303这样设置以后如果有键值对被修改了客户端B就可以通过_redis_:invalidate频道获得失效消息了。
4 从简单的基于密码访问到细粒度的权限控制
实例的访问权限控制列表功能Access Control ListACL这个特性可以有效地提升Redis的使用安全性。
在Redis 6.0 版本之前要想实现实例的安全访问只能通过设置密码来控制例如客户端连接实例前需要输入密码。
此外对于一些高风险的命令例如KEYS、FLUSHDB、FLUSHALL等在Redis 6.0 之前我们也只能通过rename-command来重新命名这些命令避免客户端直接调用。
Redis 6.0 提供了更加细粒度的访问权限控制这主要有两方面的体现。
首先6.0版本支持创建不同用户来使用Redis。在6.0版本前所有客户端可以使用同一个密码进行登录使用但是没有用户的概念而在6.0中我们可以使用ACL SETUSER命令创建用户。例如我们可以执行下面的命令创建并启用一个用户normaluser把它的密码设置为“abc”
ACL SETUSER normaluser on abc另外6.0版本还支持以用户为粒度设置命令操作的访问权限。我把具体操作列在了下表中你可以看下其中加号和减号-就分别表示给用户赋予或撤销命令的调用权限。
为了便于你理解我给你举个例子。假设我们要设置用户normaluser只能调用Hash类型的命令操作而不能调用String类型的命令操作我们可以执行如下命令
ACL SETUSER normaluser hash -string除了设置某个命令或某类命令的访问控制权限6.0版本还支持以key为粒度设置访问权限。
具体的做法是使用波浪号“~”和key的前缀来表示控制访问的key。例如我们执行下面命令就可以设置用户normaluser只能对以“user:”为前缀的key进行命令操作
ACL SETUSER normaluser ~user:* all好了到这里你了解了Redis 6.0可以设置不同用户来访问实例而且可以基于用户和key的粒度设置某个用户对某些key允许或禁止执行的命令操作。
这样一来我们在有多用户的Redis应用场景下就可以非常方便和灵活地为不同用户设置不同级别的命令操作权限了这对于提供安全的Redis访问非常有帮助。
5 启用RESP 3协议
Redis 6.0实现了RESP 3通信协议而之前都是使用的RESP 2。在RESP 2中客户端和服务器端的通信内容都是以字节数组形式进行编码的客户端需要根据操作的命令或是数据类型自行对传输的数据进行解码增加了客户端开发复杂度。
而RESP 3直接支持多种数据类型的区分编码包括空值、浮点数、布尔值、有序的字典集合、无序的集合等。
所谓区分编码就是指直接通过不同的开头字符区分不同的数据类型这样一来客户端就可以直接通过判断传递消息的开头字符来实现数据转换操作了提升了客户端的效率。除此之外RESP 3协议还可以支持客户端以普通模式和广播模式实现客户端缓存。
6 总结 Redis 6.0是刚刚推出的新的功能特性还需要在实际应用中进行部署和验证所以如果你想试用Redis 6.0可以尝试先在非核心业务上使用Redis 6.0
可以验证新特性带来的性能或功能优势避免因为新特性不稳定而导致核心业务受到影响