Redis 6.0新特性,你知道几个?
你好,我是猿java。
首先让我们先来看一张图片:
上图是截取Redis官网首页,想必对Redis有所了解的小伙伴并不陌生了,截止当前时间,Redis官方6.0的最后一个stable版本已经更新到6.2.6,其实7.0-RC1版本已经有了,可以从github拉源码看看。
2020年5月,Redis官方推出6.0的第一个版本,到现在差不多1年的时间,官方宣传说:Redis 6.0是一个更新跨度比较大的版本,里面带来了一些革命性的新特性,今天是2022虎年的大年初四,因为疫情被困杭州,闲暇之际,特写此文分享一下个人对 6.0 新特性的研究,期待与更多的你一起探讨。
要想研究Redis6.0的新特性,自然要看权威宣布,详情参考Redis作者 antirez的官宣,下图截取了新特性部分内容:
针对上面的新特性,博主会挑选几个比较重要的来展开讨论:
1. 新特性–多线程
多线程是备受关注的一个特性,因为在6.0版本之前,redis给大家的印象一直是单线程(其实4.0版本之后也使用了多线程),那么redis 6.0 官方为什么要打破常规,引进多线程呢?
原因:Redis是内存数据库,操作内存的速度很快,所以Redis的性能瓶颈不是cpu而是网络IO。随着硬件技术的快速发展,单个主线程处理网络请求的速度已经跟不上底层网络硬件的速度,也就是软件速度跟不上硬件速度,所以软件需要升级,需要把网络IO交给多线程处理。
1 | 备注:Redis单线程,主要是指Redis的网络IO和键值对读写由一个线程来完成。 |
针对多线程要特别说明:Redis 的多 IO 线程只是用来处理网络请求,对于读写命令,Redis 仍然使用原来的单线程来处理。
那为什么Redis的多线程只是用于处理网络请求呢?为什么读写等操作不放到多线程中处理呢?
在引进多线程的原因中有提到Redis的性能瓶颈在网络IO,所以处理了这个问题就解决了核心问题,另外读写命令还是保留原来的单线程,主要有2个原因:
读写命令它并不是性能瓶颈,所以无需画蛇添足。
保留单线程,原来读写命令主线程的单线程模型不会被破坏,也就不会因为引入多线程带来额外的互斥机制,比如:保证 Lua 脚本、事务的原子性。
于此,对于Redis的这种解决问题的思路是不是可以启发我们:平时工作一定要把握核心问题,切勿本末倒置或画蛇添足。
下面我把redis单线程和多线程模型整理成下面两张图片:
开启多线程的方法
redis.conf文件中 配置项为 yes,表示启用多线程,默认是关闭状态。
1 | io-thread-do-reads yes |
使用建议
对于CPU消耗不大,吞吐量上不去的应用,可以考虑开启多线程。但是,毕竟多线程功能推出时间不久,如果不是对性能有苛刻要求,建议慎用,以免对生产造成事故,建议可以运用在一些重要级不高的服务,一来练手,二来可以把控风险。
2. 新特性–客户端缓存
在Redis 6.0,客户端可以缓存服务端返回的数据,业务可以直接快速读取本地缓存数据。既然客户端会缓存数据,那势必会存在多份数据,于是就会产生经典的问题:如何保证客户端和服务器数据的一致性?
Redis 6.0 的Tracking功能提供了2种模式来解决该问题:
普通模式
服务端保存客户端读取的所有key,一旦有key失效,服务端给客户端发送 invalidate消息,告知客户端key已失效,客户端就会删除对应的缓存。服务端也会把记录的key记录删除。
广播方式
服务器给客户端广播所有失效的key,这种方式存在的问题是:当多个客户端共用一个redis时,势必导致自己不关心key也会受到invalidate消息,造成了无效的网络开销和处理干扰。
处理方式:客户端可以注册需要跟踪的key,这样服务器只把客户端注册的key的invalidate消息通知给客户端
3. 新特性–RESP 3协议
Redis 6.0之前的版本使用的是RESP 2,Redis 6.0实现了RESP 3通信协议。
两者的区别:
- RESP 2:客户端和服务器端的通信内容是以字节数组形式进行编码,客户端需要根据操作的命令或是数据类型自行对传输的数据进行解码,增加了客户端开发复杂度。
- RESP 3 直接支持多种数据类型的区分编码(直接通过不同的开头字符,区分不同的数据类型),包括空值、浮点数、布尔值、有序的字典集合、无序的集合等。客户端可以通过判断传递消息的开头字符,来实现数据转换,大大提升效率。
新特性中普通模式和广播模式实现客户端缓存也可以通过RESP 3 协议来支持。
4. 新特性–细粒度的权限控制ACL
Redis 6.0之前版本,只能通过设置密码来控制安全访问,Redis 6.0提供了2个维度来控制权限。
1. 创建多用户
Redis 6.0版本之前,只能共用一个账号/密码访问redis,Redis 6.0之后可以向mysql一样,创建多用户来隔离权限。指令:
1 | ACL SETUSER 用户名 on > 密码 |
2. 针对用户控制命令操作的访问权限
权限操作命令如下表,+:增加 -:减少
举例:
1 | 针对用户admin,只能调用String类型的命令操作,而不能调用Hash类型的命令操作 |
到此,redis 6.0 的新特性就分享完成,本片文章,没有非常深入的讲解redis的实现,只是从宏观的角度阐述了下,如果你还想更深入的了解redis,可以到Redis官网或从github上拉源码(redis是c语言开发),了解更深细节从源码开始。
学习交流
如果你觉得文章有帮助,请帮忙转发给更多的好友,或关注公众号:猿java,持续输出硬核文章。