Appearance
存储原理与Segment
存储架构
┌─────────────────────────────────────────┐
│ ES写入流程 │
├─────────────────────────────────────────┤
│ │
│ 文档 ──→ Buffer ──→ Translog ──┐ │
│ │ │ │
│ │ ─────▼─────┐
│ │ │ refresh │ │
│ │ └─────┬─────┘ │
│ │ │ │
│ │ ┌────▼────┐ │
│ │ │Segment │ │
│ │ │ (.liv) │ │
│ │ └────────┘ │
└─────────────────────────────────────────┘Segment结构
Lucene索引结构
Index
│
├─ _1.fdt (Document数据)
├─ _1.fdx (Document索引)
├─ _1.fnm (Fields信息)
├─ _1.fdt (Term字典)
├─ _1.tip (Term索引)
├─ _1.doc (Posting列表)
├─ _1.pos (位置信息)
├─ _1.pay (载荷信息)
└─ _1.liv (Live文档标记)Segment文件说明
| 文件 | 说明 |
|---|---|
| .fdt | 文档数据 |
| .fdx | 文档索引 |
| .fnm | Fields信息 |
| .fdt | Term字典 |
| .tip | Term索引 |
| .doc | Posting列表 |
| .pos | 位置信息 |
| .pay | 载荷信息 |
| .liv | Live文档标记 |
Segment特点
- 不可变性:Segment生成后不可修改
- 合并机制:后台合并小Segment
- 删除逻辑:.liv标记删除
写入流程
1. 写入Buffer
┌─────────────────────────────────┐
│ 写入流程 │
├─────────────────────────────────┤
│ │
│ 1. 写入Memory Buffer │
│ (同时写入Translog) │
│ │
│ 2. refresh (默认1s) │
│ Buffer → Segment (.liv) │
│ 清空Buffer │
│ │
│ 3. flush (默认30m或512MB) │
│ Segment → 磁盘 │
│ 删除Translog │
│ │
└─────────────────────────────────┘2. Translog
json
// Translog配置
{
"index": {
"translog": {
"sync_interval": "5s",
"size": "512mb",
"durability": "async"
}
}
}| 参数 | 说明 |
|---|---|
| sync_interval | 同步间隔(默认5s) |
| size | Translog大小 |
| durability | 同步模式(request/async) |
3. flush
时机:
- 30分钟
- 512MB
- Translog太大refresh vs flush
| 操作 | 作用 | 开销 |
|---|---|---|
| refresh | 写入Buffer到Segment��可搜索 | 低 |
| flush | 写入Segment到磁盘,清理Translog | 高(I/O) |
删除与更新
删除逻辑
写入时:.liv = [0, 1, 1, 0]
删除doc 2:.liv = [0, 1, 0, 0](标记删除)
合并时:清理.liv=0的文档,真正删除更新逻辑
1. 文档标记为删除(.liv=0)
2. 新文档写入新Segment合并Segment
json
// 手动合并
POST /my_index/_forcemerge
{
"max_num_segments": 1
}
// 定期合并
{
"index": {
"merge": {
"scheduler": {
"max_thread_count": 1
}
}
}
}面试考点
Q: 为什么Segment不可修改?
- 写入优化:顺序写,提高性能
- 方便合并:无需随机删除
- 缓存友好:无需维护更新状态
Q: refresh默认1s能改吗?
json
PUT /my_index/_settings
{
"refresh_interval": "-1" // 关闭
// "refresh_interval": "10s" // 10秒
}Q: 删除的文档占空间吗?
- 查询时跳过(.liv标记)
- 合并时清理
Q: 为什么ES是近实时?
- refresh 1s写入Buffer到Segment
- flush 30m持久化到磁盘
Q: Translog作用?
- 保证数据不丢失
- 恢复未flush的数据
