Redis 7.0

Posted by Yano on June 4, 2022

新特性概述

安装 7.0

https://redis.io/download/

核心特性

https://github.com/redis/redis/blob/7.0/00-RELEASENOTES

  • Function
  • Multi-part AOF
  • Sharded-pubsub

Function

Redis functions

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

Redis persistence # Append-only file

6.0 AOF 实现:Redis 源码简洁剖析 15 - AOF

Since Redis 7.0.0, Redis uses a multi part AOF mechanism. That is, the original single AOF file is split into base file (at most one) and incremental files (there may be more than one). The base file represents an initial (RDB or AOF format) snapshot of the data present when the AOF is rewritten. The incremental files contains incremental changes since the last base AOF file was created. All these files are put in a separate directory and are tracked by a manifest file.

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 Pub/Sub # 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 而不会进行广播,以很简单的方法避免了资源的浪费。

参考链接

Redis 源码简洁剖析系列

Java 编程思想-最全思维导图-GitHub,需要的小伙伴可以自取~

原创不易,希望大家转载时请先联系我,并标注原文链接。

我的公众号

coding 笔记、读书笔记、点滴记录,以后的文章也会同步到公众号(Coding Insight)中,希望大家关注^_^