Redis是我见过最像“一个人写出来”的软件。如果你翻过它的源码和文档应该会懂我的意思——命令名取得随意又准确C语言函数写得直接注释里偶尔还冒出一句意大利人的自言自语。所以当Redis之父Antirez在2020年正式离开维护岗位时我的第一反应不是“Redis完了”而是一个扛了十多年核心包袱的大神终于能卸下担子去做点自己想做的事了。标题里说的“再见了Antirez”与其说是一场告别不如说是一个时代标记。Redis今天的地位太过稳固稳定到很多人已经把它当成和Linux内核一样“本来就在那里”的基础设施。但如果你愿意往回看会发现这个内存数据库并不是哪个大厂孵化的重型项目而是Antirez一个人从实际需求里长出来的作品。这篇不是悼文他也不需要悼文。我想借这个标题把Redis背后的技术选择、代码哲学以及“一个人维护一个世界级开源项目”这件事拆开讲讲顺便聊聊他在2020年转身离开后社区和产品本身发生了什么。1. “再见”的含义Antirez退出Redis维护比很多人想象的更平静1.1 一个时代节点的确认从核心维护者到交棒者Antirez的离开并不是突然发生的。早在2014、2015年左右他就开始逐步把一些核心模块的维护工作交给身边信任的贡献者比如负责集群和模块系统的几位核心开发者都是在那几年陆续接手的。到了2020年他在个人博客和社交账号上明确表示要退出Redis项目的日常维护工作把项目正式交给Redis公司团队和社区继续推进。这件事在当时的后端圈子里震动不小。因为那是Redis是几乎每套Web系统都在用的缓存与数据结构中间件。很多人的第一反应是担心项目会不会断更开源社区会不会失去方向但我当时的判断恰恰相反——Antirez的离开恰恰说明Redis已经从一个“个人英雄主义的开源项目”平稳过渡成了一个“有组织的、可持续运转的软件生态”。他的退出不是撒手不管而是负责任地确认这东西不需要我再盯着也能活。1.2 平静退出为什么比悲情离场更难得回顾开源界的历史创始人被社区逼走、项目分裂、团队内讧之类的戏码并不少见。Antirez的处理方式与之相比显得异常体面。他没有发表任何抱怨没有点名批评公司与社区之间的矛盾只是说“我累了我想把精力放到别的地方去”然后安静地把文档、issue、仓库权限一一交接。这种平静背后其实是一种对项目边界的清醒认知。Antirez曾经在多个场合表达过开源软件的火爆会带来很多超出写代码本身的事情包括社区维护、商业公司内部的政治、无穷无尽的issue和邮件。他享受的是设计数据结构和解决算法问题的过程而不是当一个大项目的CEO。所以当他选择在项目最辉煌的时候抽身我反而觉得这是对Redis最负责的行为——不让个人情绪过度绑架一个已经被千家万户依赖的软件。2. Redis之神的封神起点一个名为LLOOGG的实时统计需求2.1 不是为做数据库而做数据库来自真实业务的一次“偷懒”Redis的诞生故事很多老后端都听过Antirez最早是在做一款类似实时博客分析的工具叫LLOOGG用来追踪和分析网站访问流量。做这类产品的时候他遇到了一个非常朴素又非常头疼的问题——每一次页面刷新都要实时更新访问计数、独立访客、时间段统计等数据传统的关系型数据库在这种场景下显得笨重。那时候的常规做法无非两种直接写MySQL靠索引和SQL聚合或者引入某种预计算机制把统计结果缓存在内存里。但Antirez当时的野心更大一点他发现自己真正想要的是一个“可以供多个进程共享访问”的内存数据结构服务——既能放计数器又能放列表和集合还能给key设置过期时间。这东西像极了PostgreSQL里的某种内存临时层但他不想被限于某个数据库客户端干脆自己动手写。2.2 第一版Redis有多“小”几个文件、一堆C代码和一个明确的核心思路早期Redis的原型远没有现在这么宏大。它就是几个C文件实现了一个简单的TCP服务同一时间只服务一个客户端支持非常原始的命令解析核心数据结构也就哈希表、链表、字符串那几样。但正是这种“小”塑造了Redis最初的气质功能少而精确每一条命令都能直接映射到一个具体的数据结构操作。后来Antirez在一篇回顾里讲过当时他给自己定的原则是“不解决理论问题只解决手头问题”。LLOOGG需要实时统计他就为LLOOGG做一个带INCR命令的计数器需要维护最近访客列表就为它做LIST类型。今天的Redis被归类为“多模态数据存储”但它的出发点其实极其朴素——刚好长成一个能扛住实时统计压力的内存数据库。这段经历对我个人的启发很大。很多技术选型上的纠结其实应该回到业务源头去问你到底在解决哪个具体问题Antirez不是先画了一张数据库蓝图再去实现而是先在应用层撞上了一个真实痛点再从痛点反推出一个通用组件。Redis之所以实用就是因为它的每一层设计都带着“真实世界拷问过”的痕迹。3. 代码里有神性拆解Redis中那些“简单到优雅”的核心设计3.1 SDS让C字符串第一次真正拥有“长度”这个概念Redis用C语言编写但你在它的源码里很少会看到裸的char*字符串取而代之的是一个叫SDSSimple Dynamic String的结构。这是Redis底层最不起眼、却影响最深的设计之一。传统C字符串靠结尾的\0来标记边界获取长度得O(n)扫描中间还不能包含空字符不只是二进制上不安全而且所有字符串拼接、截断都要开发者小心翼翼管理内存。SDS在字符串头部记录了已用长度和空闲长度一方面把strlen变成了O(1)操作另一方面通过空间预分配和惰性释放大幅减少了频繁append时realloc带来的性能抖动。这套设计并非Redis首创但Antirez把它在一个数据库项目里用到了极致。所有键、所有值、所有协议帧背后都是SDS。它让Redis在存储包含二进制内容的数据时也能做到完全安全。你甚至可以这么理解SDS的存在让Redis的字符串类型从设计上就超越了C语言标准库提供的字符串抽象。3.2 单线程事件循环用最简单的并发模型消解掉一类难题Redis过去很长一段时间的标志性特征就是单线程模型——所有命令在一个主线程里串行执行。很多人第一次听到这个设计会很疑惑内存数据库不是应该靠多线程并发来榨取性能吗实际上Redis单线程模型的优势被大多数人低估了。它从根上消除了多线程编程中让人头皮发麻的竞争条件不需要死锁不需要自旋锁不需要处理缓存一致性。更关键的是正因为串行执行所有命令INCR、DECR这类复合操作天然就具有原子性不需要多余的锁开销就能保证计数不丢。一个线程配合epoll/kqueue事件循环照样能支撑十几万甚至几十万的QPS因为瓶颈本来就不在CPU上而在网络和内核协议栈上。Redis 6.0开始引入了IO多线程但那只是把网络数据包的读和写交给辅助线程来处理真正的命令执行仍然集中在主线程。理解了这层设计之后你就明白Antirez一直在走“用简单模型解决主要矛盾”的路线而不是逢性能问题就上多线程。3.3 跳表与ziplist数据结构选择里的实用主义如果说SDS和事件循环还算是“基础操作”那么有序集合ZSet底层实现的选择就更能体现Antirez作为程序员的底气。ZSet既要支持单个成员的快速插入删除又要支持按分数范围查询还要能做类似排行榜那样的倒序分页。教科书上会推荐平衡树但Redis用了一个很多人以为“很低级”的结构——跳表skiplist。跳表的思路比平衡树简单得多多层链表上层通过随机化来决定一个节点出现在多少层查找时从最高层往下走本质上就是“跳着走”时间复杂度也能做到近似O(log n)。它没有平衡树那种复杂的旋转操作实现起来短而清爽更重要的是范围查询天然友好你给我一个分数区间我能直接从链表里顺着把结果取出来。Antirez早年写过一篇短文解释为什么不选平衡树核心就是他发现实现复杂度带来的维护成本远远超过跳表那一点理论上的时间差。再比如ziplist——Redis在保存数量不多的小哈希、小列表时会用一个连续内存块来存储数据而不是直接上真正的哈希表或双向链表。连续存储带来的好处非常实在内存碎片少、CPU缓存命中率高。它的代价是插入和删除可能引发后续元素的移动甚至连锁更新所以Redis只会在元素数量小、长度短的时候启用这个优化一旦数据规模上来就自动转换为常规结构。这种“分情况处理、不搞一刀切”的工程智慧你只有真正做高性能服务时才能体会到它有多值钱。3.4 命令集的“上帝视角”把数据库做成数据结构工具箱Redis的命令设计也是一绝。普通数据库给你的是SQL是表和关系Redis给你的是SET/GET、HSET/HGETALL、RPUSH/LRANGE、SADD/SINTER、ZADD/ZRANGEBYSCORE——一整套编码成动词的数据结构操作。这个设计看似简单却让Redis能够成为业务系统的“算法工具箱”。排行榜可以用ZSet去重可以用Set队列可以用List会话缓存可以用Hash配合EXPIRE。你可以用一条INCR搞定计数器用BITFIELD做周期内活跃用户统计用PUBLISH/SUBSCRIBE实现轻量级消息通知。这种“用命令组合解决业务问题”的体验在传统数据库身上是感受不到的。我在实际项目里最常感慨的是Redis的很多命令是“词法层面”就设计得极度清晰错误信息写得也非常口语化读起来不会让你有在看机器语言的冰冷感。Antirez在写文档和报错文本时明显是站在开发者的体验角度思考的。3.5 代码里的“人味”那些注释和提交信息如果你翻过Redis源码会发现里面有不少让人会心一笑的注释。比如有些代码块会标注“这是为某个特定客户端场景优化的别乱删”有些地方会写“我知道这里还能再优化但现在的复杂度已经够了”。这些注释不是教科书式的“这段代码做什么”而是一个真实开发者留下的思考和顾虑。这种“人味”在严谨工程里反而成了稀缺品。很多公司的中间件代码优秀得毫无性格哪怕你读完整套源码也不知道到底是哪些人、在什么场景下、为什么做出这些取舍。而我读Redis源码时能隔着屏幕感受到Antirez的情绪边界——比如他会为了一个内存布局问题盯好几个星期或者对某个命令的命名后悔不已后在注释里吐槽自己。软件工程常说可读性Redis大概算是最能体现“作者人格”的大型C项目之一。4. 离开之后Redis没有倒下但少了一种“有人气的代码”4.1 2020年后的记忆点Redis 7、函数、多线程IO与模块化Antirez走后Redis的发展并没有停步。Redis 7带来了函数Redis Function机制让原本依赖Lua脚本才能实现的复杂逻辑有了更统一的服务端管理方式ACL权限体系被进一步加强IO多线程也从早期实验走向生产可用。这些事情在Antirez在位时就有铺垫但如果没有一个组织化的团队持续投入单凭个人维护者很难把节奏推到这一步。从结果看Antirez的离开对Redis日常稳定性几乎没有造成冲击。这本身就是了不起的遗产他没有把项目结构变成“非自己不可”的独裁状态而是通过文档、设计笔记、社区流程把一个开源项目变成了可传承的公共财产。很多开源项目做到一半创始人撒手后迅速死掉Redis之所以能平稳接力和Antirez早年有意培养核心维护者、留下大量设计注解有很大关系。4.2 商业化与开源的边界AGPL许可争议背后其实没有谁对谁错Antirez在任期间Redis的开源许可是从BSD转向AGPL的。这个转变在当时引起了不小的争议——BSD允许你随便改随便用AGPL则要求你以服务形式对外提供修改版时同样开源。对Redis公司而言这种收紧是为了防止大厂借着开源代码做托管服务却只出不进对很多中小团队来说这只是更谨慎一点并不妨碍内部使用。后Antirez时代Redis公司在商业化动作上明显更有存在感了包括推出Redis Stack、强化企业版和企业级支持服务。有人会感叹“Redis不再纯粹”但我不这么看。开源软件要长久生存必须面对一个现实问题维护者的时间、服务器、安全审计、法律合规都要用真金白银来换。Antirez能体面离开恰恰说明商业公司接住了这个盘。开放源代码和商业运作从来不是二选一的敌人关键在于接棒者是否理解项目原有的技术气质。4.3 维护者倦怠是所有活跃开源项目都要面对的“房间里的大象”Antirez在多个场合提到过自己为什么不想继续做维护每天处理大量issue、回复邮件、评审提交占据了几乎所有能用来写代码的时间做创新设计的时间被无限压缩长期下来就是burnout。这其实是所有超级用户量级开源项目维护者的共同困境——你不是在和一个技术问题缠斗而是在和一个全天候运转的公共服务缠斗。他选择离开这件事本身给开源社区提供了一个值得学习的范本承认自己的精力边界允许自己退场把位置交出去而不是死撑着直到项目腐烂。这一点我认为比任何Redis代码设计都要重要。正因为Redis传来了“创始人也会累”的讯息后来的一批开源项目在建立治理模式时会更早地思考怎么把维护权分散、怎么写传承文档、怎么培养接班人。5. 如果Antirez还在键盘前他会怎么点评2024年的Redis5.1 Redis Stack模块化的扩张是方向还是妥协这两年Redis公司主推Redis Stack把JSON、向量检索、时序数据类型打包进一个产品线里。很多人会问这还是一直强调“保持简单”的Redis吗从我看到的公开言论推断Antirez对模块化本身并不反对他和核心团队很早就设计了模块系统允许外部开发者以module方式扩展Redis命令。他真正警惕的可能是“膨胀”当Redis想做的事情太多时核心的优雅会不会被稀释。如果你去读他早期写的一些设计文档会发现他始终坚持“能不做就不做”每条命令都要回答“是不是真的有不可替代的使用场景”。所以我的猜测是他不会全盘否认Redis Stack但可能会反复提醒模块之间要保持独立别让最简单的SET/GET被一堆高级功能掩盖。Redis今天最大的价值仍然是它可以在几十毫秒内完成多种数据结构的运算这个底座没丢那么在这个底座上盖多少层楼都是合理的。5.2 大模型时代的内存数据库冷热数据分层会让Redis过时吗每次出现新架构热潮都会有人唱衰Redis比如曾经有人断言Rust重写的高性能KV会把它挤下去也有人觉得云原生内存数据平台才是未来。但事实是Redis这类“内存数据结构服务器”有它独特的位置它不只是一个缓存而是一个能运行数据逻辑的内存层。在大模型场景里向量检索模块可以直接在内存中做相似度计算会话状态和特征向量都能以极低延迟被读取在传统业务里排行榜、计数器、分布式锁、限流器这些场景根本找不到更顺手的替代品。只要“热数据需要极低延迟和灵活数据结构”这个需求存在Redis的核心价值就不会消失。Antirez早年的设计几乎是所有后来内存竞品都要借鉴的基准线。后来者可以做得更花哨但Redis用最朴素的命令组合搭出的稳定性依然难以被超越。5.3 “Redis之神”这个称呼或许是最不该被期待的东西Antirez本人对“神”这个字恐怕是不好意思接受的。他从始至终都强调自己只是遇到了合适的问题、写出了合适的数据结构并且在开源社区的帮助下把它打磨得越来越好。与其说他是“神”不如说他是一个把复杂问题看穿到简单层面的工程师。理解这一点对我们普通开发者来说是非常受用的。Redis并不依赖秘诀它依赖的是对真实问题的敏锐观察、数据结构基本功以及“能不能把这个东西改到更好”的长期耐心。Antirez离开前留给开发者的最大财富不是眼前的这套数据库而是这套数据库侧面写下的思维路径从问题出发用简单方案解决在代码里留下思考痕迹。所以“再见了Antirez”这句话我后来觉得更像是在致敬一个状态他终于可以去写自己想写的小工具去研究完全无关的领域去过一个普通程序员的生活。而他留下的Redis则像一棵已经扎根很深的树不需要园艺师天天在场也能在合适的气候里继续结果。我也越来越确信最好的开源软件不是创始人永远留在上面而是创始人有勇气在上面刻下“此处已经交给后来者祝你好运”。
阅读完成 · 觉得有帮助?