Hazelcast
Hazelcast 是一款开源的分布式内存计算平台,核心能力是将内存资源跨集群节点聚合,提供分布式数据结构(如 IMap
、ICache
、IQueue
)、分布式计算(如 MapReduce
、Jet
)和集群管理功能,底层设计围绕 “高性能、高可用、弹性扩展” 三大目标展开。
其底层原理可拆解为 6 大核心模块,各模块协同工作实现分布式能力,以下从架构到细节逐一解析:
一、整体架构:去中心化的 Peer-to-Peer(P2P)集群
Hazelcast 集群采用无中心节点的 P2P 架构(部分组件如 CP Subsystem 有逻辑主节点,但无物理中心),所有节点(Member)地位平等,可同时作为 “客户端” 和 “服务端”:
- 节点启动后自动加入集群,无需依赖外部注册中心(也支持集成 K8s、Consul 等第三方注册中心);
- 集群内节点通过协议同步状态(如成员列表、分区信息),任意节点故障不影响集群整体可用性(只要副本节点存活);
- 客户端(Client)可连接任意节点,节点会自动路由请求到目标数据所在节点(无需客户端感知数据分布)。
二、核心模块 1:集群发现与成员管理(Gossip 协议)
集群的 “成员感知” 是分布式能力的基础,Hazelcast 通过 Gossip 协议实现成员状态同步,底层分两步:节点发现 和 成员状态维护。
1. 节点发现:如何找到集群中的其他节点?
Hazelcast 支持多种发现机制,适配不同部署环境,底层逻辑是 “让新节点感知已有集群的 IP / 端口”:
发现机制 | 底层原理 | 适用场景 |
---|---|---|
多播(Multicast) | 新节点发送多播数据包(默认端口 54327),集群内已有节点接收后回复自身地址 | 小规模集群、同网段部署 |
TCP/IP | 配置 “种子节点列表”(已知的集群节点 IP),新节点主动连接种子节点获取集群信息 | 跨网段、大规模集群 |
K8s 集成 | 基于 K8s API 监听 Pod 标签,自动发现同标签下的 Hazelcast 节点 | K8s 容器化部署 |
第三方注册中心 | 集成 Consul/Eureka/ZooKeeper,节点启动后向注册中心注册,通过注册中心获取集群列表 | 混合部署、多集群管理 |
2. 成员状态维护:如何同步 “节点上下线” 信息?
节点加入集群后,通过 Gossip 协议 传播成员状态(在线 / 离线 / 疑似故障),确保所有节点的 “成员列表” 一致:
- Gossip 核心逻辑:每个节点周期性(默认 1 秒)随机选择 1-2 个其他节点,交换 “成员状态列表”(包含节点 UUID、IP、状态、最后心跳时间);
- 状态扩散:通过 “随机转发” 实现状态的快速扩散(O (logN) 时间复杂度),避免单节点通信压力;
- 成员标识:每个节点有唯一
UUID
(启动时生成),作为集群内的唯一身份标识,避免 IP 变更导致的身份混乱。
三、核心模块 2:分布式数据存储(分区 + 副本机制)
Hazelcast 的核心价值是 “分布式数据结构”(如 IMap
、ICache
),底层通过 “分区(Partition)+ 副本(Replica)” 实现数据的分布式存储与高可用,本质是 “将数据拆分到不同节点,同时备份多份避免丢失”。
1. 数据分区:如何拆分数据到集群节点?
Hazelcast 对所有分布式数据结构(如 IMap
)采用 哈希分区策略,具体步骤:
- 固定分区数:默认将数据划分为 271 个分区(质数,确保哈希分布更均匀,可通过
hazelcast.partition.count
配置); - 分区计算:对数据的 “键(Key)” 进行哈希(默认用
MurmurHash3
),然后对 “分区数” 取模,得到该 Key 所属的 分区 ID(如partitionId = MurmurHash3(key) % 271
); - 分区分配:集群启动时,通过 “一致性哈希” 将 271 个分区均匀分配给所有节点(每个节点负责~271/N 个分区,N 为节点数);
- 分区分配结果会同步给所有节点,形成 “分区 - 节点映射表”(Partition Table),客户端也会缓存该表,实现请求的直接路由。
2. 副本机制:如何保证数据不丢失?
为避免节点故障导致数据丢失,Hazelcast 为每个分区设置 多份副本,分为 “主分区(Primary Partition)” 和 “备份分区(Backup Partition)”:
- 副本配置:默认 1 个备份(可通过
backup-count
配置,如backup-count: 2
表示 2 个备份); - 副本存储规则:主分区和备份分区必须存储在 不同节点(且尽量跨机架,通过
zone-aware
配置实现),避免单点故障; - 读写流程:
- 写入(Put):客户端将请求路由到主分区所在节点 → 主节点写入数据 → 同步(默认同步,可配置异步)到所有备份节点 → 确认写入成功;
- 读取(Get):默认路由到主分区节点读取(保证最新),也可配置
read-from-backup: true
从备份节点读取,降低主节点压力;
- 副本升级:若主分区所在节点故障,Hazelcast 会自动将 “备份分区” 升级为新的主分区,同时重新创建新的备份分区(确保副本数不变)。
四、核心模块 3:一致性协议(AP/CP 双模式支持)
分布式系统的核心挑战是 “一致性”,Hazelcast 提供两种一致性模式,适配不同业务场景:
1. 默认模式:AP 最终一致性(满足高可用、分区容错)
Hazelcast 早期版本仅支持 AP 模式(符合 CAP 理论,优先保证 Availability 和 Partition Tolerance),底层通过 “分区复制 + Gossip 同步” 实现最终一致性:
- 数据写入时,主分区成功写入并同步到备份分区后即返回,无需等待所有节点确认;
- 集群网络分区时,各分区仍可独立提供读写服务(分区内主备正常),分区恢复后通过 Gossip 同步数据,最终达到全集群一致;
- 适用场景:非强一致性需求的业务(如缓存、会话存储、实时计算中间结果)。
2. CP 模式:强一致性(满足原子性、一致性)
Hazelcast 3.10+ 引入 CP Subsystem(CP 集群),通过 Raft 协议 实现强一致性,用于需要原子操作的场景(如分布式锁 ILock
、分布式计数器 ICountDownLatch
):
- CP 集群架构:从整体集群中划分出一个 “CP 子集”(默认 3/5 个节点,奇数个节点确保 Raft 选举),每个 CP 子集独立运行 Raft 协议;
- Raft 协议核心逻辑:
- Leader 选举:CP 子集启动时,节点通过投票选举出一个 Leader,其余为 Follower;Leader 负责处理所有写请求,Follower 被动同步 Leader 的日志;
- 日志复制:Leader 接收写请求后,将操作记录为 “日志条目”,同步到所有 Follower;当多数 Follower(如 3 节点集群中 ≥2 个)确认日志后,Leader 提交日志并执行操作,然后向客户端返回成功;
- 故障恢复:Leader 故障后,Follower 超时未收到心跳会转为 Candidate,重新发起选举,确保 CP 子集始终有可用 Leader;
- 适用场景:强一致性需求的业务(如分布式锁、分布式事务、全局唯一 ID)。
五、核心模块 4:通信机制(Netty 高性能 NIO)
集群节点间、客户端与节点间的通信,底层基于 Netty 框架(高性能异步 NIO 框架)实现,确保低延迟、高并发:
- 通信模型:采用 TCP 长连接,节点间建立固定连接池(避免频繁创建 / 销毁连接的开销),客户端与节点间默认 1 个长连接(可配置连接数);
- 协议设计:自定义 二进制协议(Hazelcast Protocol),相比 HTTP/JSON 等文本协议,二进制协议体积更小、解析更快,支持 “请求 - 响应”“单向通知”“批量传输” 等模式;
- 异步通信:核心操作(如数据读写、集群状态同步)均采用异步 I/O,避免线程阻塞,提升吞吐量;
- 压缩与加密:支持对传输数据进行压缩(如 GZIP、LZ4),减少网络带宽占用;同时支持 TLS/SSL 加密,保障数据传输安全。
六、核心模块 5:序列化(高效数据传输与存储)
分布式环境中,数据需在节点间传输或持久化(如持久化到磁盘),序列化效率直接影响性能,Hazelcast 自研 Hazelcast Serialization Framework,解决 Java 原生 Serializable
效率低的问题:
- 核心优势:
- 无反射开销:通过预生成序列化代码(如
Portable
接口)或注解(@Serializable
),避免 Java 反射的性能损耗; - 类型紧凑:存储数据时仅保留必要的类型信息(如用 1 字节标识类型),而非完整类名,减少数据体积;
- 扩展性:支持自定义序列化器(如集成 Kryo、Jackson、Protobuf),适配不同数据格式(如 JSON、Avro);
- 无反射开销:通过预生成序列化代码(如
- 常用序列化方式:
序列化方式 适用场景 特点 Portable 自定义 POJO 类 支持部分反序列化(只反序列化需要的字段) IdentifiedDataSerializable 框架内置数据结构(如 IMap
键值对)需实现接口,性能最优 Kryo 第三方类、复杂对象 兼容性强,序列化速度快 Jackson JSON 格式数据 适合与外部系统交互
七、核心模块 6:故障检测与恢复
分布式系统中节点故障不可避免,Hazelcast 通过 “心跳检测 + 分区迁移 + 故障恢复” 确保集群稳定运行:
1. 故障检测:如何发现故障节点?
采用 双层检测机制,避免 “误判故障”(如网络抖动导致的短暂失联):
- 心跳检测:节点间每 1 秒发送一次心跳包(默认超时时间 30 秒),若超时未收到心跳,标记节点为 “疑似故障(Suspect)”;
- Gossip 确认:疑似故障状态通过 Gossip 协议扩散到其他节点,若多数节点(如 ≥50%)均未收到该节点的心跳,才正式标记为 “故障(Dead)”。
2. 故障恢复:故障后如何恢复服务?
节点故障后,核心是恢复故障节点负责的分区和服务,流程如下:
- 分区迁移:故障节点的主分区,由其备份分区自动升级为新主分区;同时,集群重新分配新的备份分区(从其他节点复制数据),确保副本数不变;
- 服务迁移:若故障节点是 CP Subsystem 的 Leader,CP 子集通过 Raft 重新选举 Leader;若故障节点是客户端连接的节点,客户端会自动重试连接其他节点(基于缓存的分区表,重新路由请求);
- 数据恢复:若启用了持久化(如
MapStore
持久化到数据库、Hot Restart
持久化到磁盘),节点重启后会从持久化存储中恢复数据,再加入集群同步最新状态。
总结:Hazelcast 底层原理核心逻辑
Hazelcast 本质是通过 “内存聚合 + 分布式协议 + 高性能通信”,将多个独立节点伪装成 “一个大内存集群”:
- 集群层面:用 Gossip 协议维护成员状态,P2P 架构保证无单点故障;
- 数据层面:用 “分区 + 副本” 实现分布式存储,AP/CP 双模式适配不同一致性需求;
- 性能层面:用 Netty 通信、高效序列化、异步 I/O 降低延迟、提升吞吐量;
- 可靠性层面:用心跳检测 + Raft 协议 + 分区迁移,确保故障后服务不中断、数据不丢失。
这种设计让 Hazelcast 既能作为 “分布式缓存” 提升读取性能,也能作为 “分布式计算平台”(如 Hazelcast Jet)处理实时数据,广泛应用于微服务、大数据、实时风控等场景。