- Redis 采用高级结构和原子操作将数据存储在内存中。
- 支持持久性(RDB/AOF)、异步复制以及Pub/Sub和Lua等工具。
- 非常适合具有极低延迟的缓存、会话、消息传递和排名。
如果你曾经需要你的应用程序像火箭一样快速运行,你可能听说过 Redis。这项技术是一种内存数据系统,它提供 极低的延迟和几乎即时的响应,当速度是绝对优先考虑的事情时,这是理想的选择。
Redis 不仅仅是一个缓存系统,它是一个键值型NoSQL 数据库,拥有多种数据结构和集成工具。它最初于 2009 年发布,使用 C 语言编写,其名称来源于“远程字典服务器”(Remote Dictionary Server)。如今,Redis 拥有非常活跃的生态系统,几乎支持所有编程语言,并具备强大的持久化和复制功能。
Redis 是什么以及它有什么用途?
Redis 是一款内存存储引擎,支持键值对和高级数据结构。由于它在内存中运行,因此可以减少磁盘访问常见的瓶颈,非常适合对速度要求极高的场景:例如用于处理繁重查询的缓存、用户会话管理、实时消息传递、在线游戏、包含流数据的仪表盘等等。
在许多项目中,它被用作传统数据库前的缓存层,用于存储重复性结果,以避免持续的重新计算或重新查询。当对数据持久性没有严格要求,或者其持久性配置为确保数据存储在磁盘上时,它本身也可以用作数据库。
其客户端/服务器架构、网络接口和轻量级设计使其易于部署并从多个主机连接。此外,它还提供异步主从副本模式(主节点在复制的同时继续运行),这有助于扩展读取能力并提高可用性。
主要特色
Redis最大的优势在于所有数据都驻留在主内存中。这消除了关键路径上的磁盘访问,从而实现了极快的读写速度。此外,每个字符串最大可达512MB,支持二进制数据,并包含列表、集合、有序集合、哈希表、HyperLogLog、位图和流等多种数据结构。
Redis 对这些数据结构实现了高级的服务器端原子操作。这使得您可以对集合执行并集、交集或差集运算,修改子字符串,或者对整数和浮点数进行增减运算而不会出现竞态条件。
它包含加速开发和简化常见模式的工具:发布/订阅频道(非常适合实时消息传递和通知)、带 TTL 的密钥用于自动过期、原子计数器用于指标和并发控制,以及从 2.6 版本开始对服务器端逻辑的Lua 脚本的嵌入式支持。
另一个强大的优势是它与模块的兼容性。Redis模块扩展了诸如JSON 文档、时间序列和搜索等功能,使其成为一个远超简单键值对的多功能系统。

历史、许可证和演变
Redis 由 Salvatore Sanfilippo 于 2009 年创建,旨在改善名为 LLOGG 的产品的延迟。它迅速获得成功,2010 年VMware 聘请 Sanfilippo 全职领导该项目;Pieter Noordhuis 随后也加入了团队。2013 年至 2015 年间,Redis 由 Pivotal 赞助,之后由 Redis Labs 接手。
自 2.6 版本起,服务器集成了 Lua 解释器,支持在 Redis 内部直接执行脚本,确保操作的原子性,并最大限度地降低客户端到服务器的往返延迟。在许可方面,它采用RSALv2 和 SSPLv1双许可模式分发。
数据模型和操作
Redis 使用全局字典将键映射到值。与更简单的键值对方案不同,Redis 的值可以是不同的类型。类型决定了可用的命令以及可以对该数据执行的原子操作。
Redis 的 String 类型是“二进制安全的”:它可以包含文本、整数、浮点数或原始二进制数据,例如 JPEG 图像或序列化对象。您可以对字符串的某些部分进行操作,修改特定位,或将其用作带有递增/递减功能的计数器。
列表用于管理队列或栈,集合和有序集合用于成员关系和按分数排名,哈希表存储字段值映射,这对于对对象的属性进行分组非常有用。HyperLogLog 用于以极少的内存实现近似基数计数器,而流则有助于以分组方式处理事件流。
此外,Redis 提供事务(MULTI/EXEC),允许您将多个操作分组,按顺序原子地执行。结合 Lua,您可以可靠地封装复杂的服务器端逻辑。
持久性:快照和 AOF
Redis 可以纯内存运行,但也支持磁盘持久化,以平衡性能和持久性。通过快照(关系数据库),它可以定期对数据集进行快照并异步保存,从而最大限度地减少对响应时间的影响。
另一种选择是 AOF(日志记录),它会记录对文件的每一次写入操作。这种模式提供了更精细、更可配置的持久性:`appendfsync=always`强制每次更改都进行同步(安全性最高,但性能较低),而`appendfsync=everysec` 每秒同步一次(性能平衡性极佳)。
如有需要,您还可以手动触发保存操作,立即强制创建快照。即使机器完全崩溃,通常也只会丢失少量数据,具体数量取决于您选择的同步策略。
在旧版本中,从 2.4 版本开始允许使用“虚拟内存”,但这种方法现在已经过时了。目前,建议在关系数据库 (RDB)、自动机会数据库 (AOF) 或两者结合使用之间进行选择,并根据数据重要性和所需性能调整配置。
复制和高可用性
Redis 实现了异步主副本复制。这意味着写入操作在主服务器上进行,副本服务器同步更新,而不会阻塞主服务器,从而保证服务在同步期间持续运行。一个主服务器可以拥有多个副本服务器,而一个副本服务器又可以作为另一个副本服务器的主服务器,从而形成树状拓扑结构。
复制对于扩展读取操作和实现冗余非常有用。某些配置允许向副本写入数据,但如果控制不当,这可能会导致数据不一致;默认情况下,副本通常用作只读以保持一致性。
将副本部署在用户附近可以降低感知延迟。借助编排和哨兵/集群工具,可以实现高可用性和自动故障转移,从而最大限度地减少主节点故障时的停机时间。
客户端/服务器架构和生态系统
Redis 服务器提供了一个简单的协议,不同语言的客户端都可以连接到该协议。您可以使用其官方命令行界面 (redis-cli)进行测试、管理或快速脚本编写,也可以将库集成到您的应用程序中。
它支持 ActionScript、C、C++、C#、Java、Go、Python、PHP、Ruby、Scala、JavaScript(包括服务器端 Node.js)、R、Erlang、Haskell、Lua、Objective-C、Perl、Common Lisp、Smalltalk、Tcl、Io、haXe、Pure Data 等多种语言的客户端。如此广泛的支持使其几乎可以轻松部署到任何技术栈中。
真实用例和实际示例
一个非常常见的例子是线上房地产中介:房源信息(包括价格、配套设施和房间数量)几乎不会改变。如果没有缓存,每次访问都需要重复查询和计算。而使用 Redis,首次加载后,对象会被保存,并带有一个键(例如property_4056)和一个生存时间(TTL),比如一个月。后续访问直接从内存读取数据,避免访问数据库。
缓存大量报告结果、管理已验证的会话、使用排序集构建实时排名,或者使用 Pub/Sub 作为服务之间的轻量级消息传递通道,也是常见的做法。
我们使用一个包含 16.000 行错误数据的表进行了测试,分别测量了以下三个步骤的耗时:1) 查询数据库;2) 将数据集合保存到 Redis;3) 从 Redis 读取数据。结果令人震惊:从 Redis 检索数据的速度比从数据库检索快 26 倍。这些对比测试通常能够凸显性能对用户体验和基础设施成本的实际影响。
Redis 与 Memcached
这两种技术都用于内存缓存,但存在显著差异。Redis 提供多种数据类型(列表、集合、哈希表等)、可选的磁盘持久化、发布/订阅模式、Lua 脚本、事务以及用于扩展功能的模块。而 Memcached 则专注于简单的内存键值模型,不具备持久化功能。
就原始性能而言,两者都非常快;Redis 在处理复杂结构和原子性服务器端操作的场景中往往表现更佳。如果您只需要一个非常简单且超轻量的缓存,Memcached 可能就足够了,但如果您追求更强大的功能和更高的灵活性,Redis 通常是最佳选择。
托管服务与自管理服务(Redis 和 Valkey)
您可以自行部署 Redis 或 Valkey,也可以选择托管云服务。自行管理可以让您完全控制,但可扩展性和维护工作(添加节点、更新、安全、备份、监控)则由您负责。
托管服务可减轻运维负担:更易于扩展、高可用性以及轻松更新。这通常意味着更低的总体拥有成本,并使团队能够将更多精力集中在数据建模和业务功能上,而不是平台相关的任务上。
集成工具:Pub/Sub、TTL、计数器和 Lua
借助发布/订阅模式,您可以在频道中广播消息,并让多个订阅者即时接收,这非常适合聊天、通知以及微服务之间的协作。它是一种简单而有效的模式。
生存时间 (TTL) 键允许您“自动清理”临时数据:会话、令牌、过期的查询结果等。这可以防止数据库被过时的信息填充,并简化过期逻辑。
原子计数器非常适合用于指标、速率限制、队列,或者任何需要在并发环境中安全地进行加减操作的情况。
最后,Lua 的嵌入式支持使您能够以原子性的方式在数据附近运行脚本。这减少了网络传输,并允许您一步完成复杂操作,从而提高一致性和性能。
常见问题
Redis 有什么用途?它可以加速应用程序,提供内存缓存、会话、实时排名、轻量级 Pub/Sub 消息传递功能,并且在延迟至关重要或需要持久化时,可以用作 NoSQL 数据库。
为什么 Redis 速度如此之快?因为数据驻留在 RAM 中,消除了关键路径上的磁盘访问,并提供了原子性的服务器端操作;此外,它的协议轻量高效。
它可以用作数据库吗?可以。它是一个内存型 NoSQL 数据库,并提供持久化选项(关系数据库和 AOF)。根据您的配置,您可以优先考虑性能或持久性,或者两者兼顾。
语言支持
几乎所有编程语言都有成熟的客户端:Python (redis-py)、Java (Jedis)、Node.js (ioredis)、C#/.NET (StackExchange.Redis)、PHP (phpredis)、Go (go-redis)、Ruby (redis-rb) 等等。如此丰富的选择确保了与您现有技术栈的无缝集成。
Redis 已成为解决大多数现代架构中性能和实时问题的“万能牌”:它结合了闪电般的速度、丰富的数据结构、可配置的持久性、复制以及一系列实用工具,如果使用得当,就能显著改善用户体验。