Elasticsearch 分布式存储与 Raft 算法:你真的分清楚了吗?
Elasticsearch(ES)以天生分布式、横向扩展能力强、高可用著称,但这套能力背后,藏着一套精巧但容易被误解的架构。很多开发者日常使用中,常常混淆"数据存储"与"集群管理"的职责边界。
本文不堆砌概念,而是通过 5 个环环相扣的技术问答,帮你彻底理清 ES 的分布式存储逻辑,以及 Raft 算法在其中到底扮演什么角色——哪些事归它管,哪些事根本不经过它。
1. ES 的数据是如何分布式存储的?
核心逻辑
ES 分布式存储的核心逻辑可以概括为三句话:
通过分片拆分数据,借助路由定位数据,依靠主副分片保障高可用。
三大核心机制
(1)分片(Shard)
- 分片是 ES 底层最小的物理存储单元。
- 创建索引时,数据会被拆成多个分片,分散到集群不同节点上。
- 作用:突破单机存储上限,同时让搜索请求能并行执行,大幅提升吞吐量。
(2)主分片与副本分片
| 类型 | 角色 | 关键职责 |
|---|---|---|
| 主分片(Primary Shard) | 写入的唯一入口 | 所有数据写入必须先经过主分片 |
| 副本分片(Replica Shard) | 主分片的完整拷贝 | 主分片宕机时自动晋升;同时分担读请求,实现负载均衡 |
(3)路由(Routing)机制
写入一条数据时,ES 根据文档的 _id(或自定义路由键)计算目标分片:
text
shard_number = hash(_id) % number_of_primary_shards
完整写入流程(5 步)
| 步骤 | 执行节点 | 动作 |
|---|---|---|
| ① | 协调节点 | 接收客户端请求 |
| ② | 协调节点 | 通过路由公式算出目标主分片,将请求转发给对应的数据节点 |
| ③ | 数据节点 | 在主分片上执行写入操作 |
| ④ | 主分片 | 将数据并行复制给所有副本分片 |
| ⑤ | 协调节点 | 待主分片和必要副本分片均写入成功后,向客户端返回成功响应 |
2. 分布式写入的"部分失败"与幂等性
问题场景
主分片和副本都写入成功了,但结果返回给协调节点时网络断了,怎么办?
- 客户端会收到异常(如 Timeout),误以为写入失败。
- 但集群内部,数据其实已经稳稳落盘。
- 当客户端发起重试时,ES 如何避免数据被重复写入?
解决方案:乐观锁 + 幂等性
ES 为每个文档维护一个 _version 版本号,机制如下:
| 阶段 | 版本号变化 | 处理逻辑 |
|---|---|---|
| 第一次写入 | 1 → 2 | 正常写入,主分片和副本同步更新版本号 |
| 客户端重试 | 仍为 2 | 目标节点发现当前版本已是 2,且重试数据不更新 |
| 幂等判定 | 保持 2,不变为 3 | ES 不会再次物理写入,直接返回成功 |
最终效果:即便网络不稳、客户端多次重试,数据也只被写入一次,保证了最终一致性。
3. Raft 算法在 ES 中的真实角色
常见误区
❌ 很多人误以为 Raft 用于管理主副分片间的数据同步。
这是一个典型误解。
正确认知:控制面与数据面严格分离
| 层面 | 负责算法 | 管理对象 | 职责 |
|---|---|---|---|
| 控制面(元数据) | Raft | Cluster State(集群元数据) | 集群节点、Mapping 配置、分片分配信息等 |
| 数据面(业务数据) | ES 自研主从复制协议 | 文档数据 | 主分片与副本分片间的数据同步 |
为什么 Raft 不负责数据同步?
- 业务数据量可达 PB 级,若走 Raft 的日志复制流程,性能瓶颈极其严重。
- ES 自研的复制协议允许数据直接并行写入各分片,效率远高于 Raft 集中协调。
形象比喻
| 角色 | 对应机构 | 职责 |
|---|---|---|
| Raft | 餐厅"董事会" | 制定规章制度、任命店长(管理元数据) |
| 主从分片复制 | 餐厅"后厨" | 具体炒菜出餐(处理业务数据) |
董事会不需要过问每一道菜具体怎么炒。
4. 新增索引需要经过 Raft 吗?
答案:绝对需要。
新增索引(Create Index)本质上是修改集群元数据的操作。
完整流程(4 步)
| 步骤 | 执行方 | 动作 |
|---|---|---|
| ① | Master 节点 | 计算包含新索引信息的新集群状态 |
| ② | Master 节点(通过 Raft) | 将"元数据变更"作为日志,复制同步给候选主节点 |
| ③ | 半数以上节点确认后 | Master 正式提交新集群状态,广播给全集群 |
| ④ | 各数据节点 | 收到最新 Cluster State 后,在本地为新分片分配资源 |
判断标准
| 操作类型 | 是否经过 Raft | 示例 |
|---|---|---|
| 改变"集群指挥图" | ✅ 必须经过 | 创建/删除索引、修改副本数、节点上下线 |
| 写入文档数据 | ❌ 不经过 | 向已存在的索引中写入文档 |
5. 总结:Raft 是主从模式吗?
是的,Raft 本身是主从模式
Raft 的核心运行机制确实是主从模式(Leader & Follower):
| 特征 | 说明 |
|---|---|
| 绝对的主从 | 同一时刻只有一个 Leader,所有元数据变更必须交由 Leader 处理 |
| 日志复制 | Leader 将变更写成日志(Log),同步复制给 Follower |
| 故障重选 | Leader 挂掉后,Follower 触发新一轮选举产生新 Leader |
但在 ES 中,这是两套并行的"主从模式"
| 套数 | 负责算法 | 同步内容 | 类比 |
|---|---|---|---|
| 第一套 | Raft | 元数据指令日志(Cluster State) | 管"户口本" |
| 第二套 | ES 自研复制协议 | 真实的文档数据 | 管"货物" |
最终结论
两者各司其职,互不干扰,共同撑起了 Elasticsearch 强大而稳定的分布式能力。
评论
欢迎留下反馈,评论发布后会立即显示。