Redis,这款在当代软件架构中占据核心地位的内存数据结构存储系统,其发展历程是一部充满创新、应对挑战和社群驱动演进的生动史诗。从其创始人为解决特定业务痛点而进行的早期探索,到如今成为支持大规模、高性能应用的关键组件,Redis 的故事不仅反映了技术的进步,也折射出开源软件发展的动态与复杂性。本报告旨在追溯 Redis 从诞生至今的关键里程碑、核心设计哲学、主要版本迭代、社群互动及其对现代应用架构的深远影响。
起源:源于需求的解决方案
Redis 的诞生,并非源于纯粹的学术研究或某种预设的技术探索,而是为了解决一个迫在眉睫的、非常具体的实际业务问题。这个问题的核心,以及由此催生出的独特设计理念,共同奠定了 Redis 未来发展的基调。
Salvatore “antirez” Sanfilippo 与 LLOOGG 的挑战
Salvatore Sanfilippo,一位在安全领域(他因 hping 工具和著名的 idle scan 攻击而闻名)和嵌入式系统(他是 Jim Tcl 解释器的作者)均有建树的意大利开发者,在运营其初创公司 LLOOGG 时,遇到了一个严峻的技术瓶颈。LLOOGG 是一款实时的网站流量分析产品(或者可以称之为日志分析器),其后端所依赖的 MySQL 数据库,在处理高并发写入请求和快速分析近期产生的大量数据方面,显得力不从心,性能堪忧。
这个在现实世界中遇到的性能难题,成为了 Redis 诞生的直接催化剂。Sanfilippo 意识到,他迫切需要一种新型的内存数据库。这种数据库不仅要能够高效地处理各种复杂的数据结构,尤其重要的是,它要能够快速地执行列表操作,以便能够经济有效地满足 LLOOGG 项目的独特需求。正如他本人后来所述:“在我努力解决我的新产品所面临的可伸缩性问题时,我开始意识到,我真正需要的是一个能够支持复杂数据结构的内存数据库……Redis 就是这样开始的——我先写了一个原型,结果它很好地解决了我们当时面临的问题。”
最初的开发工作始于2009年初。到了同年的6月,Redis 项目已经足够稳定,可以被成功地部署到 LLOOGG 的生产环境中,并成功地取代了原有的 MySQL 系统。这次早期的实际应用,不仅解决了 LLOOGG 当时的燃眉之急,也成为了 Redis 核心设计理念的首次实战验证。
核心设计哲学:速度、简洁与强大的数据结构
Redis 从其诞生之初,就确立了其独特而鲜明的设计哲学,这些核心原则深刻地影响了它的整体架构和功能集合:
- 内存优先 (In-Memory First): 最为根本的一条原则,就是将整个数据集都存储在 RAM(随机存取存储器)之中,以此来实现极低的读写延迟。这可以说是针对 LLOOGG 项目中遇到的磁盘 I/O 性能瓶颈的直接回应。这一特性,是 Redis 身份的核心所在。
- 单线程命令执行 (Single-Threaded Command Execution): Sanfilippo 做出了一个在当时看来颇为反常规的决定:采用单线程的事件循环来处理核心的命令执行。这个设计基于高效的 I/O 多路复用技术(例如在 Linux 操作系统上使用 epoll,在 BSD/macOS 操作系统上使用 kqueue),其主要目的是为了消除多线程编程中常见的锁机制和同步操作所带来的额外开销与内在复杂性。正如一些分析所解释的那样:“在一个像 Redis 这样的内存密集型系统中,最大的性能提升并非来自于并行执行本身,而是来自于对各种不必要开销的消除。”这一点,也自然而然地引出了 Redis 的下一个重要特性。
- 操作原子性 (Atomicity of Operations): Redis 中的每一个命令都被设计成是原子性的,也就是说,它要么作为一个不可分割的单元被完整地执行,要么就根本不执行,不会出现部分执行的状态。这种设计极大地简化了应用程序的开发过程,减少了开发者对竞态条件和数据一致性问题的担忧。这种操作上的原子性,可以说是其单线程模型的一个直接产物。
- 丰富的基础数据结构 (Rich, Foundational Data Structures): Redis 并没有将数据隐藏在复杂的 API 或关系模型之后,而是选择直接向开发者暴露了诸如字符串(Strings)、列表(Lists)、集合(Sets)和哈希(Hashes)等一系列基础且强大的数据结构。这种直接的方法,对于程序员来说通常非常直观,并允许他们能够为各种不同的问题进行自然而高效的数据建模。
- 开发者体验 (Developer Experience): 从项目一开始,Redis 就非常注重易用性、简洁的客户端通信协议以及清晰明了的官方文档,致力于打造一款能够令开发者感到愉悦并且使用起来高效的工具。
早期开发与首次公开发布
据了解,Sanfilippo 最初是使用 Tcl 语言来构建 Redis 的原型的。之后,为了追求更高的执行性能和对系统更精细的控制能力,他选择用 C 语言对其进行了重写。在 LLOOGG 项目内部的应用取得成功之后,Redis 被正式开源。Sanfilippo 当时在著名的技术社区 Hacker News 上分享了 Redis 的测试版本,并因此获得了大量宝贵的早期用户反馈。这些反馈极大地推动了 Redis 的快速迭代和新功能的添加。
值得一提的是,在 VMware 公司最终决定赞助他的全职开发工作之前,Sanfilippo 曾投入了大量的时间,在没有直接经济报酬的情况下,全心全意地进行着 Redis 的开发。这充分体现了他对这个项目的执着追求与巨大投入。
第一节启示与影响
Redis 的诞生故事,揭示了几个非常关键的因素,这些因素不仅塑造了它早期的形态特征,也从某种程度上预示了其未来能够取得巨大成功的轨迹。
首先,问题驱动的创新是 Redis 起源的核心所在。Redis 并非凭空想象的产物,而是为了解决 LLOOGG 当时所面临的那个迫切的、真实存在的系统可伸缩性危机。这种源于实际需求的实用主义出发点,使得 Redis 从一开始就专注于为一些特定的、常见的工作负载提供极致的性能表现。这也直接导致了其在设计上的一些独特选择,例如优先考虑内存的访问速度,以及针对像列表这样的动态数据结构进行高效的处理能力。这与那些试图从一开始就构建一个功能全面的、通用的数据库解决方案的项目的思路,形成了鲜明的对比。Sanfilippo 的目标非常明确,就是要解决 LLOOGG 的具体问题——即如何处理巨大的写入量,并实现快速的实时数据分析,而不是去构建一个试图满足所有需求的通用数据库。
其次,“以简驭繁”的性能策略,鲜明地体现在其单线程核心的设计之上。在多核处理器日益普及的时代背景下,选择单线程的架构似乎有些有悖常理。但这实际上是一个经过深思熟虑的战略决策,其目的是通过大幅减少多线程同步所带来的额外开销,来最大化那些内存密集型操作的执行性能。这一独特的设计选择,再结合上非阻塞的 I/O 模型,使得 Redis 能够为许多常见的操作实现非常高的吞吐量和极低的延迟。这充分证明了,对于某些特定的应用场景来说,原始的多核并行处理能力,并非通往极致速度的唯一途径。传统的那些多线程系统,往往会因为线程上下文切换和各种锁机制而产生不小的性能开销。对于那些因为数据本身就存储在内存中而执行速度已经很快的操作来说,这些额外的开销甚至可能占据了整个执行时间的很大一部分。Redis 的设计,通过在单个线程内部对命令执行进行序列化,巧妙地规避了这一点,它更多地是依靠 RAM 本身的高速度和高效的事件处理机制,来服务于大量并发的客户端连接。
最后,开发者友好性可以说是其能够迅速普及开来的重要催化剂。通过直接向开发者暴露那些他们早已熟悉的基础数据结构,并保证所有操作的原子性,Redis 显著地降低了开发者的认知负担和使用门槛。这种易于理解和易于使用的特性,是其能够迅速获得广泛采用的一个强大驱动力。开发者们可以轻松地将他们应用层面的概念,直接映射到 Redis 所提供的各种数据结构之上,而无需借助复杂的对象关系映射(ORM)工具,或者去学习一套新的查询语言。同时,命令执行的原子性,也极大地简化了客户端应用程序在进行并发管理时的复杂性,使得 Redis 成为了一个富有吸引力且非常高效的开发工具。Sanfilippo 从一开始就明确提出的、要打造一款能够令开发者感到愉悦且易于使用的工具的目标,也直接体现在了这些精心设计的功能和特性之中。
奠定基石与早期成长 (版本 1.x - 2.x)
这一发展阶段,标志着 Redis 从一个最初的、由个人发起的项目,逐步成长为一个功能日益完善的、备受关注的内存数据存储系统。其核心的架构模式在此时得以确立,并且引入了一系列关键的特性。这些特性不仅定义了 Redis 早期的核心能力,也为其后续的辉煌发展奠定了坚实的基础。
深入剖析内存优先、单线程架构
Redis 的架构核心,在于其坚定不移的内存优先的设计哲学,即数据主要被存储在 RAM(随机存取存储器)之中。这是其能够实现令人惊叹的高速性能的基石。然而,这一设计也天然地意味着,Redis 所能存储的数据集的大小,会受到可用 RAM 容量的固有限制。这在进行系统容量规划和成本考量时,是一个需要被优先考虑的关键因素。
其所谓的单线程模型,特指的是其核心命令的执行过程。Redis 利用了一套非常高效的事件循环机制(例如,在 Linux 操作系统上,它通常会使用 epoll;而在像 BSD 或 macOS 这样的操作系统上,则可能会使用 kqueue 等类似的系统调用)来并发地处理来自多个客户端的连接请求。这个事件循环机制,会一次处理一个来自不同客户端的命令,但它只会在某个客户端确实有数据准备就绪时,才会去处理该客户端的请求。通过这种方式,Redis 能够在不为每一个客户端都分配一个独立线程的情况下,高效地管理大量的并发连接。
这种独特的模型带来了许多显著的优势:它极大地简化了 Redis 内部的逻辑实现,因为无需引入那些复杂的多线程锁机制;它天然地保证了单个命令操作的原子性;并且,由于单个 CPU 核心可以持续地处理数据,它通常也能够带来更好的 CPU 缓存利用率。
这种设计主要的权衡之处在于,如果单个命令的执行时间过长,它就可能会阻塞其他所有客户端的请求,因为 Redis 无法利用多个 CPU 核心来并行地加速该命令的执行。然而,对于 Redis 所擅长处理的那些通常耗时极短的内存密集型操作而言,这往往并不会构成真正的性能瓶颈。而且,在后续的版本中,Redis 也引入了一些缓解措施,例如为命令设置超时限制,以及针对某些特定的、可能会比较耗时的操作(比如删除一个非常大的键)引入后台线程来进行处理等。
核心数据结构:构建模块
Redis 从其早期版本开始,就以其在服务器端提供的、内容丰富的内置数据结构而脱颖而出,它远非一个简单的键值对存储系统所能比拟。这些数据结构并不仅仅是一些简单的存储类型,它们各自都附带了一套功能强大且保证原子性执行的命令集,允许开发者能够以非常高效的方式来操作和处理这些数据。
- 字符串 (Strings): 它是二进制安全的,并且用途非常广泛。字符串类型常被用于缓存 HTML 片段、存储一些简单的配置值,以及实现各种计数器功能(例如,通过
INCR命令)。 - 列表 (Lists): 它是一个有序的字符串集合,其底层通常是通过双向链表来实现的。这种实现方式使得在列表的头部或尾部进行插入或删除操作,都具有 O(1) 的恒定时间复杂度(例如,通过
LPUSH,RPOP等命令)。因此,列表类型非常适合被用作消息队列或任务队列。 - 集合 (Sets): 它是一个无序的、不允许包含重复成员的字符串集合。集合类型支持像并集、交集、差集这样的常用集合操作。
- 哈希 (Hashes) (在 2.2 版本中被引入): 它是一种字段-值 (field-value) 的映射结构,非常适合用于高效地表示和存储对象类型的数据。
- 有序集合 (Sorted Sets / ZSETs): 在有序集合中,每一个成员都会关联一个浮点数类型的分数(score),并且集合中的成员会根据这个分数进行排序。这使得有序集合能够高效地支持像范围查询、实现排行榜等复杂功能。
这些内置的数据结构,能够非常直观地映射到我们在日常编程中经常遇到的一些常见范式和用例,这使得开发者们能够轻松地上手并高效地使用 Redis 来解决各种实际问题。
Redis 2.0 (约 2010 年第三季度): 位图、虚拟内存 (早期尝试) 与发布/订阅机制
Redis 2.0 版本的发布,是一个非常重要的里程碑。它不仅引入了多项全新的功能,也对一些现有的机制进行了扩展和改进。
- 位图 (Bitmaps): 这项功能允许开发者将字符串类型的数据视为一个位的序列,并对其进行直接的位操作(例如,通过
SETBIT,GETBIT,BITCOUNT等命令)。这对于以空间效率极高的方式来追踪大量布尔型信息(例如,记录用户的活跃状态、签到情况等)非常有用。虽然其具体的引入版本可能需要进一步的确认,但位图操作通常被认为是 Redis 早期的核心功能之一。 - 虚拟内存 (Virtual Memory / VM): 这是 Redis 在其早期为了尝试克服 RAM 容量限制所做的一次努力。它允许将那些不常用的值(注意,不是键)交换到磁盘上进行存储,而键本身则依然保留在内存之中,以保证能够进行快速的查找。其设计的初衷,是针对那些只有一小部分键会被频繁访问,或者某些值本身非常巨大的数据集。其内部的实现,据称使用了位图来追踪那些被交换到磁盘上的内存页面,并通过专门的 I/O 线程来负责将这些值按需加载回内存。相关的资料明确指出:“Redis 的虚拟内存特性,将首次出现在 Redis 2.0 的稳定发行版之中。” 并且也证实:“虚拟内存机制只能将值交换到磁盘,而与键相关联的对象则始终保留在内存之中。”
- 发布/订阅 (Publish/Subscribe / Pub/Sub):
Redis 2.0 引入了一种消息传递的范式,其中,发布者(Publishers)可以将消息发送到特定的频道(Channels)之上,而订阅者(Subscribers)则可以监听这些它们感兴趣的频道,双方无需彼此直接了解对方的存在。这一机制为实现实时通信、事件通知以及构建解耦的系统架构提供了强大的支持。它支持基于精确频道名称的订阅,也支持基于模式匹配的频道订阅(通过
PSUBSCRIBE命令)。其消息传递的语义是“至多一次”(at-most-once),并且在默认情况下,Pub/Sub 机制中的消息是不会被持久化存储的。相关的解释提到:“发布/订阅是一种消息传递技术,它促进了分布式系统中不同组件之间的有效通信。” 同时也有强调:“Redis 赋予了我们实时的发布/订阅能力,这使其非常适合用于构建像聊天应用这样的系统,因为它几乎没有延迟,并且内置了良好的可伸缩性。”
Redis 2.2 (约 2011 年第一季度): 哈希数据类型的引入
在这个版本中,Redis 正式引入了哈希 (Hash) 数据类型(与之相关的命令包括 HSET, HGET, HGETALL 等)。哈希被设计用来高效地存储那些类似于对象的结构(也就是说,在单个键名之下,可以包含多个字段-值对)。与将对象的每个字段都存储为一个独立的顶级键相比,使用哈希数据类型的这种方式,能够显著地减少键的数量,从而降低了键的开销,并提高了内存的使用效率。相关的资料指出:“Redis 哈希是一种用于表示字符串类型的字段和字符串类型的值之间映射关系的数据类型……它非常适合用来表示各种数据对象。”
Redis 2.4 (约 2011 年第四季度): Sentinel 实现高可用性;虚拟内存被弃用
- Redis Sentinel: 这是一个用于监控 Redis 实例、在发生故障时提供通知,并能够实现自动故障转移的系统。如果一个主节点(master)发生了故障,Sentinel 系统会自动地将它的一个副本(replica,在早期版本中也称为 slave)提升为新的主节点,并且会重新配置其他的副本节点以及连接到 Redis 的客户端,使它们都能够连接到这个新的主节点。Sentinel 本身通常会作为一个由多个 Sentinel 进程组成的分布式系统来运行,这样做可以避免 Sentinel 自身出现单点故障,并且它会使用一种仲裁机制(quorum)来进行决策,以判断主节点是否真的发生了故障。相关的资料明确指出:“Redis Sentinel 是一个分布式的、具有容错能力的系统,其设计目标是确保 Redis 服务器的高可用性。” 并且补充道:“当不使用 Redis Cluster(集群模式)时,Redis Sentinel 为 Redis 提供了高可用性的解决方案。”
- 虚拟内存的弃用 (Virtual Memory Deprecation): 实践证明,之前引入的虚拟内存机制,在实际使用中存在着诸多的弊端和问题。因此,在 Redis 2.4 版本中,虚拟内存功能被正式标记为不推荐使用。项目的重心也重新回到了优化纯内存性能,以及探索其他的可扩展性策略之上。当时的重要提示写道:“Redis VM(虚拟内存)现已弃用。Redis 2.4 将是最后一个包含虚拟内存特性的 Redis 版本(但它同时也会警告用户,不鼓励继续使用虚拟内存)。” 相关的资料也确认:“虚拟内存(已弃用)……在 2.4 版本中被标记为弃用,并在后续的 2.6 版本中被彻底移除。”
Redis 2.6 (约 2012 年第三季度): Lua 脚本扩展服务器端能力;虚拟内存被移除
- Lua 脚本 (Lua Scripting):
这个版本允许用户直接在 Redis 服务器上执行 Lua 脚本(通过
EVAL和EVALSHA这两个命令)。这些脚本可以调用 Redis 提供的大多数命令,并能够实现各种自定义的逻辑。更重要的是,这些脚本的执行过程是原子性的。其主要的优势在于,通过在服务器端执行复杂的逻辑,可以有效地减少网络延迟,为那些需要操作多个键的复杂场景提供原子性的保证,并且能够组合出一些 Redis 原生命令所不具备的新功能。脚本在首次执行后,会根据其内容的 SHA1 摘要进行缓存,以便后续可以通过EVALSHA命令来高效地重复执行,而无需再次传输整个脚本内容。相关的解释说道:“Redis 允许用户在服务器上传输并执行 Lua 脚本……由于脚本是在服务器端执行的,因此从脚本中读取和写入数据的效率非常高。Redis 保证了脚本的原子性执行。” 并且明确指出:“从 Redis 2.6 版本开始,Redis 包含了使用 Lua 编程语言的服务器端脚本功能。” - 虚拟内存的移除 (Virtual Memory Removal): 在这个版本中,之前被标记为弃用的虚拟内存功能,被彻底地从 Redis 的代码中移除了。
Redis 2.8 (约 2013 年末至 2014 年初): 部分重同步 (PSYNC) 与 HyperLogLogs
- 部分重同步 (Partial Resynchronization / PSYNC v1): 这项改进显著地提高了 Redis 主从复制的效率。当一个副本节点因为网络等原因与主节点断开连接,并在之后重新连接上时,它可以尝试通过仅仅重放来自主节点积压缓冲区(backlog)中的那些在断开期间缺失的命令,来进行部分重同步,而不再需要像以前那样进行完整的数据集转储和重新加载。当然,这需要在主节点上维护一个一定大小的积压缓冲区。如果副本节点落后主节点太多,超出了积压缓冲区的范围,那么仍然需要进行一次完全的同步操作。相关的解释提到:“从 2.8 版本开始,Redis 包含了一种部分复制的机制。因此,当一个从节点重新连接到其主节点时……它可以请求主节点在无需转储整个内存实例的情况下进行重新同步。”
- HyperLogLogs (HLL):
这是一种概率性的数据结构,它可以用来以极小的、几乎是固定的内存量(通常大约只需要 12KB),并且在一个相对较小的标准误差范围之内,来估算一个非常大的集合的基数(即集合中唯一元素的数量)。与之相关的命令包括
PFADD(添加元素到 HyperLogLog),PFCOUNT(获取估算的基数), 和PFMERGE(合并多个 HyperLogLog)。它非常适用于那些对绝对精确度要求不高,但对内存效率要求极高的场景,例如统计网站的独立访客数量、不同搜索查询的独立数量等等。相关的资料指出:“自 Redis 2.8.9 版本起,HyperLogLogs 功能已经可用……一个 Redis HyperLogLog 最多只会消耗大约 12KB 的内存,并且能够产生一个标准误差为 0.81% 的近似估算值。”
第二节启示与影响
Redis 1.x 和 2.x 版本的发展历程,清晰地揭示了其核心设计哲学是如何通过不断的实践和迭代,而逐步演化并日趋成熟的。
首先,迭代式的问题解决与特性演进的模式在这一时期表现得淋漓尽致。虚拟内存功能的引入与最终被果断弃用,便是一个非常典型的例子。它充分展示了 Redis 在产品开发上所秉持的务实态度。虚拟内存最初是为了解决 RAM 容量限制这一非常实际的问题而设计的,但当其在实际应用中被证明弊大于利时,项目团队能够果断地调整方向,转而去寻求更优的解决方案(例如,后来在更高版本中推出的集群化方案)。这清楚地表明,Redis 的发展并非一成不变的,而是会根据实际的使用效果和来自社群的宝贵反馈,来进行灵活的调整,并且不惧怕去修正那些在早期阶段所做出的决策。
其次,构建分布式系统基石的意图在这一时期也逐渐显现出来。诸如发布/订阅(Pub/Sub)机制和 Sentinel 高可用性方案等重要特性的加入,表明 Redis 不再仅仅满足于做一个简单的、单点的数据存储系统,而是开始逐渐演变为一个能够促进构建更复杂、更具弹性的分布式应用的关键组件。Pub/Sub 机制提供了原生的消息传递能力,为实现事件驱动的架构和服务之间的解耦提供了有力的支持。而 Sentinel 则直接解决了高可用性这一在生产环境中至关重要的需求,通过自动化的故障转移机制,使得 Redis 更加适用于那些关键任务型的应用场景。这些特性所关注的,并不仅仅是数据存储本身,更是数据和服务在整个分布式环境中的交互方式和可靠性保障。
最后,在核心的简洁性与功能的可扩展性之间寻求一个理想的平衡点,是这一发展时期的另一个重要主题。Lua 脚本功能的引入,是 Redis 向着服务器端可编程性迈出的重要一步。它允许用户通过编写自定义脚本来扩展 Redis 的核心功能,而无需向核心代码中添加大量可能只适用于小众场景的命令。这样做的好处是,既保持了 Redis 主 API 的相对简洁和易用性,又为那些高级用户提供了强大的定制能力。当用户开始广泛地采用 Redis 之后,他们自然会遇到一些需要进行更复杂的原子操作,或者希望能够在数据旁边直接执行一些自定义逻辑的场景。Lua 脚本提供了一种通用的方式来实现这些需求,它不仅能够有效地减少网络往返所带来的延迟,还能够确保一系列操作的原子性执行。这也为后来在更高版本中出现的、更为强大的模块 API 和函数功能埋下了重要的伏笔。
攀登新高峰:集群化、模块化与流处理 (版本 3.x - 5.x)
在这一关键的发展阶段,Redis 显著地走向成熟,并开始着力解决在大规模部署时所面临的各种挑战。它不仅增强了自身的横向可扩展性,还引入了功能强大的新型数据结构,以满足现代应用程序日益增长的复杂需求。
Redis 3.0 (约 2015 年 4 月): Redis Cluster – 原生横向扩展能力
Redis 3.0 版本的发布,标志着一个至关重要的转折点。它正式引入了 Redis Cluster,这是 Redis 的一个原生的分布式实现,它允许数据能够在多个 Redis 节点之间进行自动的分片(sharding)。其主要的设计目标,是实现高性能和良好的线性可伸缩性(理论上,集群可以扩展到多达 1000 个节点,但通常在实际应用中,建议将节点数量控制在百位数级别),同时提供可接受的写操作安全性和系统可用性。
在 Redis Cluster 中,整个键空间被巧妙地划分为了 16384 个哈希槽 (hash slots)。集群中的每一个主节点(master node)都会负责管理这些哈希槽的一个子集。当需要确定某个键应该存储在哪个哈希槽时,Redis Cluster 会计算该键的 CRC16 校验和,然后对 16384 进行取模运算,从而得到其对应的哈希槽编号。这种架构设计的一个显著特点是,它避免了使用中心化的代理节点(proxy)。集群内部采用的是异步复制的机制,并且节点之间会通过一条专门的集群总线 (cluster bus) 进行通信,这条总线主要用于节点之间的发现、故障检测以及配置信息的更新等。
对于连接到 Redis Cluster 的客户端而言,它们通常需要具备一定的集群感知能力。这是因为当客户端尝试访问的某个键恰好位于另一个不同的节点上时,它们可能会收到 MOVED 或 ASK 这样的重定向指令,客户端需要能够正确地处理这些指令,并将请求转发到正确的节点。需要注意的是,在 Redis Cluster 中,多键操作(例如,同时对多个键进行原子性的读写)只有在所有涉及到的键都恰好哈希到同一个哈希槽中的情况下才被支持。为了应对这一限制,并允许用户在某些场景下仍然能够执行涉及多个键的操作,Redis Cluster 引入了哈希标签 (hash tags) 的概念。哈希标签是指键名中用花括号 {...} 包裹起来的那一部分,它可以强制让不同的键(只要它们的花括号部分相同)被分配到同一个哈希槽中。相关的资料概述了 Redis Cluster 的目标和关键的键分布机制:“Redis Cluster 是 Redis 的一个分布式实现……其目标是实现高性能和线性可伸缩性……以及良好的可用性……” 并且也解释了其数据分片方式、集群内部的主从复制模型以及写操作的一致性保障。
Redis 4.0 (约 2017 年 7 月): 模块 API、PSYNC2、LFU 淘汰策略与异步删除
Redis 4.0 版本带来了多项重大的改进,进一步增强了其核心功能和整体性能。
- 模块 API (Modules API): 这是一项主要的、旨在提升 Redis 可扩展性的功能。它允许开发者使用 C 语言(或者其他可以与 C 语言进行绑定的编程语言)来编写 Redis 的扩展模块,从而能够向 Redis 中添加全新的数据类型、自定义的命令以及各种新的功能,并且这些扩展模块的执行性能能够接近于 Redis 的原生实现。这些模块可以被动态地加载到运行中的 Redis 服务器中,这为创建那些需要更深度集成和更高性能的扩展功能,提供了一条超越传统 Lua 脚本的、更为强大的途径。早期的一些模块示例(通常是由 Redis Labs,即后来的 Redis Ltd. 开发的),例如 RediSearch(用于实现全文搜索功能)、RedisJSON(用于原生支持 JSON 数据类型)等,都充分展示了该 API 的强大能力和巨大潜力。相关的资料强调:“Redis 4.0.0 版本中最重要的特性之一,就是备受期待的模块系统……这个模块系统提供了一个 API,允许通过动态加载的模块(这些模块主要用 C 语言编写)来对 Redis 进行扩展。”
- PSYNC2 (改进的复制机制): 这个版本进一步增强了自 Redis 2.8 版本以来引入的部分重同步(PSYNC)机制。PSYNC2 允许那些在故障转移后被提升为新主节点的旧副本节点,能够与其原有的、仍然是副本状态的旧副本节点进行部分同步。并且,它还使得副本节点在经历重启或升级之后,也能够尝试与其主节点进行部分重同步,从而进一步减少了在复制过程中进行全量数据重同步(这通常是一个非常耗时的操作)的需要。相关的资料提到:“PSYNC2,是新的复制引擎。现在,一个被提升为新的主节点的从节点,能够接受其旧的从节点……而无需进行一次完整的重同步操作。”
- LFU (Least Frequently Used) 淘汰策略:
当 Redis 实例的内存使用量达到
maxmemory所设定的阈值时,除了原有的 LRU(Least Recently Used,最近最少使用)淘汰策略之外,这个版本新增了 LFU(Least Frequently Used,最不经常使用)作为键淘汰的一个可选策略。LFU 策略旨在通过淘汰那些在一段时间内访问频率最低的键(而不是仅仅淘汰那些最近最少被访问的键),来在许多缓存应用场景中获得更好的缓存命中率。需要注意的是,Redis 中 LFU 的实现是一种近似算法,而非绝对精确的 LFU。 - 异步删除 (Asynchronous Deletion -
UNLINK,FLUSHALL/FLUSHDB ASYNC): 这个版本引入了非阻塞的键删除机制。UNLINK命令的行为与我们熟知的DEL命令类似,但其主要的区别在于,实际的内存回收操作会在一个后台线程中进行,这样做可以显著减少在删除那些非常大的键(例如包含数百万个元素的列表或集合)时可能造成的服务延迟。同时,FLUSHALL ASYNC和FLUSHDB ASYNC这两个命令,也提供了非阻塞的、异步清空整个数据库或特定数据库的功能。 - 内存内省与主动碎片整理 (Memory Introspection and Active Defragmentation):
新版本中增加了
MEMORY USAGE命令,用于报告指定键所占用的内存大小。同时还提供了MEMORY DOCTOR命令,用于观察和诊断整个 Redis 实例的内存消耗情况。此外,还引入了一项主动内存碎片整理的功能(这项功能在使用 Jemalloc 作为内存分配器时可用),它可以在线地、持续地对抗内存碎片化的问题,从而提高内存的利用效率。
Redis 5.0 (约 2018 年 10 月): Redis Streams – 事件数据处理新范式
Redis 5.0 版本中最引人注目、也是意义最为深远的新特性,无疑是 Redis Streams 的引入(与之相关的命令包括 XADD, XREAD, XREADGROUP 等)。这是一种全新的、功能极其强大的、仅支持追加操作的日志型数据结构,它是专门为了高效地管理和处理高速产生的事件数据而设计的。
在 Redis Stream 中,每一个条目(entry)都有一个唯一的、通常是基于时间的 ID,并且可以包含一个或多个字段-值对(field-value pairs)。Streams 不仅支持对指定范围内的条目进行查询(通过 XRANGE 命令),还支持阻塞式的读取操作(通过 XREAD 命令)。更重要的是,它引入了至关重要的消费者组 (Consumer Groups) 的概念(通过 XGROUP, XREADGROUP, XACK 等命令来实现)。消费者组允许多个不同的客户端协作地从同一个流中消费消息,并且提供了像消息确认(acknowledgment)和待处理条目列表(pending entries list, PEL)等高级机制。这些机制使得 Redis Streams 能够实现比之前基本的 Pub/Sub 模式更为健壮、也更具可扩展性的消息处理能力。其典型的应用场景包括事件溯源(event sourcing)、传感器数据的收集与处理、实时通知系统以及作为高性能的消息队列等。相关的资料明确指出:“Redis Streams 是在 Redis 5.0 版本中引入的一个非常强大的特性,它为实时数据处理和构建事件驱动的架构提供了有力的支持。” 并且也有记录写道:“在2018年10月,Redis 5.0 版本正式发布,它引入了 Redis Stream——这是一种新的数据结构,它允许在单个键名之下,存储带有自动生成的、基于时间的序列号的、包含多个字段和字符串值的条目。”
第三节启示与影响
Redis 从 3.x 版本到 5.x 版本的发展历程,深刻地揭示了其向着更广阔的应用领域进行拓展的雄心壮志和强大能力。
首先,攻克可伸缩性的前沿阵地是这一时期的核心主题。Redis Cluster 的正式推出,直接回应了市场上日益增长的、需要处理超出单个 Redis 实例能力范围的庞大数据集和高并发工作负载的迫切需求。这标志着 Redis 从一个主要被视为单节点解决方案的系统,向着一个真正的分布式系统所迈出的关键性转变。随着 Redis 在业界变得日益普及,越来越多的用户开始触及到垂直扩展(即简单地使用配置更高、内存更大的物理机器)所能带来的性能极限。在这样的背景下,通过数据分片来实现的水平扩展能力,就变得至关重要了。Redis Cluster 为此提供了一个原生的、尽管在配置和管理上可能相对复杂一些的解决方案,它使得 Redis 能够在那些需要更大存储容量和更高吞吐量的应用场景中,与其他分布式数据存储方案展开竞争。
其次,将可扩展性确立为核心信条的理念,鲜明地体现在模块 API 的引入之上。这标志着一个重大的哲学转变,它使得 Redis 不再仅仅是一个封闭的系统,而是开始演变成为一个具有平台化潜力的基础架构。它承认了一个事实,即核心系统不可能(也不应该)去尝试实现所有可以想象到的功能,但它可以为那些需要进行深度、高性能扩展的场景,提供必要的钩子和接口。虽然之前引入的 Lua 脚本功能对于组合现有的 Redis 命令来说非常有用,但模块 API 则更进一步,它允许开发者创建全新的数据类型和底层的操作命令。这为 Redis 开辟了更为广阔的用例前景(例如,通过模块来实现像全文搜索、图数据库功能、甚至是 AI 模型服务等),而又不会因为将这些可能相对小众的功能都内置到核心之中,而让所有的用户都为这种核心的膨胀付出代价。这种机制有效地培育起了一个围绕 Redis 的、专业化的扩展功能生态系统。
最后,通过引入 Streams 来主动适应现代数据处理模式,是 Redis 具有前瞻性眼光的一大体现。Redis Streams 的出现,清晰地认识到了事件驱动架构在现代软件设计中的兴起,以及市场上对于一种比之前基本的 Pub/Sub 模式更为健壮、更具持久性且更易于扩展的消息传递系统的迫切需求。传统的 Pub/Sub 机制,其本质是“即发即弃”的,消息一旦发出,如果没有订阅者立即接收,就可能会丢失。而 Streams 则提供了消息的持久化存储、强大的消费者组管理以及精细的消息确认机制,这使得 Redis 在某些特定的用例中,甚至可以成为像 Kafka 这样的专用消息队列系统的一个可行的替代方案,尤其是在那些既需要低延迟的消息处理,又希望能够与现有的 Redis 数据集进行紧密集成的场景中。这一重要的特性,完美地迎合了像微服务架构、物联网应用以及实时数据分析等新兴的技术趋势。
IV: 迈向企业级:增强的安全性与可编程性 (版本 6.x - 7.x)
在这一关键的发展阶段,Redis 积极地融入了那些对于企业级应用采纳来说至关重要的特性。其重点主要集中在显著增强系统的安全性、提供更为复杂和灵活的可编程性,以及在协议层面进行重要的增强。
Redis 6.0 (约 2020 年 5 月): SSL/TLS 加密、访问控制列表 (ACLs)、RESP3 协议与客户端缓存
Redis 6.0 是一次具有里程碑意义的重大版本升级,它带来了多项针对安全性和性能优化的核心功能。
- SSL/TLS 加密: 这个版本首次为 Redis 提供了原生的、对客户端与服务器之间,以及服务器与服务器之间(例如在主从复制或集群总线通信时)的通信进行加密的支持。对于那些特别注重安全性的部署场景来说,尤其是在一些受到严格监管的行业,或者当 Redis 需要暴露在受信网络之外时,这无疑是一项至关重要的特性。相关的资料详细说明:“从版本 6 开始,Redis 支持将 SSL/TLS 作为一项可选功能……在构建时,它需要 OpenSSL 的开发库”,并且阐述了关于证书、私钥以及客户端认证等方面的配置细节。
- 访问控制列表 (ACLs):
Redis 6.0 引入了一套非常细粒度的权限管理系统,它允许管理员能够精确地定义每一个用户可以对哪些特定的键执行哪些特定的命令。这取代了之前那种相对简单的、全局性的密码保护机制 (
requirepass),从而提供了一个更为灵活、也更为安全的访问控制模型。ACLs 的引入,使得 Redis 能够更好地支持多租户的环境,并有助于团队遵循最小权限的原则,从而在整体上提升了系统的安全性。在 Redis 企业版 6.0 的发行说明中也提到了:“针对数据库访问的 ACL 和 RBAC(基于角色的访问控制)功能得到了改进。” - RESP3 (REdis Serialization Protocol version 3): 这是 Redis 通信协议的一个全新版本,其设计目标是提供更为丰富的语义表达能力。与之前的 RESP2 协议相比,RESP3 允许服务器能够主动地向客户端推送数据,而不仅仅是局限于传统的那种简单的请求-应答模式。这一重要的改变,为实现像客户端缓存失效通知这样的高级功能奠定了坚实的基础。同时,RESP3 协议也更直接地支持在响应中表示一些新的数据类型,例如映射(maps)、集合(sets)和属性(attributes)等。相关的资料指出:“通过使用 Redis 6 版本所支持的新版 Redis 协议 RESP3,客户端可以在同一个连接中既运行数据查询,又能够接收到来自服务器的缓存失效消息。”
- 客户端缓存 (Client-Side Caching): 这是一种旨在提升应用性能的机制。在这种机制下,Redis 服务器会追踪客户端曾经请求过的那些键,并在这些键的值发生变化时,主动向相应的客户端发送失效通知。这使得客户端可以在其本地内存中缓存这些数据,从而有效地减少对 Redis 服务器的请求次数和网络传输所带来的延迟。该功能通常会与 RESP3 协议协同工作,以实现高效的缓存失效通知。它支持两种主要的模式:默认模式(服务器会精确追踪每一个被客户端缓存的键)和广播模式(服务器则会追踪键的前缀,当任何匹配该前缀的键发生变化时,都会发送通知)。相关的资料详细解释了客户端缓存及其不同的工作模式:“当使用客户端缓存时,应用程序会将那些常用查询的应答结果,直接存储在应用程序自身的内存之中。”
Redis 7.0 (约 2022 年 4 月): Redis Functions – 服务器端逻辑的再进化
Redis 7.0 版本的核心亮点,无疑是 Redis Functions 的引入。这可以看作是对之前版本中 Lua 脚本功能的又一次重要演进和升华。
- Redis Functions: 它允许开发者将之前编写的脚本(现在更正式地被称为“函数”)作为一种可管理的库,加载到 Redis 服务器之中。这些函数不仅能够被持久化存储,还能够在主从节点之间进行复制。这有效地解决了之前基于
EVAL命令来执行脚本的方式所存在的一些局限性,例如客户端需要自行管理脚本的内容和其对应的 SHA1 摘要、脚本的调试相对困难,以及在多个客户端或应用之间共享和复用脚本逻辑不方便等问题。通过将函数提升为数据库中的“一等公民”,Redis Functions 支持了更好的开发工作流,并使得对服务器端逻辑模式的强制执行变得更加容易。与之前的 Lua 脚本一样,这些函数的执行过程仍然是原子性的。相关的资料明确指出:“Redis Functions 是一个用于管理那些将在服务器上执行的代码的 API。此功能自 Redis 7 版本起可用,它取代了在先前版本中主要通过EVAL命令来使用脚本的方式。” 并且补充道:“Redis Functions 在 7.0 版本中,作为对通过EVAL命令执行 Lua 脚本方式的一种进化和后继者而被引入。函数使得脚本逻辑可以被存储在 Memorystore(即 Redis 实例)之中,而无需应用程序的开发者在每次执行EVAL命令时都重新发送脚本的逻辑代码。”
第四节启示与影响
Redis 6.x 和 7.x 版本的发展,清晰地展现了其向着满足企业级应用需求而进行的成熟演进,以及对持续提升开发者生产力的高度关注。
首先,向企业级应用的成熟化是这一时期的显著特征。诸如 SSL/TLS 加密和访问控制列表 (ACLs) 这样的重量级功能的加入,并不仅仅是简单的增量改进,更是 Redis 要想在那些具有严格安全和合规性要求的企业环境中被认真对待所必需的关键补充。早期的 Redis 版本,更多地是侧重于极致的性能表现和开发者的易用性。随着其在业界变得日益普及,许多大型组织也开始希望能够采用它,但往往因为其在安全特性方面的缺失而面临一些障碍。原生的 TLS 加密支持和细粒度的访问控制(ACLs)机制,直接解决了这些长期存在的担忧,从而极大地拓宽了 Redis 的适用范围和应用场景。
其次,可编程性的精炼化以适应日益复杂的应用需求,鲜明地体现在 Redis Functions 的推出之上。它代表了对服务器端脚本能力的一次重大改进和提升,有效地解决了之前基于 EVAL/EVALSHA 的脚本模型在操作和开发层面所存在的一些痛点。通过引入 Redis Functions,使得服务器端逻辑的管理变得更易于维护、更具持久性,并且与数据库本身的集成度也更高。虽然 Lua 脚本本身功能已经非常强大,但如果将脚本的管理(例如发送脚本代码或其 SHA 摘要)视为客户端的关注点,那么对于那些逻辑比较复杂的应用来说,这种方式可能会显得有些繁琐。而通过让 Redis 服务器自身来负责存储和复制这些函数,其行为就更像是传统关系型数据库中的存储过程了,从而能够有效地简化服务器端逻辑的部署和后续的维护工作。
最后,对客户端与服务器之间交互的深度优化,通过像 RESP3 协议和客户端缓存这样的新特性得以实现。这清楚地表明,Redis 的关注点已经不仅仅局限于服务器端的处理效率,而是开始着眼于优化整个数据访问的完整路径。这也体现了 Redis 团队对一个重要事实的深刻认知,即网络延迟和数据传输本身,通常也是影响整体应用性能的重要因素。客户端缓存机制允许应用程序能够避免对那些频繁访问的数据进行不必要的网络往返请求,从而能够大幅度地降低访问延迟。而 RESP3 协议所提供的、能够主动向客户端推送缓存失效消息的能力,则使得这种客户端缓存模式变得更加健壮和高效。所有这些,都展示了一种超越 Redis 服务器本身、着眼于整体系统性能优化的宏观视角。
V: 现代纪元:治理、许可风波与未来展望 (版本 8.x 及以后)
这一时期见证了 Redis 治理结构的重大转变、一次引发了广泛争议的许可证变更、来自开发者社群的强烈反应(包括 Valkey 这个重要分支的出现)、Redis 随后为了应对局面而转向三许可证模式的调整,以及在近期版本中所取得的一系列技术进步。
Redis Ltd. (前身为 Redis Labs) 在开发与赞助中的角色
Salvatore Sanfilippo 在其早期进行 Redis 开发工作的过程中,最初曾得到 VMware 公司的赞助,随后又得到了 Pivotal 公司的支持。之后,Redis Labs(该公司于2021年正式更名为 Redis Ltd.)成为了开源 Redis 项目最主要的商业赞助者和实际的管理者。
Redis Ltd. 在为开源的 Redis 核心贡献代码的同时,也开发并提供了一个功能更为增强的商业版本——Redis Enterprise。此外,许多在早期对 Redis 生态系统产生了重要影响的模块,例如 RediSearch、RedisJSON 等,也都是由 Redis Ltd. (或其前身 Redis Labs) 开发的。相关的资料记载:“从2015年到2020年,他(指 Sanfilippo)领导了一个由 Redis Ltd. 赞助的、负责 Redis 项目核心开发的团队。” 并且也明确指出:“Redis Labs 是 Redis 的‘开源之家’和官方赞助商……它同时也是 Redis Enterprise 这个商业产品的提供者。”
许可证的转变:从 BSD 到 RSALv2/SSPLv1 及社群的回应 (2024 年 3 月)
在历史上,Redis 的核心代码一直采用的是 BSD 3-Clause 许可证,这是一种非常宽松的、被广泛接受的开源许可证。然而,在2024年3月,Redis Ltd. 突然宣布,从 Redis 7.4 版本开始,核心的 Redis 项目将转向一种双重许可证的模式:即 Redis Source Available License v2 (RSALv2) 和 Server Side Public License v1 (SSPLv1)。
Redis Ltd. 对此给出的主要理由是,此举旨在阻止那些大型的云服务提供商,通过将 Redis 作为一种托管服务来直接盈利,而不对其核心技术的发展做出相应的贡献,从而希望能够确保 Redis 项目自身的长期可持续发展。
然而,开发者社群对此的反应普遍是负面的。许多人,包括著名的开源促进会 (OSI) 本身,都认为 SSPLv1 并非一个 OSI 批准的、真正意义上的开源许可证。人们普遍担忧这种许可证模式,会对 Redis 的商业使用带来诸多限制,特别是对于那些将 Redis 作为一种服务来提供给其他用户的公司而言。这一举动被一些人视为是对真正开源精神的一种背离。相关的总结写道:“在2024年3月,Redis Labs(即现在的 Redis Ltd.)做出了一个非常有争议的决定,将其原本的 BSD 许可证转换为使用 RSALv2……和 SSPLv1 的双重许可证模式……其宣称的目的是为了阻止那些主要的云服务提供商……在不进行回馈的情况下,就将 Redis 作为一种托管服务来提供。”“社群的反应是迅速且负面的。”
Valkey 分支:一个开源的替代选择 (2024 年 3月/4月)
作为对 Redis 许可证变更的直接回应,一群曾经的 Redis 核心维护者和一些主要的科技公司(包括 AWS、Google Cloud、Oracle、Ericsson 等行业巨头)共同发起了一个名为 Valkey 的新项目。Valkey 项目是基于 Redis 7.2.4 版本的一个分支创建的,并且它选择继续采用原先的 BSD 3-Clause 许可证。
Valkey 项目迅速地成为了 Linux 基金会旗下的一个正式项目,其明确的目标是维护一个真正开源的、由社群驱动的 Redis 替代方案。其核心的理由,是希望能够确保 Redis(或者说,一个与 Redis 高度兼容的系统)能够在一种宽松的开源许可证之下持续可用,并以一种开放的、协作的方式来继续其未来的发展。许多主流的 Linux 发行版,也相继宣布了计划在其官方的软件仓库中,用 Valkey 来替换掉原先的 Redis。
Valkey 项目一经推出,就迅速获得了来自开发者社群的广泛关注和大力支持,并伴随着重要的代码贡献和快速的版本发布(例如 Valkey 8.0, 8.1 等)。它专注于在性能、可靠性和可扩展性等方面进行持续的改进,并且也包含了许多由社群开发的、非常实用的模块,例如搜索功能、JSON 支持以及布隆过滤器等。相关的描述详细记载了 Valkey 的诞生过程:“作为对 Redis OSS 7.2 版本许可证变更的回应,Valkey 这个分支被创建了出来。它代表了维护一个真正开源的基础设施选项,以服务于全球开发者的坚定承诺……这个分支最初是由来自 AWS、Ericsson、Oracle 和 Google 的一群专注的贡献者共同发起的。”
Redis 回归开源之根:采用 AGPLv3 的三许可证模式 (2025 年 5 月,针对 Redis 8.0)
面对来自开发者社群的强烈反应,以及 Valkey 项目的迅速崛起所带来的竞争压力,Redis Ltd. 在2025年5月宣布了一项重大的策略调整:从 Redis 8.0 版本开始,Redis 的开源版本将采用一种包含 RSALv2、SSPLv1 以及 OSI 批准的 GNU Affero General Public License v3 (AGPLv3) 在内的三许可证模式。
此举被广泛视为 Redis Ltd. 试图回应社群的关切,并重新与开源的核心原则进行对齐的一种努力。同时,AGPLv3 这种具有强 कॉपी左 (copyleft) 特性的许可证,仍然为那些希望在不贡献其服务本身源代码的情况下,就将 Redis 作为一种即服务(as-a-service)产品来提供的云服务提供商,设置了一定的障碍。值得注意的是,Redis 的创始人 Salvatore Sanfilippo 于2024年末以布道师和顾问的身份重新回归 Redis Ltd.,这可能在公司做出这一重要的许可证决策过程中,发挥了积极的影响。相关的资料指出:“Redis 已经通过发布 Redis 8 版本,回归到了真正的开源许可模式。该版本在现有的 RSALv2 和 SSPLv1 许可证之外,还额外提供了 AGPLv3……这个许可证选项。” 并且也提到:“Salvatore Sanfilippo 的影响:Redis 的创造者‘antirez’于2024年11月重新加入了公司,并积极倡导采用 AGPLv3 许可证。”
Redis 8.0 (2025 年 5 月): 集成模块、I/O 线程增强与向量集
Redis 8.0 版本的发布,带来了多项非常重要的更新和功能增强:
- 名称变更:“Redis Community Edition” 这个名称被正式更改为了 “Redis Open Source”。
- 功能集成 (前身为独立模块): 许多先前作为独立模块提供的、非常关键的功能(例如 RediSearch, RedisJSON, RedisTimeSeries, RedisBloom, 以及像 Cuckoo filter, Count-min sketch, Top-K, t-digest 这样的概率性数据结构),现在都已经被直接集成为了 Redis 8.0 的核心组成部分。这极大地增强了核心产品的开箱即用能力。
- 向量集 (Vector Sets) [测试版]: 这是一种受到有序集合(Sorted Sets)启发而设计的新型数据结构,它是专门为了进行向量相似性搜索而优化的。这对于当前日益重要的人工智能和机器学习应用场景(例如语义搜索、推荐系统等)来说,具有至关重要的意义。据了解,这项功能的开发也得到了 Redis 创始人 Salvatore Sanfilippo 的直接参与。
- I/O 线程改进: 新版本进一步增强了 Redis 在 I/O 操作方面对多核处理器的利用率,其主要目标是提高整体的吞吐量。需要注意的是,这与 Redis 核心命令执行仍然是单线程的机制并不冲突,这里的多线程主要用于优化网络数据的处理。
- 据称,该版本还包含了超过30项针对性能和资源利用率的改进,以及更为健壮的复制机制。
- 此外,还增加了一些新的哈希命令,例如
HGETDEL,HGETEX,HSETEX等。 相关的发行说明中写道:“Redis Open Source 8.0.0 (发布于2025年5月)……Redis 的查询引擎和8种新的数据结构,现在已经成为了 Redis 8 的组成部分……向量集 [预览版]……以及新的 I/O 线程实现……”
Salvatore Sanfilippo 的回归及其对 Redis 的愿景
Salvatore Sanfilippo 于2024年11月,以开发者布道师和技术顾问的身份,重新加入了 Redis Ltd. 公司。他的这次回归,被社群中的许多人视为一个非常积极的信号,并且很可能对公司最终决定转向采用 AGPLv3 许可证的决策,产生了积极的影响。他曾公开表达了希望看到 Redis 能够不断发展和进化,特别是在像向量能力这样的新兴领域(例如新引入的向量集功能),并希望能够帮助重塑公司与开发者社群之间的关系的愿望。在他后续发表的博客文章和接受的访谈中,他也深入反思了当前开源软件所面临的各种挑战、与云服务提供商之间的动态关系,以及他本人对 Redis 技术持续演进的热情。在他的一篇博文中,Sanfilippo 写道:“所以我开始思考,也许,终究我还是可以在 Redis 的生态系统中扮演一个有意义的角色。也许我能够帮助重塑公司对待社群的态度。”
第五节启示与影响
Redis 近期的发展历程,特别是围绕着其许可证所发生的一系列变动,为我们理解整个开源软件的生态系统及其未来的发展趋势,提供了非常深刻的视角。
首先,开源项目的可持续性困境是这一系列事件的核心议题。从最初的 BSD 许可证,到后来转向 RSAL/SSPL,再到最终选择采用 AGPLv3 的三许可证模式,以及期间 Valkey 分支的出现,都生动地展示了纯粹的开源理想与维持一个大规模开源项目长期、健康发展的财务现实之间的潜在冲突。这种情况尤其在面临那些大型云服务提供商可能进行的“掠夺式”使用时,显得尤为突出。Redis Ltd. 最初决定转向 RSAL/SSPL 许可证,其主要目的就是为了迫使那些从 Redis 中获益的云服务提供商,能够以某种形式回馈到项目的核心发展之中。然而,来自开发者社群的强烈反对,以及 Valkey 这个重要分支的迅速产生,都清楚地表明了用户对于宽松的、真正的开源许可证的强烈偏好。最终,Redis Ltd. 选择在其许可证选项中加入 AGPLv3,可以看作是一种试图在多方利益之间寻求平衡的折衷方案——它既在一定程度上满足了开源社区对“开放”的定义,同时又通过 AGPLv3 本身的特性,对那些希望提供 Redis 即服务(as-a-service)的云服务提供商施加了一定的义务。这也反映了在更广泛的行业范围内,其他一些知名的开源项目(例如 MongoDB、Elasticsearch 等)也曾面临过类似的挑战,并采取过类似的许可证策略调整。
其次,开发者社群与项目分支的力量不容忽视。Valkey 项目的迅速形成,并很快获得了来自业界主要参与者的大力支持,清楚地表明了:一个强大且积极的开发者社群,尤其是在得到一些具有影响力的支持者(例如大型科技公司)的背书的情况下,当一个项目的管理者被认为其行为偏离了社群的核心利益时,是完全有能力创建出可行的、具有竞争力的替代方案的。这对原始项目的所有者来说,无疑起到了一种强有力的制衡作用。Redis Ltd. 当初的许可证变更,被社群中的很大一部分人视为一种信任的破坏。因此,许多关键的开发者和主要的用户(尤其是那些云服务提供商)迅速地围绕着 Valkey 项目凝聚起来,以确保能够在原始的 BSD 许可证之下,保持项目的连续性和开放性。Linux 基金会对 Valkey 项目的支持,则为其提供了合法性的背书和稳健的治理结构。这充分说明了,“开源”并不仅仅是关乎许可证本身的条款,更关乎社群的控制权、信任的建立以及共同的价值观。
再次,Redis 8.0 版本所进行的战略性功能整合,其意义也十分重大。将像 JSON 支持、全文搜索以及时间序列数据处理这样广受欢迎的、原先作为独立模块提供的功能,直接集成到 Redis 8.0 的核心之中,可以被看作是 Redis Ltd. 为了加强其核心 Redis 产品竞争力的一项重要战略举措。这样做使得 Redis 开箱即用的功能更加丰富,这可能也是为了更有效地与包括 Valkey 在内的各种替代品(Valkey 同样也在积极地整合各种有用的模块)进行竞争,并在其新的许可模式之下,为用户提供更多的附加价值。通过将这些强大的功能直接捆绑到核心产品中,Redis Ltd. 使得其开源的 Redis 产品本身对用户更具吸引力。这也简化了那些以前必须自己去单独寻找、安装和管理这些独立模块的用户的部署和使用过程。同时,这也符合当前数据库技术发展的一个大趋势,即数据库本身变得越来越“多模型化”,并倾向于提供更为丰富和原生的功能支持。而新引入的向量集(Vector Sets)功能,则更是直接瞄准了当前异常蓬勃发展的人工智能和机器学习市场,显示了 Redis 积极拥抱新技术浪潮的决心。
最后,原始创作者的持久影响力在整个事件中也显而易见。Salvatore Sanfilippo 的回归,以及他公开发表的关于开源、社区和 Redis 未来发展的看法,似乎对 Redis Ltd. 公司的决策方向产生了切实可见的影响,特别是在最终决定采用 AGPLv3 许可证,以及更加关注像向量集这样的创新功能方面。这突显了即使在离开项目一段时间之后,一个受人尊敬的创始人,仍然可以凭借其深厚的技术积累和在社区中的崇高声望,行使其重要的道德和技术权威。Sanfilippo 在 Redis 开发者社群中广受尊敬,他的重新参与,以及他对回归 OSI 批准的开源许可证的积极倡导,无论是在 Redis Ltd. 公司内部,还是在广大的开发者社群之中,都具有相当大的分量。他在技术上的持续贡献,例如参与设计和实现新的向量集功能,也充分展示了他持续推动项目创新和发展的强大能力。
表1: Redis 许可演进
| 时期/版本 | 许可证 | 主要影响/社群反应 |
|---|---|---|
| 初始 (至 7.2.x 版本) | BSD 3-Clause | 非常宽松,极大地促进了 Redis 的广泛采用和社群的早期发展。 |
| Redis 7.4 (2024年3月) | 双重许可: RSALv2 / SSPLv1 | 虽然源码仍然可用,但这两个许可证均未获得 OSI 的批准,其主要目的是为了限制云服务提供商的“免费”使用。这一变更引发了社群强烈的负面反应,并直接导致了 Valkey 分支的出现。 |
| Redis 8.0 (2025年5月) | 三重许可: RSALv2 / SSPLv1 / AGPLv3 | AGPLv3 是一个 OSI 批准的开源许可证,此举被视为 Redis Ltd. 向社群和解并回归开源根基的姿态,但同时也通过 AGPLv3 的特性,对服务提供商保留了一定的限制。 |
VI: Redis 持久不衰的架构支柱
本节将重新审视并详细阐述在 Redis 整个演进过程中,那些始终定义着其核心特性、并对其巨大成功产生着持久影响的关键架构元素。
数据持久化策略:RDB vs. AOF – 优缺点与适用场景
Redis 提供了两种主要的数据持久化机制,以确保在服务器发生重启或意外故障后,内存中的数据不会完全丢失。同时也允许用户根据他们自身对数据安全性和系统性能的不同需求,在这两种机制之间进行灵活的权衡和选择。
-
RDB (Redis Database Backup): RDB 是一种时间点快照(point-in-time snapshot)的持久化机制。它会在用户预先设定的时间间隔内,自动地(或者由用户手动触发)生成整个数据集在某个特定时刻的快照。RDB 文件是以一种经过压缩的二进制格式进行存储的,因此它通常非常紧凑,非常适合用于进行数据备份和灾难恢复。并且,由于其格式的特性,当 Redis 服务器重启时,从 RDB 文件中加载数据的速度通常会相对比较快。其后台保存的操作,通常是通过
fork系统调用创建一个子进程来完成的,这个子进程会负责将当前内存中的数据写入到磁盘上的 RDB 文件中,这样做可以最大限度地减少持久化操作对父进程(即 Redis 主进程)性能的影响。 -
AOF (Append-Only File): AOF 持久化机制则会记录下服务器所接收到的每一个写操作命令(例如
SET,INCR,LPUSH等)。这些命令会以 Redis 协议本身的格式,被追加到 AOF 文件的末尾。当 Redis 服务器重启时,它可以通过重新执行 AOF 文件中所记录的所有写命令,来逐步地重建出原始的数据集。AOF 提供了不同的fsync(同步到磁盘)策略(例如everysec表示每秒同步一次,always表示每个写命令都立即同步,no表示完全依赖操作系统的同步机制),这允许用户在数据丢失的风险和写入操作的性能之间,根据自己的需求进行选择。AOF 日志文件是仅追加(append-only)的,因此它通常不会遇到像传统数据库日志那样的磁盘寻道问题,并且在发生像断电这样的意外情况时,通常具有较好的数据健壮性。此外,Redis 还能够在 AOF 文件变得过大时,自动地在后台对其进行重写(rewrite),以减小其体积并优化其结构。 -
比较与选择:RDB 的主要优点在于其生成的快照文件非常紧凑,并且在进行数据恢复时速度相对较快。但其主要的缺点是,如果在两次快照操作之间发生了服务器故障,那么在这期间所写入的数据就有可能会丢失。相比之下,AOF 则能够提供更高的数据安全性(尤其是在将
fsync策略设置为always或everysec时),但其生成的日志文件通常会比 RDB 文件要大,并且在进行数据恢复时,由于需要重放所有的写命令,其速度可能会相对较慢。通常的建议是,如果用户需要达到类似于 PostgreSQL 这样的关系型数据库的数据安全级别,那么可以考虑同时启用 RDB 和 AOF 这两种持久化机制。如果应用场景可以容忍几分钟的数据丢失,那么单独使用 RDB 进行定期的备份,也是一个不错的选择。许多用户选择单独使用 AOF 来保证数据的持久性,但即使在这种情况下,定期地创建 RDB 快照仍然被认为是一种进行数据库备份、加速服务器重启过程,以及应对 AOF 引擎潜在错误的良好实践。当然,对于那些纯粹用作缓存的场景,用户也可以选择完全禁用所有的持久化机制,以追求极致的性能。表2: Redis 持久化选项对比 (RDB vs. AOF)
特性 RDB (Redis Database Backup) AOF (Append-Only File) 机制 时间点快照 记录服务器接收到的每一个写操作命令 持久性 时间点保存,两次快照操作之间的数据可能会丢失 仅追加写入,可以通过 fsync策略进行配置(例如每秒同步一次、每个查询都同步)以提高持久性保证的级别性能影响 通常通过 fork子进程在后台进行保存,对主进程的性能影响较小取决于所选择的 fsync策略,always策略对性能影响最大,everysec通常是一个良好的折衷方案文件大小 生成的是紧凑的二进制文件 通常情况下会比 RDB 文件要大,其内容是文本格式的(在进行重写操作后,文件体积可能会显著减小) 恢复速度 通常情况下会比 AOF 要快,因为它是直接加载整个快照文件进行恢复 需要重放所有的写操作命令,因此在数据量较大时,恢复速度可能会比较慢 优点 非常适合用于进行数据备份,数据恢复速度快,对 Redis 自身的性能影响也比较小 数据安全性更高(丢失数据的风险相对较小),AOF 日志文件易于人类理解和进行解析,并且在日志文件损坏时,通常也更容易进行修复 缺点 在两次快照操作之间,如果发生故障,数据丢失的风险较高 文件体积通常较大,数据恢复速度可能会比较慢,并且根据所选择的 fsync策略,可能会对写入性能产生一定的影响
Redis 数据结构的强大功能与多功能性
Redis 的核心竞争力之一,就在于其在服务器端提供的、内容极其丰富的内置数据结构。这些并不仅仅是一些简单的存储类型,它们各自都拥有一套原子性的操作命令,允许开发者能够以非常高效和复杂的方式来处理和操作这些数据。
- 核心数据结构回顾: 像字符串 (Strings)、列表 (Lists)、哈希 (Hashes)、集合 (Sets) 和有序集合 (Sorted Sets) 这样的基础数据结构,构成了 Redis 功能的基石。它们被广泛地应用于各种不同的场景,例如实现数据缓存、构建消息队列、表示和存储对象、管理各种关系数据(例如社交网络中的关注关系),以及实现排行榜功能等等。
- 高级数据结构扩展: 随着 Redis 版本的不断迭代和发展,它也引入了越来越多高级的、针对特定场景优化的数据结构。例如,用于高效处理事件数据的流 (Streams),用于进行大规模基数估算的 HyperLogLogs,用于支持基于位置服务的地理空间索引 (Geospatial indexes),用于进行精细位操作的位域 (Bitfields),以及在最新的 Redis 8 版本中被直接集成进核心的 JSON 数据类型、时间序列数据 (TimeSeries) 和向量集 (Vector Sets) 等等。这些都极大地拓宽了 Redis 的应用边界和可能性。
相关的资料强调:“Redis 所提供的那些复杂的数据结构,为现代应用程序中许多常见的用例,都提供了非常灵活的数据建模方式。” 同时,最新的发布信息也突出了像 JSON、时间序列数据、各种概率性数据结构以及向量集这样的高级功能,已经被成功地集成到了 Redis 8 的核心之中。
Redis 中的事务与原子性
原子性是 Redis 设计理念中一个非常基本且重要的原则。
- 单个命令的原子性: 在 Redis 中,每一个单独执行的命令,其本身都是原子性的。这意味着,一个命令要么就完全被成功执行,要么就根本不执行,绝对不会出现只执行了一部分的状态。
MULTI/EXEC事务: Redis 通过MULTI和EXEC这两个命令,为用户提供了事务支持。客户端可以将多个需要按顺序执行的命令,先通过MULTI命令放入一个队列之中,然后再通过EXEC命令,将队列中的所有命令一次性地、按顺序地、并且是原子性地发送给服务器去执行。- 事务的原子性特性: 这里需要明确的是,Redis 事务的原子性,指的是被放入队列中的所有命令,会作为一个整体被发送到服务器,并在服务器端按顺序执行。在这些命令执行期间,它们不会被来自其他客户端的命令所打断。如果在命令入队的过程中发生了错误(例如,某个命令的语法不正确),那么整个事务将会被服务器丢弃,不会执行任何命令。然而,需要注意的是,如果某个命令在
EXEC执行期间发生了运行时错误(例如,试图对一个错误类型的键执行了某个不兼容的操作),那么其他的命令仍然会继续执行;Redis 并不会因为某个命令的运行时错误而进行回滚操作。这是一种“部分要么全做,要么就都不做”(指入队阶段的错误)与“出错命令之前的命令已执行,出错命令之后的命令继续执行”(指运行时错误)相结合的机制。 WATCH/UNWATCH/DISCARD实现乐观锁: Redis 还提供了WATCH命令,它允许客户端监视一个或多个键。如果在客户端执行EXEC命令之前,任何一个被WATCH命令所监视的键,被其他的客户端修改了,那么整个事务将会执行失败。这为实现乐观锁(optimistic locking)提供了一种有效的机制。UNWATCH命令则用于取消对所有键的监视,而DISCARD命令则用于放弃当前正在构建的事务队列,清空所有已入队的命令。
相关的资料详细解释了 Redis 事务的这些特性:“Redis 事务允许你将多个命令排入队列,然后在通过 EXEC 命令提交时,按顺序地执行它们……其执行是原子性的:事务中的所有命令会作为一个数据块被发送到 Redis。(在入队阶段)它是部分‘要么全做,要么全不做’的:如果某个命令在排队时就失败了(例如语法错误)……那么整个事务都将被丢弃。但是,如果某个命令在运行时发生了错误……Redis 仍然会继续执行队列中其他的命令。”
Redis 配置示例
在实际部署 Redis 时,合理的配置对于性能和安全性至关重要。以下是一个典型的 redis.conf 配置片段,供参考:
# 监听端口
port 6379
# 绑定本地回环地址,提升安全性
bind 127.0.0.1
# 设置访问密码
requirepass yourStrongPassword
# 启用持久化(RDB 快照)
save 900 1
save 300 10
save 60 10000
dir /var/lib/redis
# 限制最大内存用量,超出后采用 LRU 淘汰策略
maxmemory 256mb
maxmemory-policy allkeys-lru
# 开启 AOF 持久化
appendonly yes
appendfsync everysec
# 开启保护模式,防止误操作
protected-mode yes
⚡️ 说明:实际生产环境请根据业务需求调整端口、内存、持久化策略和安全相关配置。
Redis 的影响及其周边生态系统
Redis 的影响力远远不止于其核心功能本身,它已经深刻地改变了现代应用架构的设计模式,并围绕其催生出了一个充满活力、不断壮大的开发者社群和丰富的工具生态系统。
重塑应用架构:超越缓存的边界
尽管缓存是 Redis 最广为人知、也是其首要的应用场景,但其深远的影响力早已远远超出了这一范畴,并已渗透到现代应用架构的多个不同层面:
- 会话管理 (Session Management): 由于其极高的读写速度和处理大量并发请求的出色能力,Redis 成为了在 Web 应用中存储用户会话数据的理想选择,其性能表现通常远优于传统的、基于磁盘的关系型数据库。将会话信息存储在 Redis 这样的内存数据库中,使得 Web 服务器集群可以轻松地进行水平扩展,而无需再依赖于像“粘性会话 (sticky sessions)”这样的复杂机制,因为集群中的任何一台服务器都可以快速地访问到存储在 Redis 中的共享会话数据。
- 实时分析 (Real-time Analytics): 利用 Redis 强大的有序集合 (Sorted Sets) 来实现各种排行榜功能、通过原子性的自增操作来实现高效的计数器,以及通过其先进的流 (Streams) 数据结构来处理高速产生的事件数据,使得 Redis 在实时数据分析领域大放异彩,并被广泛应用于需要即时洞察和快速响应的场景。
- 消息代理/队列 (Message Brokering/Queues): 通过其内置的列表 (Lists) 数据结构(可以作为简单的消息队列使用)、发布/订阅 (Pub/Sub) 机制,特别是后来引入的功能更为强大的流 (Streams) 数据结构,Redis 被广泛地用作服务之间的通信总线和异步任务处理队列。
- 速率限制 (Rate Limiting): 利用 Redis 所提供的原子性的自增操作(例如
INCR命令),可以非常方便且高效地实现各种速率限制器。这对于保护 API 接口、防止恶意请求和滥用行为来说,至关重要。 - 地理空间索引 (Geospatial Indexing): Redis 提供了专门的地理空间相关命令,允许开发者存储和查询基于地理位置的数据。这使得它非常适用于实现像查找附近商家、追踪用户或共享资产的实时位置等各种与位置相关的应用功能。
- 机器学习 (Machine Learning): 随着人工智能和机器学习技术的飞速发展,Redis 在其相关的流程中也扮演着越来越重要的角色。例如,它可以被用作高效的特征存储(feature store)、支持模型的实时推理(real-time model inference),以及通过其最新增加的向量集 (Vector Sets) 功能来实现高效的向量相似性搜索等。
Redis 通过提供一个快速的、可共享的状态存储,以及高效的、灵活的通信渠道,极大地促进了像微服务这样的现代应用架构模式的普及和发展。相关的资料总结道:“Redis 的发布/订阅功能,允许开发者轻松地实现消息队列……而 Redis Streams……则提供了一个具有持久性且功能更为丰富的消息队列系统。” 同时,这些资料也广泛地涵盖了 Redis 在实时分析、会话管理等多种不同用途中的成功应用。
充满活力的社群:成长、客户端库与工具 (例如 RedisInsight)
Redis 之所以能够取得如此巨大的成功,离不开其背后那个庞大、活跃且富有创造力的开发者社群。
- 社群的成长: 从项目早期,其创始人 Salvatore Sanfilippo 就非常积极地培育和建设社群开始,Redis 社群通过各种不同的形式,例如官方和非官方的论坛、各种规模的技术会议(例如著名的 RedisConf)、以及海量的在线学习资源等等,不断地发展和壮大。相关的资料提到:“Redis 得到了一个非常强大的开源社群的支持……例如,Redis 在 Reddit 上的子版块就拥有超过 8000 名成员,而其在 GitHub 上的官方仓库则拥有超过 67000 个星标。”
- 丰富的客户端库: 针对几乎所有主流的编程语言,都存在着大量由官方或社区贡献的高质量客户端库。这些库极大地简化了将 Redis 集成到各种不同类型的应用程序中的过程。例如,在 Java 语言中,Jedis 和 Lettuce 是广受欢迎的选择;在 Python 语言中,redis-py 则是事实上的标准库;而在 .NET 平台下,StackExchange.Redis 也备受推崇。
- 管理与监控工具:
- RedisInsight: 这是由 Redis Ltd. (即之前的 Redis Labs) 开发的一款功能强大的图形用户界面 (GUI) 工具。它为开发者和运维人员提供了包括浏览和操作数据、监控 Redis 实例的性能指标、分析执行过的命令、提供方便的命令行访问界面在内的多种实用功能。并且,它还集成了基于 AI 驱动的 Copilot 助手,以及用于进行数据迁移和集成的 RDI(Redis Data Integration)连接功能。相关的描述称 RedisInsight 是“一个用于可视化和优化 Redis 中数据的强大工具……而 Redis Copilot 则是一个由 AI 驱动的开发者助手……”
扩展核心功能:第三方及 Redis Ltd. 模块的角色
Redis 4.0 版本引入的模块 API,为 Redis 的功能扩展打开了一扇全新的大门,使其能够超越其内置数据结构和命令集的限制,从而应对更为广泛和复杂的应用场景。
- Redis Ltd. 开发的模块 (其中许多现已集成入 Redis 8 的核心,或者作为 Redis Stack 的一部分提供): 例如像 RediSearch (用于实现全文搜索功能)、RedisJSON (用于原生支持 JSON 数据类型)、RedisTimeSeries (用于处理时间序列数据)、RedisGraph (用于实现图数据库功能)、RedisBloom (提供了一系列概率性数据结构,如布隆过滤器、布谷鸟过滤器等) 和 RedisAI (用于在 Redis 中直接运行 AI 模型进行推理) 等模块,都极大地扩展了 Redis 的应用场景,使其有效地转变为了一个功能丰富的多模型数据库。
- 有影响力的社群驱动/第三方开源模块: 除了 Redis Ltd. 官方开发的那些模块之外,广大的开发者社群也贡献了许多非常有价值的、具有创新性的模块(这里主要指那些在 Redis 8 核心功能集成或 Redis Stack 产品捆绑之外,具有一定的历史影响力或者真正保持独立发展的模块)。例如,一些资料中列举的像
redis-cell(用于实现基于令牌桶算法的速率限制)、neural-redis(一个可训练的神经网络模块)、redis-tdigest(实现了 t-digest 这种用于估算百分位数的数据结构)、Cthulhu(一个允许使用 JavaScript 来编写 Redis 模块的框架)、Redis Snowflake(用于生成类似雪花算法的分布式唯一 ID) 和Redis-roaring(实现了 Roaring Bitmaps 这种高效的位图数据结构) 等等。
这些形形色色的模块,将 Redis 的核心能力有效地延伸到了像高级搜索、图计算、时间序列分析以及人工智能和机器学习等全新的领域,从而在实际上将 Redis 转变为一个功能更为全面的多模型数据库平台。相关的资料提到:“Redis 模块是 Redis 的一些附加组件,它们能够扩展 Redis 的功能,以覆盖各个不同行业中最流行的那些用例……模块可以由任何人来创建。”
第七节启示与影响
Redis 对现代软件开发所产生的影响,是多维度且极其深远的。
首先,Redis 已经成为了许多现代应用架构模式的赋能者。其卓越的执行速度和灵活的数据结构,使得它在像微服务架构、事件驱动架构以及各种实时数据处理系统这些先进的架构模式中,都扮演着至关重要的关键组件角色。它通常会作为一个快速的数据层,或者一个高效的通信骨干来发挥作用,从而使得这些在理论上看起来很美好的先进架构模式,在实际的工程实践中变得真正可行。例如,微服务架构天然就需要一个能够提供快速共享状态存储和高效服务间通信的机制,而 Redis 恰好能够同时满足这两方面的需求。同样,事件驱动的系统则严重依赖于健壮可靠的消息队列,而 Redis Streams 正好能够很好地满足这一需求。此外,像实时分析、在线排行榜等功能,则直接受益于 Redis 那些经过精心优化的数据结构和其自身的高性能特性。
其次,其生态系统的效应非常显著。针对几乎所有流行的编程语言,都存在着高质量的、易于使用的客户端库,以及像 RedisInsight 这样功能强大的管理和监控工具。这些都极大地降低了开发者采用和使用 Redis 的门槛,为其最终能够取得广泛的成功,做出了巨大的贡献。通过那些开发者们早已熟悉的客户端库,可以轻松地将 Redis 集成到他们现有的技术栈之中,这使得开发团队能够无缝地采用 Redis 来提升其应用的性能和功能。而像 RedisInsight 这样的工具,则简化了对 Redis 实例的操作、调试和数据探索过程,使得 Redis 更易于被更广泛的开发者群体和运维人员所接受和使用。
最后,模块系统作为一种力量倍增器(虽然也曾一度成为争议的焦点),其作用不容小觑。模块系统极大地扩展了 Redis 的核心能力,有效地将其从一个主要的数据结构服务器,转变为一个功能更为全面的多模型数据库平台。然而,值得注意的是,Redis Ltd. 公司对其开发的某些非常流行的模块所采用的许可方式,也一度成为了在核心 Redis 本身许可证发生变更前夕的一个争议焦点。诸如 RediSearch 和 RedisJSON 这样的模块,在 Redis 快速的内存引擎基础之上,添加了全新的数据库范式(例如搜索引擎功能、文档存储功能等),这本身是非常强大的。但是,其中一些由 Redis Ltd. 开发的模块,在被集成到 Redis 8 核心之前,曾一度采用了比核心 Redis 更为严格的许可证(例如,一些旧版模块曾使用过像 RSAL、SSPL 这样的许可证),这在某种程度上也预示了后来核心 Redis 本身的许可证变更趋势,并加剧了当时社群中的一些不安情绪。如今,许多这类曾经作为独立模块提供的强大功能,都已经被整合进了采用新的三许可证模式的 Redis 8 核心之中,这本身也是一个非常重大的转变和发展。
最后总结
Redis 的发展历程,从 Salvatore Sanfilippo 为了解决 LLOOGG 项目的燃眉之急而进行的个人探索,到如今成为支撑全球无数高性能应用的关键基石,充分展现了在实际需求的驱动下,技术创新所能爆发出的巨大能量。其核心设计哲学——以内存为先、追求极致的速度、提供简洁而强大的数据结构、以及始终关注开发者体验——不仅在早期为其赢得了用户的青睐,更在漫长的演进过程中,被证明是其能够保持持久生命力的关键所在。
从最初支持基本的键值存储和列表操作,到后来逐步引入哈希、集合、有序集合等更为丰富的数据结构,再到通过 Sentinel 和 Cluster 机制解决高可用与横向扩展的挑战,Redis 的每一步都紧密围绕着提升性能和满足更广泛应用场景的需求。Lua 脚本的加入,赋予了服务器端一定的可编程性;而模块 API 的出现,则更是将 Redis 提升到了一个可扩展平台的层面,催生了像搜索、JSON 处理、时间序列分析等更为专业的应用能力。Redis Streams 的引入,则使其在事件驱动架构和实时消息处理领域占据了重要的一席之地。
进入近代,Redis 6.x 和 7.x 版本在安全性(如 SSL/TLS 加密、ACLs)、可编程性(如 Redis Functions)以及协议层面(如 RESP3、客户端缓存)的持续增强,使其更加符合企业级应用对稳健性和精细化管理的需求。
然而,开源项目的治理和商业化探索之路,从来都不是一帆风顺的。近期围绕 Redis 许可证所发生的一系列变动——从最初的 BSD 到引发争议的 RSAL/SSPL 双重许可,再到 Valkey 分支的出现,以及最终 Redis Ltd. 选择在 Redis 8.0 中回归到包含 AGPLv3 在内的三许可证模式——深刻地反映了在当前云计算时代,开源项目在维护自身可持续发展与坚持开放共享理念之间所面临的复杂博弈和艰难抉择。这一系列的事件,不仅对 Redis 自身的发展轨迹产生了深远的影响,也为整个开源软件行业如何平衡商业利益与社群期望,提供了极具价值的案例研究。
幸运的是,Redis 8.0 版本的发布,通过将许多 ранее 作为独立模块提供的强大功能直接集成到核心之中,并引入了像向量集这样的前沿特性,再次展现了其强大的技术创新能力和积极拥抱未来的决心。其创始人 Salvatore Sanfilippo 的回归,也为项目的未来发展方向和与社群的关系修复,注入了新的活力和希望。
总而言之,Redis 的故事,是一部关于如何从一个具体的问题出发,通过简洁而强大的设计,不断迭代和演进,并最终成长为一个在各自领域都具有巨大影响力的技术产品的经典传奇。它告诉我们,真正的创新往往源于对实际需求的深刻洞察;一个活跃、开放的社群是技术项目赖以生存和发展的沃土;而在商业化和开源精神之间寻求可持续的平衡,则是每一个成功的开源项目都必须认真思考和勇敢面对的课题。展望未来,无论其治理模式和商业策略如何演变,Redis 凭借其在内存数据处理领域的核心技术优势和不断创新的能力,仍将在未来的数字世界中,继续扮演着不可或缺的关键角色。