Redis 与 Hazelcast:面向 Java 开发者的实用对比
Java 开发者视角下 Redis 与 Hazelcast 的逐项实用对比——架构、数据模型、线程、协调、计算、运维、成本——以及在何时选哪个的清晰指引。两者都不错;只是擅长的事情不同。
两者都加快读取。两者都把键值数据放进内存。两者都有 Spring Boot starter。除此三句之外,它们走向完全不同的方向,二者之间的选择,更多关乎你究竟在构建什么样的系统。
为什么这场对比总会出现
问题每次都以相同方式落下:一个 Java 团队遇到了慢页面,有人提到缓存,第二天早上白板上出现一个半成形的方案——两个方框,Redis 和 Hazelcast,中间一个箭头。两者都是合理答案,也都是真正不同的工具。靠"撞上去"做选择,往往意味着你将与自己根本没意识到要承担的约束共处。
这篇文章是我希望第一次面对这个选择时有人给我的对比。它假定你已经读过本系列的前两篇,分别讲 Redis 缓存策略 与 把 Hazelcast 当作内存数据网格。如果没有,浏览一下——后面的内容会更扎实。
一段话答案
如果你的团队需要一个快的键值缓存与发布订阅系统、运行多语言栈,并希望运维故事保持简单,选 Redis。如果你的团队主要在 JVM 上、需要分布式协调(锁、原子计数器、领导选举)、希望计算与数据共驻、或希望缓存就嵌入在应用内部,选 Hazelcast。两者基本缓存都做得好。在基础缓存之外,它们各自奖励不同的下注。
架构——两种不同形状
Redis 是一个远端服务器。用 C 写成,单分片单线程运行,你的应用通过网络协议(RESP)与之对话。本质上它是你连接的进程。即便用 Redis Cluster 扩容,模型仍是"应用使用的外部服务"。
Hazelcast 是用 Java 写的分布式系统,作为集群的一部分运行。在嵌入式模式下,启动的每个 JVM 都加入同一个 Hazelcast 集群——你的应用就是一个成员。在客户端-服务端模式下它看起来更像 Redis,但底层引擎仍是一张 JVM 原生的对等网格。
这一形状差异是其他大多数差异的根源。单线程对多线程。远端对嵌入式。先多语言对先 JVM。看清形状之后,其余对比不再像功能列表,开始变得不可避免。
数据模型与操作
两者都有丰富的数据结构集合。它们既有重叠,也有分歧。
- Redis:字符串、哈希、列表、集合、有序集合、流、HyperLogLog、Geo、位图、发布订阅。每种带几十条原生命令。有序集合与流尤其有差异化——别处难有匹敌的等价物。
- Hazelcast:
IMap、IQueue、ITopic、MultiMap、ReplicatedMap、IExecutorService、IAtomicLong、FencedLock、ISet、IList。每种像对应的java.util接口,但分布式。
实务上重要的是:Redis 给你更锋利、更专门的数据结构(有序集合、流),但 API 是你需要拼装的不透明命令的扁平列表。Hazelcast 给你由分布式引擎支撑的熟悉 Java 类型——对 JVM 团队顺手,对 Python 服务则不那么。
线程与原子性
Redis 单分片单线程。每个命令必须执行完才能开始下一个。这就是其可预测性的秘密——Redis 内部没有竞态。代价是长时间运行的命令会阻塞整个分片,CPU 饱和很快撞上单核天花板。
Hazelcast 在每个节点的所有核心上多线程。不同 key 上的操作并行运行。代价是分布式并发的复杂度——靠 EntryProcessor 这样的原语缓解,它把代码送到数据上,给你单 key 的原子性。
对大多数缓存负载,无论哪种差异都不重要。对要做集群级协调的负载,Hazelcast 的原语更友好。对只需要一个快速发布订阅系统的负载,Redis 很难被超越。
持久化与耐久性
Redis 提供两种持久化方式:快照(RDB——周期性时间点转储)与追加文件(AOF——每次写入都被记录以便回放)。它们成熟、好理解,并允许你以写入性能换取耐久性。
Hazelcast 有 Persistence(原 Hot Restart Store),每个成员把自己的分区写到本地磁盘,这样整集群重启后能恢复。对"数据库是真相,网格是缓存"的负载,你接一个 MapStore,对真正的数据存储进行读穿透与写穿透。
两者都能熬过进程重启。两者都在耐久性与吞吐之间提供可配置的取舍。差别更多在持久化故事如何与你其余的栈集成——Redis 把它当作服务器问题;Hazelcast 把它当作每个 map 的配置。
分布式协调
这是两者拉开距离的地方。
Redis 并非作为协调层而设计。人们这样用它——用 SET NX 与 Redlock 算法实现分布式锁、靠 EXPIRE 游戏构建领导选举、用 MULTI/EXEC 或 Lua 脚本做事务——但这每一种用法都是"你,作为开发者,在一个并未承诺正确性的工具之上构建正确性"。对弱协调(偶尔失败的咨询锁)这没问题。对强协调(不能让两个实例都自认为是 leader),这是危险的。
Hazelcast 自带基于 Raft 共识的 CP subsystem,提供具有线性一致语义的 FencedLock、IAtomicLong、IAtomicReference 与 ISemaphore。这些是你本来要去找 ZooKeeper 或 etcd 提供的原语。在已经运行 Hazelcast 的 Java 服务里,这是一种实在的能力,而且不需要再多一块基础设施。
在数据所在处执行计算
Redis 通过 Lua(以及较新的 Redis Functions)执行脚本。它们在服务器上、数据上、单线程地运行——可用于无往返的原子读改写。约束是脚本必须短且非阻塞,并且用 Lua 写是从你的应用语言切换出去。
Hazelcast 提供 EntryProcessor 用于单条目原子更新,IExecutorService 用于可路由到特定 key 的拥有者、特定成员,或所有成员的任意任务。代码是普通 Java,可以足够大,结果聚合内建。对在大数据集上的分析或批量更新,这一差别意义重大——你把函数送到数据,而不是把数据搬到函数。
Hazelcast Jet(现已并入核心)在此之上更进一步,提供完整的流处理流水线,从数据源读取、用对你 IMap 的状态查询做转换、再写入下游。Redis 没有等价物。
语言与生态契合
Redis 真的是多语言的。每种主流语言都有可靠的客户端。协议小且文档良好。如果你的栈里有 Java 服务、Python 服务、Node 服务和 Go 服务都需要同一份缓存,Redis 是显然的选择。
Hazelcast 优先服务 JVM。.NET、C++、Python、Node 与 Go 也有客户端,但与 Java 体验相比明显是二等公民。分布式 Java 类型(IMap、IExecutorService)和送到数据上的任务都假定数据是——嗯——一个 Java 集群上的 Java 对象。多语言栈也能用 Hazelcast,但你会放弃使它有趣的很大一部分。
运维与部署
这里有两套故事,实际差别很大。
Redis 是单一二进制、被广泛理解,且有成熟的托管选项(Amazon ElastiCache、Redis Enterprise、Upstash、Memorystore)。大多数团队不自己跑 Redis——他们租用。故障转移、集群、监控都是有成熟答案的成熟问题。一旦有了托管集群和客户端库,运维学习曲线是平缓的。
Hazelcast 是一个 JVM,有 JVM 的运维特征——堆调优、GC 行为、通过 JMX 的可观测性。Hazelcast Cloud 是官方托管选项;AWS、Azure 与 Kubernetes 都有一流的发现插件。在嵌入式模式下,你根本不单独运行 Hazelcast——它就在你的应用 JVM 里。这可以是好事(少一件要运维的)也可以是麻烦(集群重启就是应用重启)。要刻意选择。
性能——关于基准的小提醒
两者会在不同负载、版本、硬件、配置以及基准撰写者偏好下互有胜负。可用的概括:
- 对小值的纯 GET/SET,原始吞吐量量级相当。Redis 因为单线程效率往往单实例占优;Hazelcast 因为每核都做工作往往整集群占优。
- 对带索引 map 的复杂查询,Hazelcast 通常占优,因为工作在分区间被并行化。对单个 key 上的深度处理,Redis 通常占优,因为没有协调开销。
- 对跨地域或跨可用区部署,两者都有具相似取舍的复制方案。
诚实的回答:用你的数据、你的访问模式和你的硬件做基准。公开数字通常足够偏颇,值得怀疑。
成本
两者都有免费的开源版本和付费的商用版本。划分如下:
- Redis OSS 采用 BSD 许可;Redis Stack(包含扩展模块)与 Redis Enterprise 是商用。Redis 本身近期改为 RSALv2/SSPL 推动了 Valkey 分叉——如果"永久宽松开源"对你重要,了解这点有用。
- Hazelcast 社区版 是 Apache 2.0,包含大多数分布式数据结构。Persistence、WAN 复制、安全功能与 Hazelcast Cloud 是商用。
对大多数团队,他们真正运行的版本对两者都是开源。成本故事只有在企业规模或需要特定商用功能时才浮出。
何时选 Redis
- 你需要的是键值缓存与发布订阅系统,仅此。
- 你的栈真的多语言——多种语言对同一缓存说话。
- 你想第一天就用上托管服务(ElastiCache 或类似),并不再为它操心。
- 你需要 Hazelcast 没有功能对等的有序集合、流或类布隆过滤器结构。
- "一个独立缓存服务器、被广泛理解、有成熟托管选项"的运维简单性是硬要求。
何时选 Hazelcast
- 你在 JVM 上,需要集群级协调——具线性一致保证的分布式锁、跨服务的原子计数器、共享工作流状态。
- 你希望计算运行在数据所在处——用
EntryProcessor做原子更新,分区间并行查询,用 Jet 做流处理。 - 你希望嵌入式网格——每个应用实例同时是网格成员,无需运维独立缓存层。
- 你在构建有状态的 Java 服务(工作流引擎、网关、实时分析),缓存与应用拥有相同生命周期。
- 你希望淘汰 ZooKeeper 或 etcd,把协调收拢到你已经在跑的东西里。
能两个一起用吗?
能,许多团队就是这样——但选择前请认真考虑。两份缓存意味着两套故障模式、两套运维故事、两套一致性模型,以及对每块状态归属的两倍决策量。实践中行得通的模式:根据你系统的形状选主工具(多语言缓存与发布订阅选 Redis;JVM 原生协调与网格选 Hazelcast),只在另一种工具不能覆盖的特定狭窄需求上引入另一种。"我们用 Hazelcast 做进程内 map,用 Redis 做跨语言发布订阅"是合理的。"我们用 Redis 做一些缓存,用 Hazelcast 做另一些缓存"通常说明有人做了两次决策。
最后一句
工具选择看起来像技术选择,多数情况下其实是伪装的架构选择。Redis 把你拉向带远端缓存的分层架构。Hazelcast 把你拉向带内嵌网格的有状态 JVM 服务。两种都是合理架构。按功能清单选,往往选错;按你的系统天然想成为什么去选,往往选对。
对 2026 年的多数团队来说,决定性问题不是"哪个更快",而是"我们在构建什么样的系统?哪个工具能让开?"回答了这个,选择往往会自己宣告。
常见问题
这两个之中会有一个在五年内被淘汰吗?
几乎不会。它们有不同的生态位、庞大的用户基础和活跃的开发。Redis 近期的许可证变化让 Valkey 分叉变得有趣,如果许可证对你重要,有充分的理由把开源社区切到那边——但底层技术不会消失。Hazelcast 也在稳步演进。两个都可以下注;不要赌"二选一谁会赢"的二元结果。
Hazelcast 能在事件流处理上替代 Kafka 吗?
部分能。Hazelcast Jet(自版本 5 起在核心中)提供流处理流水线,Hazelcast 自身也能通过 JetService 维护有序的持久化流。对保留期、回放与消费者组语义都重要的高吞吐事件日志负载,Kafka 仍是专用工具。对需要对网格数据做状态查询的延迟敏感的富化流水线,Jet 真的有竞争力。
如果我评估的是 Valkey 而不是 Redis,这场对比会怎么变?
实际上变化很少——Valkey 是 Redis 7.2 的一个分叉,由 Linux 基金会维护,API 和协议相同。本文关于 Redis 的内容大致都适用于 Valkey,差别在于许可证、治理,以及(随时间)每个项目选择添加的新功能。如果你重视许可证纯粹性,Valkey 是让你能继续使用所学一切的答案。
在 Kubernetes 上跑会改变这个选择吗?
会改变运维故事,不改变架构故事。在 Kubernetes 上,Redis 已经成熟,有 operators 与托管选项。Hazelcast 在 Kubernetes 上也支持良好,通过 Kubernetes 插件提供一流的发现,并有官方 Helm chart。两者都跑得干净。决定性因素仍然是协调需求、嵌入式 vs 独立层、多语言 vs 仅 JVM。
我已经用 Spring Boot——这会把我推向某一个吗?
两者都有一流的 Spring Boot 集成。Spring Cache 通过 @Cacheable 等支持任何一种。Spring Session 都有实现。Hazelcast 的 Spring Boot starter 自动配置一个嵌入式集群;Spring Data Redis starter 配置一个 Redis 客户端连接。Spring 不是决定性因素——架构才是。