ES的写入流程是什么样的?
ES 写入流程概述
- 定义:
- ES 的写入流程是将文档(如 JSON)索引到分片的过程,涉及分片分配、数据存储和同步。
- 核心步骤:
- 协调节点接收请求并路由。
- 主分片写入数据。
- 副本分片同步写入。
- 确认返回结果。
问题解答
- 发请求首先是发到哪个节点上的?
- 发到任意节点(通常是协调节点),由其路由到正确的主分片所在节点。
- 写请求都会到主节点上吗?
- 写请求不直接到主节点(Master Node),而是到主分片所在的数据节点,主节点仅管理元数据。
- 只要写一个主分片成功后,请求就结束了吗?
- 否,默认需等待所有副本分片写入成功(可配置)。
- 副本分片是否需要保证完全写入?
- 默认需全部副本写入,但可通过
write_consistency
或wait_for_active_shards
调整。 - ES 是最终一致性还是强一致性?
- ES 是最终一致性,写入后近实时(NRT)可见,副本同步可能有短暂延迟。
核心点
- ES 写入依赖协调节点路由、主分片优先、副本同步,默认追求一致性但允许配置灵活性。
1. ES 写入流程详解
步骤分解
- 协调节点接收请求:
- 客户端发送写请求(如
PUT /index/_doc/1
)到任意 ES 节点。 -
该节点作为协调节点,解析请求。
-
路由到主分片:
- 协调节点根据文档
_id
或路由规则(如routing
参数)计算分片:- 公式:
shard = hash(_id) % number_of_primary_shards
。
- 公式:
-
请求转发到主分片所在的数据节点。
-
主分片写入:
-
主分片节点执行:
- 验证:检查文档格式、映射。
- 索引:写入内存 Buffer 和 Translog(事务日志)。
- Lucene Segment:数据暂存内存。
-
副本分片同步:
- 主分片将请求并行转发到所有副本分片。
- 副本执行相同写入(Buffer + Translog)。
-
默认需所有副本确认成功。
-
确认返回:
- 主分片收集副本响应,通知协调节点。
-
协调节点返回客户端成功(HTTP 200)或失败。
-
刷新(Refresh):
- 内存 Buffer 定期(默认 1 秒)生成 Lucene Segment,数据可搜索(近实时)。
- Translog 持久化,保障可靠性。
图示
客户端 --> [协调节点] --> [主分片] --> [副本 1, 副本 2]
| |
v v
[Buffer] [Translog]
| |
v v
[Segment] [磁盘持久化]
2. 问题逐一解答
(1) 发请求首先是发到哪个节点上的?
- 答:
- 请求发到集群中任意节点(通常客户端通过负载均衡器访问)。
- 该节点作为协调节点,负责:
- 解析请求。
- 计算分片位置。
- 转发到主分片所在节点。
- 示例:
curl -X PUT "http://node1:9200/users/_doc/1" -d '{"name":"Alice"}'
node1
是协调节点,路由到主分片。
(2) 写请求都会到主节点上吗?
- 答:
- 不会。写请求到主分片所在的数据节点,而非主节点(Master Node)。
- 主节点作用:
- 管理集群元数据(如创建索引、分片分配)。
- 不直接处理数据写入。
- 区分:
- 主节点:集群管理。
- 主分片:数据写入入口。
- 示例:
- 写
users/_doc/1
,协调节点路由到主分片(可能在node2
),主节点不参与。
(3) 只要写一个主分片成功后,请求就结束了吗?
- 答:
- 默认不会。ES 默认要求主分片和所有副本分片都写入成功后才返回成功。
- 配置参数:
wait_for_active_shards
:- 默认:所有主分片和副本(
all
)。 - 可设为
1
(仅主分片),加速响应但牺牲一致性。
- 流程:
- 主分片写成功后,异步同步副本。
- 收集副本确认后,返回客户端。
- 示例:
PUT /users/_doc/1?wait_for_active_shards=1
{
"name": "Alice"
}
- 仅主分片成功即返回。
(4) 副本分片是否需要保证完全写入?
- 答:
- 默认需要,但可配置。
- 机制:
- 主分片写成功后,副本并行写入。
- 若副本失败(超时或宕机),请求可能失败。
- 配置灵活性:
wait_for_active_shards
:指定所需成功分片数。- 例:设为
2
,主分片 + 1 副本成功即可。
- 容错:
- 副本失败不影响主分片,主节点稍后重分配副本。
- 示例:
- 1 主分片 + 2 副本,默认需 3 个都成功。
(5) ES 是最终一致性还是强一致性?
- 答:
- ES 是最终一致性。
- 原因:
- 写入主分片后,副本异步同步,可能有短暂延迟(毫秒到秒级)。
- 刷新(Refresh)后数据才可搜索(默认 1 秒)。
- 表现:
- 近实时(NRT):写入后需等待刷新。
- 副本可能落后主分片。
- 强一致性支持:
- 配置
refresh=wait_for
,等待数据可见。 - 例:
- 配置
PUT /users/_doc/1?refresh=wait_for
{
"name": "Alice"
}
- 降低性能,慎用。
- 结论:
- 默认最终一致性,适合高吞吐场景。
3. 写入流程优化
- 批量写入:
- 使用
_bulk
API 减少请求。
POST /_bulk
{ "index": { "_index": "users", "_id": "1" } }
{ "name": "Alice" }
{ "index": { "_index": "users", "_id": "2" } }
{ "name": "Bob" }
- 调整刷新间隔:
- 默认
1s
,可设为30s
提高吞吐:
PUT /users/_settings
{
"index": {
"refresh_interval": "30s"
}
}
- 分片数:
- 平衡主分片和副本数,避免过载。
4. 延伸与面试角度
- 与搜索:
- 写入性能影响搜索实时性。
- 实际应用:
- 日志:高吞吐写入,接受最终一致性。
- 电商:商品索引需快速可见。
- 调试:
_cat/segments
查看 Segment。_cat/shards
检查分片状态。- 面试点:
- 问“流程”时,提协调和分片。
- 问“一致性”时,提最终一致性。
总结
ES 写入流程从协调节点路由到主分片,同步副本后返回,默认需全部分片成功。请求不直接到主节点,仅主分片成功不结束,副本写入可配置。ES 是最终一致性,适合高性能场景。面试时,可提流程或配置优化,展示理解深度。