upan / cheat-sheet

常用工具和开源项目链接收藏
33 stars 17 forks source link

Redis版本历史 #26

Open upan opened 1 year ago

upan commented 1 year ago

概述

Redis 官网,官网文档Redis Release

当前最新版本

Redis 7 【2022-04-27】

经历接近一年的开发、三个候选版本,Redis 7.0终于正式发布,这是Redis历史上改变最多的一个大版本,它不仅包含了50多个新命令,还有大量核心新特性与改进,这些不仅能够解决用户使用中的诸多问题,还进一步拓展了Redis的使用场景。

Redis7.0核心新特性概览

Function

Function是Redis脚本方案的全新实现,在Redis 7.0之前用户只能使用EVAL命令族来执行Lua脚本,但是Redis对Lua脚本的持久化和主从复制一直是undefined状态,在各个大版本甚至release版本中也都有不同的表现。因此社区也直接要求用户在使用Lua脚本时必须在本地保存一份(这也是最为安全的方式),以防止实例重启、主从切换时可能造成的Lua脚本丢失,维护Redis中的Lua脚本一直是广大用户的痛点。

Function的出现很好的对Lua脚本进行了补充,它允许用户向Redis加载自定义的函数库,一方面相对于EVALSHA的调用方式用户自定义的函数名可以有更为清晰的语义,另一方面Function加载的函数库明确会进行主从复制和持久化存储,彻底解决了过去Lua脚本在持久化上含糊不清的问题。

那么自7.0开始,Function命令族和EVAL命令族有了各自明确的定义:FUNCTION LOAD会把函数库自动进行主从复制和持久化存储;而SCRIPT LOAD则不会进行持久化和主从复制,脚本仅保存在当前执行节点。并且社区也在计划后续版本中让Function支持更多语言,例如JavaScript、Python等,敬请期待。

总的来说,Function在7.0中被设计为数据的一部分,因此能够被保存在RDB、AOF文件中,也能通过主从复制将Function由主库复制到所有从库,可以有效解决之前Lua脚本丢失的问题,我们也非常建议大家逐步将Redis中的Lua脚本替换为Function。

Multi-part AOF

AOF是Redis数据持久化的核心解决方案,其本质是不断追加数据修改操作的redo log,那么既然是不断追加就需要做回收也即compaction,在Redis中称为AOF rewrite。

然而AOF rewrite期间的增量数据如何处理一直是个问题,在过去rewrite期间的增量数据需要在内存中保留,rewrite结束后再把这部分增量数据写入新的AOF文件中以保证数据完整性。可以看出来AOF rewrite会额外消耗内存和磁盘IO,这也是Redis AOF rewrite的痛点,虽然之前也进行过多次改进但是资源消耗的本质问题一直没有解决。

阿里云的Redis企业版在最初也遇到了这个问题,在内部经过多次迭代开发,实现了Multi-part AOF机制来解决,同时也贡献给了社区并随此次7.0发布。具体方法是采用base(全量数据)+inc(增量数据)独立文件存储的方式,彻底解决内存和IO资源的浪费,同时也支持对历史AOF文件的保存管理,结合AOF文件中的时间信息还可以实现PITR按时间点恢复(阿里云企业版Tair已支持),这进一步增强了Redis的数据可靠性,满足用户数据回档等需求。

对具体实现感兴趣的同学可以查看本文末尾参考资料。

Sharded-pubsub

Redis自2.0开始便支持发布订阅机制,使用pubsub命令族用户可以很方便地建立消息通知订阅系统,但是在cluster集群模式下Redis的pubsub存在一些问题,最为显著的就是在大规模集群中带来的广播风暴。

Redis的pubsub是按channel频道进行发布订阅,然而在集群模式下channel不被当做数据处理,也即不会参与到hash值计算无法按slot分发,所以在集群模式下Redis对用户发布的消息采用的是在集群中广播的方式。

那么问题显而易见,假如一个集群有100个节点,用户在节点1对某个channel进行publish发布消息,该节点就需要把消息广播给集群中其他99个节点,如果其他节点中只有少数节点订阅了该频道,那么绝大部分消息都是无效的,这对网络、CPU等资源造成了极大的浪费。

Sharded-pubsub便是用来解决这个问题,意如其名,sharded-pubsub会把channel按分片来进行分发,一个分片节点只负责处理属于自己的channel而不会进行广播,以很简单的方法避免了资源的浪费。

概述

image

Redis 使用标准版本标记进行版本控制:major.minor.patchlevel。 偶数的版本号表示稳定的版本, 例如 1.2,2.0,2.2,2.4,2.6,2.8。 奇数的版本号用来表示非标准版本,例如2.9.x是非稳定版本,它的稳定版本是3.0。

Redis2.6

Redis2.6在2012年正式发布,经历了17个版本,到2.6.17版本,相比于Redis2.4,主要特性如下:

1) 服务端支持Lua脚本。 2) 去掉虚拟内存相关功能。 3) 放开对客户端连接数的硬编码限制。 4) 键的过期时间支持毫秒。 5) 从节点提供只读功能。 6) 两个新的位图命令:bitcount和bitop。 7) 增强了redis-benchmark的功能:支持定制化的压测,CSV输出等功能。 8) 基于浮点数自增命令:incrbyfloat和hincrbyfloat。 9) redis-cli可以使用–eval参数实现Lua脚本执行。 10) shutdown命令增强。 11) info可以按照section输出,并且添加了一些统计项。 12) 重构了大量的核心代码,所有集群相关的代码都去掉了,cluster功能将会是3.0版本最大的亮点。 13) sort命令优化。

Redis2.8

Redis2.8在2013年11月22日正式发布 经历了24个版本,到2.8.24版本,相比于Redis2.6,主要特性如下:

1) 添加部分主从复制的功能,在一定程度上降低了由于网络问题, 造成频繁全量复制生成RDB对系统造成的压力。 2) 尝试性地支持IPv6。 3) 可以通过config set命令设置maxclients。 4) 可以用bind命令绑定多个IP地址。 5) Redis设置了明显的进程名,方便使用ps命令查看系统进程。 6) config rewrite命令可以将config set持久化到Redis配置文件中。 7) 发布订阅添加了pubsub命令。 8) Redis Sentinel第二版,相比于Redis2.6的Redis Sentinel,此版本已经变成生产可用。

Redis3.0

Redis3.0在2015年4月1日正式发布,截止到本书完成已经到3.0.7版本,相比于Redis2.8主要特性如下:

Redis3.0最大的改动就是添加Redis的分布式实现Redis Cluster,填补了Redis官方没有分布式实现的空白。Redis Cluster经历了4年才正式发布也是有原因的,具体可以参考Redis Cluster的开发日志

1) Redis Cluster: Redis的官方分布式实现。 2) 全新的embedded string对象编码结果,优化小对象内存访问,在特定的工作负载下速度大幅提升。 3) lru算法大幅提升。 4) migrate连接缓存, 大幅提升键迁移的速度。 5) migrate命令两个新的参数copy和replace。 6) 新的client pause命令,在指定时间内停止处理客户端请求。 7) bitcount命令性能提升。 8) config set设置maxmemory时候可以设置不同的单位(之前只能是字节),例如config set maxmemory1gb。 9) Redis日志小做调整:日志中会反应当前实例的角色(master或者slave)。 10) incr命令性能提升。

Redis3.2

Redis3.2在2016年5月6日正式发布,相比于Redis3.0主要特征如下:

1) 添加GEO相关功能。 2) SDS在速度和节省空间上都做了优化。 3) 支持用upstart或者systemd管理Redis进程。 4) 新的List编码类型:quicklist。 5) 从节点读取过期数据保证一致性。 6) 添加了hstrlen命令。 7) 增强了debug命令 支持了更多的参数。 8) Lua脚本功能增强。 9) 添加了Lua Debugger。 10) config set支持更多的配置参数。 11) 优化了Redis崩溃后的相关报告。 12) 新的RDB格式,但是仍然兼容旧的RDB。 13) 加速RDB的加载速度。 14) spop命令支持个数参数。 15) cluster nodes命令得到加速。 16) Jemalloc更新到4.0.3版本。

Redis4.0

可能出乎很多人的意料,Redis3.2之后的版本是4.0,而不是3.4、3.6、3.8。一般这种重大版本号的升级也意味着软件或者工具本身发生了重大变革,直到本书截稿前,Redis发布了4.0-RC2,下面列出Redis4.0的新特性:

1) 提供了模块系统,方便第三方开发者拓展Redis的功能,更多模块详见:http://redismodules.com/。 2) PSYNC2.0:优化了之前版本中,主从节点切换必然引起全量复制的问题。 3) 提供了新的缓存剔除算法:LFU(Last Frequently Used),并对已有算法进行了优化。 4) 提供了非阻塞del和flushall/flushdb功能,有效解决删除bigkey可能造成的Redis阻塞。 5) 提供了RDB-AOF混合持久化格式,充分利用了AOF和RDB各自优势。 6) 提供memory命令,实现对内存更为全面的监控统计。 7) 提供了交互数据库功能,实现Redis内部数据库之间的数据置换。 8) Redis Cluster兼容NAT和Docker。

Redis5.0

Redis 5.0在2018年10月正式发布,相比于Redis4.0主要特征如下:

1) 新的流数据类型(Stream data type) https://redis.io/topics/streams-intro 2) 新的 Redis 模块 API:定时器、集群和字典 API(Timers, Cluster and Dictionary APIs) 3) RDB 增加 LFU 和 LRU 信息 4) 集群管理器从 Ruby (redis-trib.rb) 移植到了redis-cli 中的 C 语言代码 5) 新的有序集合(sorted set)命令:ZPOPMIN/MAX 和阻塞变体(blocking variants) 6) 升级 Active defragmentation 至 v2 版本 7) 增强 HyperLogLog 的实现 8) 更好的内存统计报告 9) 许多包含子命令的命令现在都有一个 HELP 子命令 10) 客户端频繁连接和断开连接时,性能表现更好 11) 许多错误修复和其他方面的改进 12) 升级 Jemalloc 至 5.1 版本 13) 引入 CLIENT UNBLOCK 和 CLIENT ID 14) 新增 LOLWUT 命令 http://antirez.com/news/123 15) 在不存在需要保持向后兼容性的地方,弃用 “slave” 术语 16) 网络层中的差异优化 17) Lua 相关的改进 18) 引入动态的 HZ(Dynamic HZ) 以平衡空闲 CPU 使用率和响应性 19) 对 Redis 核心代码进行了重构并在许多方面进行了改进

Redis6.0

Redis 6.0在2020年5月正式发布,相比于Redis5.0主要特征如下:

1)ACL权限管控(包括ACL LOG) 2)客户端缓冲(Client side caching) 3)多线程 IO(Threaded I/O) 4)Redis集群代理 5)支持linux/bsd系统的CPU和线程(包括子线程如aof\rdb\IO线程)亲和力绑定 6)过期Key回收优化,新增主动配置参数 7)Resp3协议,兼容Resp2并更加简单、高效 8)优化了INFO命令,使之执行更快,优化了所有的阻塞命令,复杂度从O(n)到O(1),RDB加载速度优化,集群Slots命令优化,Psync2优化,修复了5.0的链式复制不一致问题。defrag优化,从试验版到正式版 9)新的module API 10)disque消息队列模块(module) 11)新增配置使Del命令如unlink执行 12)XINFO STREAM FULL流命令 13)CLIENT KILL USER username命令 14)全面支持SSL协议、并新增TSL协议 15)Redis-benchmark支持集群模式 16)重写 Systemd 支持 17)新增配置参数来删除用于在非持久性实例中进行复制的RDB文件 18)无磁盘复制副本(Diskless replication on replicas),从测试版优化,目前无磁盘复制在load rdb仍是测试版。

Redis7.0

Redis 7.0 RC1 于 2022 年 1 月 31 日发布,主要特性如下

1)Redis 函数:使用服务器端脚本扩展 Redis 的新方法 2) ACL:细粒度的基于密钥的权限,允许用户支持多个带有选择器的命令规则集 3) 集群:分片(特定于节点)发布/订阅支持 https://redis.io/topics/pubsub#sharded-pubsub 4) 在大多数情况下对子命令的一流处理 5) 命令元数据和文档 [https://redis.io/commands/command-docs, https://redis.io/topics/command-tips]([https://redis.io/commands/command-docs, https://redis.io/topics/command-tips](https://redis.io/commands/command-docs,%20https://redis.io/topics/command-tips)) 6)命令键规格。一种更好的方式让客户找到关键论点及其读/写目的 https://redis.io/topics/key-specs 7)多部分 AOF 机制避免 AOF 重写开销 8)集群:支持主机名,而不仅仅是 IP 地址 9)改进了对网络缓冲区消耗的内存的管理,以及一个选项当总内存超过限制时删除客户端 10)Cluster:一种断开集群总线连接的机制,以防止不受控制的缓冲区增长 11)AOF:时间戳注释和对时间点恢复的支持 12)Lua:支持 EVAL 脚本中的函数标志https://redis.io/topics/eval-intro#eval-flags 13)Lua: 支持 Verbatim 和 Big-Number 类型的 RESP3 回复 14)Lua: 通过 redis.REDIS_VERSION, redis.REDIS_VERSION_NUM 获取 Redis 版本

参考

upan commented 1 year ago

Redis系列之——前世今生

演进:

Redis从诞生之日从未停止过发展,直到我们现在的使用有过无数版本的更迭,这里我挑选几个重大的转折点向大家介绍:

  1. 2009年Redis诞生
  2. 2012年发布了Redis2.6版本,正式的支持lua脚本
  3. 2015年发布了Redis3.0版本,官方提出了分布式实现Redis Cluster
  4. 2017年发布了Redis4.0版本,提供了RDB-AOF混合持久化格式
  5. 2018年发布了Redis5.0版本,对核心代码进行了大范围的重构
  6. 2020年发布了Redis6.0版本,Redis引入了多线程的概念,使用多线程来处理网络数据的读写和协议解析
  7. 2022年发布了Redis7.0版本,提供了不同于lua表达式的RedisFunctions功能