Appearance
分片与副本
分片机制
主分片
- 索引数据的物理存储单元
- 索引创建时确定数量,后续不可改
- 决定数据分布:
_shard = hash(_routing) % number_of_shards
┌─────────────────────────────────────────┐
│ Index │
├─────────────────────────────────────────┤
│ Product Index (5主分片) │
├─────────────────────────────────────────┤
│ Shard 0 │ Shard 1 │ Shard 2 │ ... │
│ [0-1000] │[1001..] │ │ │
└─────────────────────────────────────────┘副本分片
- 主分片的完整拷贝
- 提供数据冗余和查询能力
- 可以动态调整数量
┌─────────────────────────────────────────┐
│ Shard 副本 │
├─────────────────────────────────────────┤
│ │
│ Primary ────┬──→ Replica 1 │
│ (主分片) │ │
│ └──→ Replica 2 │
│ │
│ 主分片坏 → 自动提升副本为主分片 │
└─────────────────────────────────────────┘分片分配
分配策略
| 配置 | 说明 |
|---|---|
index.number_of_shards | 主分片数,默认1 |
index.number_of_replicas | 副本数,默认1 |
index.routing_allocation | 分片分配感知 |
分配规则
json
PUT /my_index
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2
}
}分配感知
yaml
# node.attr配置
node.attr.rack_id: rack1
# 索引配置
{
"settings": {
"index.routing.allocation.include.rack_id": "rack1,rack2"
}
}数据读写流程
写操作流程
┌─→ Segment 1 ──→ Segment N
Client ─→ Coordinating ──┤
└─→ Translog(持久化保证)- 请求发送到协调节点
- 路由到主分片所在节点
- 主分片执行索引操作
- 并行复制到副本分片
- 等待副本确认(可选)
- 返回客户端
写一致性参数
| 参数 | 说明 |
|---|---|
consistency: all | 必须所有分片写入成功 |
consistency: quorum | 大多数分片成功(默认) |
consistency: one | 主分片成功即可 |
读操作流程
┌─→ Primary Shard
Query ─→ 协调节点 ────┤
└─→ Replica Shard- 协调节点解析查询
- 转发到相关分片(主或副本)
- 各分片独立执行查询
- 协调节点合并结果
- 返回客户端
并行读
- 主分片和副本分片都可响应查询
- 分散查询压力
- 提升QPS
面试考点
Q: 分片数确定考虑什么?
- 数据量:越大需要更多分片
- 节点数:通常 ≤ 节点数 × 分片数
- 查询并发:高并发需要更多分片
Q: 主分片数可以改吗?
❌ 不能,只能重建索引
Q: 副本分片数可以改吗?
✅ 可以动态调整:
json
PUT /my_index/_settings
{
"number_of_replicas": 2
}Q: 为什么yellow?
- 主分片正常,副本分片未分配
- 通常是节点数不足
