阿里巴巴|从 Redis7.0 发布看 Redis 的过去与未来

阿里巴巴|从 Redis7.0 发布看 Redis 的过去与未来

文章图片




前言 经历接近一年的开发、三个候选版本 , Redis 7.0终于正式发布 , 这是Redis历史上改变最多的一个大版本 , 它不仅包含了50多个新命令 , 还有大量核心新特性与改进 , 这些不仅能够解决用户使用中的诸多问题 , 还进一步拓展了Redis的使用场景 。
虽然Redis 7.0做了许多大胆的尝试 , 但是稳定性依然是最重要的基石 。 Redis官方在7.0的GA博文中也强调这一点:“While user-facing features are easy to boast of the real “unsung heroes” in this version are efforts to make Redis more performant stable and lean.”(虽然面向用户的功能更容易得到称赞 , 但这个版本中的无名英雄是我们持续不断的对Redis的优化 , 使其变得更加精简、高效、稳定) 。 相信从这里可以看出 , Redis发展至今稳定性始终被摆在最重要的位置 , 因此对于7.0的稳定性担忧大可打消 。
下面请先跟随我们一同了解Redis7.0的几个核心新特性 。
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的数据可靠性 , 满足用户数据回档等需求 。