关于redis:从Redis70发布看Redis的过去与未来

68次阅读

共计 7119 个字符,预计需要花费 18 分钟才能阅读完成。

简介:经验靠近一年的开发、三个候选版本,Redis 7.0 终于正式公布,这是 Redis 历史上扭转最多的一个大版本,它不仅蕴含了 50 多个新命令,还有大量外围新个性与改良,这些不仅可能解决用户应用中的诸多问题,还进一步拓展了 Redis 的应用场景。
发布会详情:https://developer.aliyun.com/…

image.png

前言
经验靠近一年的开发、三个候选版本,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 的数据可靠性,满足用户数据回档等需要。

对具体实现感兴趣的同学能够查看本文开端参考资料。

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 而不会进行播送,以很简略的办法防止了资源的节约。

Client-eviction
Redis 反对内存规格配置,maxmemory 和 maxmemory-policy 大家曾经都很相熟了,然而在这里我还是想再解释一下:maxmemory 管制的是 Redis 的整体运行内存而非数据内存,例如 client buffer、lua cache、fucntion cache、db metadata 等这些都会算在运行内存中,如果运行内存超过了 maxmemory 就会触发 evict 删除数据,这也是用户在应用 Redis 时的一大痛点。

在这些非数据内存应用当中,又以 client buffer 耗费最大,在大流量场景下 client 须要缓存很多用户读写数据(设想一下 keys 的后果须要先缓存在 client output buffer 中再发送给用户),因为网络流量的内存耗费导致触发 eviction 删除数据的状况十分之多。尽管 Redis 很早就反对对 client-output-buffer-limit 配置项,但其限度的也只是单个连贯维度的 output buffer,没有全局统计 client 应用内存和限度。为了解决这个问题,7.0 新增了 maxmemory-clients 配置项,来对所有 client 应用的内存做限度,如果超过了这个限度就会筛选内存耗费最大的 client 开释,用来缓解内存应用的耗费。

Client-eviction 并不是起点,还有很多元数据的内存应用会对用户造成困扰,Redis 是基于内存的数据库,咱们须要对各个模块的内存进行更准确的统计和管制,让用户可能对数据存储有更为清晰的了解和布局。

Redis 历史回顾
Redis 倒退至今已历经 7 个大版本,而每个大版本都有大量的新个性产生。例如从 3.0 开始反对 cluster 集群模式;4.0 开发的 lazyfree 和 PSYNC2 解决了 Redis 短暂的大 key 删除阻塞问题及同步中断无奈续传的问题;5.0 新增了 stream 数据结构使 Redis 具备性能残缺的轻量级音讯队列能力;6.0 更是公布了诸多企业级个性如 threaded-io、TLS 和 ACL 等,大幅晋升了 Redis 的性能和安全性。

国内开发者与 Redis 社区建设
感激国内开发者,中国区曾经成为 Redis 社区最大的奉献起源之一
阿里云从 Redis 4.0 开始就深度参加到 Redis 开源社区当中,向社区奉献了大量能力,目前阿里云在 Redis 社区共有 1 名 core team member(外围维护者)和 2 名 contributor(外围贡献者),是原作者和 Redis Labs 以外对 Redis 社区奉献最大的组织。

咱们见证了 Redis 用户在国内的快速增长,阿里云与 Redis 社区的深度单干也逐步吸引了更多的国内开发者参加到 Redis 建设中去。尤其是在 Redis core team 成立之后,社区 maintainer 也和 Redis 一样变成了多线程(1->5),对于 issue 和 PR 的疾速解决大幅晋升了社区的活跃度。这次 7.0 的 release note 中也能够看到曾经有超过 5 名国内开发者奉献了外围 feature,并奉献了近半数 commit。

这些变动与咱们在阿里云上的统计后果也是相符合的:Redis 目前同样也已是国内用户应用规模最大的 NoSQL 数据库之一,并始终处于高速增长中,越来越多的泛互联网甚至传统行业也在逐渐接收 Redis,用于疾速高效的构建业务应用服务。

尽管 Redis 倒退迅速,但国内用户却大都无奈享受技术红利
Redis 社区目前支流保护版本是 6.0,5.0 版本曾经进入低维护阶段,而国内还有大量 2.8,3.0,4.0 版本在应用中。这就很矛盾,一方面,一些对用法,性能,稳定性和抖动管制的能力都奉献在了新版本上,另一方面,国内用户却“看的到,用不上”。

除去 6.0,7.0 上的高级稳定性优化不说,比方在 4.0 前,没有 lazyfree 删除一个大 key 是同步的会卡住数据库引擎间接导致业务中断。又比方,Redis 其实安全性尤其是 lua 是始终有较大问题的,这些降级也都“隐含”在了新版本中。尽管阿里云依然在保持把这些破绽的修复拉回到低版本上,然而在公网当中还是有大量的低版本实例存在平安危险。

过多用户放心降级版本的兼容性,一方面阿里云也在要求社区来提供一些兼容性验证工具,另一方面阿里云对版本跟进是很快的,能够让用户在新版公布后尽快进行验证。从 Redis 整体和阿里云的大量客户降级状况来看,版本的向前兼容性是十分好的,大可释怀降级。

心愿更多的国内用户深度参加社区建设
国外应用 Redis 的形式和国内应用显著有差别,比方国外更多的是应用在缓存场景,而国内大多数的用法却是内存数据库。社区的倒退和 roadmap 的制订,目前国内用户的声音较小。

目前国内开发者在社区活跃度很高,但更多的是围绕在 bugfix,和 feature 上。咱们还是倡议无论是国内开发者还是使用者能够深层参加进去,举个简略的例子,提需要、讲明确需要、证实需要的合理性都是参加社区建设,这样能力更好的把咱们国内的需要传播,后续甚至能够深度参加开发,跟踪交付,这些社区工作的含金量无疑更高。

在性能上,不仅仅包含 API 层面的减少,包含接入,可观测性,一致性,一致性和平安等目前社区都在期待需要中。尽管 core team member 能够代表国内用户来把一些需要写进 roadmap,然而实在用户的发声会提供更无力的撑持。

Redis 应用场景拓展与瞻望 –Redis 还能做什么?
多模服务进入暴发期
Redis 是始终贴着用户应用倒退起来的,它如此受欢迎次要因为两个特点,极高的性能以及丰盛、方便使用的数据结构,这些简略好用的数据结构可能大幅度降低开发业务复杂度。

咱们能够看到,以 Redislabs 为代表的厂商正在鼎力的丰盛 Redis 的数据结构(modules),如 RedisSearch、Redis-Json、RedisGraph、RedisTimeSeries 和 RedisBloom 等。

同样的,阿里云内存数据库 Tair 很早就在研发各类加强数据结构和模块,目前咱们在公共云 Tair 服务中提供的商业化扩大型数据结构比 Redislabs 提供的更多,局部模块性能更强,有趣味可参见文档(本文开端参考资料)。

目前已有大量云上用户在利用 Tair 增强型数据结构来构建代码,进步开发效率,甚至实现此前难以完成的工作。2022 年是一个 Redis 扩大构造的暴发年,业内曾经度过接收期,进入高速倒退阶段。无论是 Tair 还是 Redis,咱们置信不断丰富的数据结构可能让它们走的更远,从缓存演变为高性能的计算型内存数据库,冲破、并解决更多场景问题。

一致性能力上的倒退
落盘一致性和正本一致性是应用数据库绕不开的两个话题。长期以来许多人对 Redis 的利用场景仅仅认定为缓存(尤其是国外用户)。Redis 自诞生之初便反对长久化机制 RDB 和 AOF,并且 AOF 还提供了不同级别的长久化语义:如 appendfsync 采纳最高级别 always 时能够保证数据齐全落盘不失落,具备与传统数据库一样的强落盘一致性。

在多正本一致性上,次要是指主备一致性上,原生的 Redis 仍旧采纳异步复制,数据批改操作只有在本地执行实现就会返回后果,相比于其余数据库没有提供正本间数据强统一的语义。这也限度了 Redis 的应用场景,在对数据可靠性有极高要求的用户(例如金融行业,和传统行业)中还没有被齐全接收。

目前业内也都在对 Redis 的长久化能力上进行倒退。比拟有代表性的,是阿里云的 Tair 长久内存版、AWS 的 MemoryDB、和业内开源的一些 Redis-like 的基于 rocksdb 的零碎,商业化如 Tair 的容量存储版(前混合存储)。

image.png

表 1: 社区 Redis 和其余商业化、开源产品的落盘一致性与正本一致性比照
注 1:与开源 Redis 社区版比拟
注 2:与开源 Redis 基于内存的应用老本比拟
注 3,4:来自 AWS 官网博客测试数据

综合来看,随着用户对 Redis 的利用范畴的扩充,与此同时对于容量、老本和数据可靠性的需要也在一直晋升,这些也逐步成为了掂量 Redis 企业级能力的重要指标。各大厂商和开源产品也都在构建这些能力上提出了许多解决方案。上面介绍一些典型产品和计划。

AWS 的 MemoryDB
AWS MemoryDB 的思路是基于相似 Aurora 的共享存储概念,把日志寄存在远端共享存储中,同时内存中依然保留 Redis 原有的构造。通过这种形式晋升数据的长久化一致性,同时也保障了数据读取的延时和吞吐;而毛病则同样因为日志保留在远端,写入性能重大降落(仅有 ElastiCache 也即 Redis 社区版的 15%~25%,该数据来自 AWS 官网评测,见本文开端参考资料)。在主备一致性上,因为间接采取日志的物理复制,所以主备一致性近似靠近落盘一致性。

值得一提的是原来 AOF rewrite 这种压缩(compaction)引起的开销也因为在远端做掉而躲避掉,因而是一种很彻底的云原生解法。

阿里云自研内存数据库 Tair
在长久化上阿里云走了另外一条路,通过引入新介质长久化内存来解决老本,大容量和长久化能力的问题。这个计划带来的挑战是应用长久化内存存储结构设计上较为简单,既要管制性能衰减,又要保障兼容性。Tair 长久内存很好的解决了这些问题,比照 MemoryDB 老本更低,读性能根本持平的状况下写入的速度也更快(见本文开端参考资料),更要害的是根本原封原样的兼容了 Redis API,大幅升高了用户的切换老本。

并且,Tair 长久内存型还反对半同步和强写入一致性,无论 MemoryDB 还是 Tair 长久内存都真正的做到了内存数据库的数据容错性要求。

其余开源产品的倒退
国内也呈现了一些原创性的优良落盘开源产品(Redis-Like 零碎),这些产品大都基于 LSM 存储构造如 rocksdb 上的。它们的长处次要是磁盘介质绝对内存更为便宜,但同样目前存在的毛病也十分多:运维复杂度较高,间接映射为运维老本、KV 无奈原生的反对 Redis 的数据结构、把 Redis 的强类型变成弱类型等等。

目前这类零碎在一致性和容错性上仍有很大的改善空间,而在用户应用体感上,因为很多用户应用习惯还是把 Redis-like 零碎用在业务的同步链路上,对于 LSM KV 引擎的延时上抖动整体吞吐的影响间接映射成了用户体感,因而很难作为一款通用型产品,而这些痛点也同样存在与 Tair 容量存储型中(过来叫混合存储版),这也是一个须要长期在存储和兼容性上优化的方向。

综上所述,容量版本能够很好地解决用户的应用老本问题,然而只有更好地解决了落盘一致性问题和正本一致性问题,才可能把 Redis 类零碎的应用场景拓展到企业级。这也是目前看来云厂商一个强烈竞争的企业级产品支流赛道,也有较高的技术门槛。

写在最初
Redislabs 在 2021 年 8 月正式更名为 Redis,大家看到社区版 Redis 的主页也曾经重构批改过了。自身 Redis 的商业化进度十分快,比方在主页上“夹带”Redis Stack;又比方在 github 上将一众罕用的 SDK 都购买后,开始增加局部 Redislabs 商业化开源的反对等。最初 Redis 可能也会像 MongoDB,ElasticSearch 一样走向彻底的商业化。但目前社区仍是十分公开和沉闷的。

Redis8.0 的 feature 打算曾经开始,一方面咱们也如上文所述,倡议国内开发者更多的参加到深层次的社区探讨,让社区更多的向国内应用习惯聚拢,这对重度依赖 Redis 的国内企业状况是十分事实的;另一方面,可能通过社区参加来晋升咱们的人才竞争力,除去长久化零碎,还有分布式架构,高吞吐低延时外围引擎,多模服务和脚本引擎,平安与审计等都须要继续投入。如果国内在 Redis 畛域也可能有 10~20 名内存数据库的顶尖专家,那么即使是 Redis 走向商业化闭源其影响对国内用户都会十分小。

最初,欢送大家应用 Redis7.0,也愿咱们一起在 Redis 等内存数据库技术上走得更远!

正文完
 0