面对海量数据的索引管理,你是否感到无从下手?索引压缩如何操作?滚动索引怎样配置?ILM生命周期管理如何实现自动化?本文将全面讲解Elasticsearch索引管理的核心技术,包括常用API 、索引压缩 、索引别名 、滚动索引 、索引模板 、ILM生命周期管理 和数据流,并分享生产环境的避坑经验,助你成为ES索引管理专家!
📋 文章目录
- 一、常用API速查
- [1.1 _cat API](#1.1 _cat API)
- [1.2 _cluster API](#1.2 _cluster API)
- 二、索引压缩(Shrink)
- 三、索引别名(Alias)
- 四、滚动索引(Rollover)
- [五、索引模板(Index Template)](#五、索引模板(Index Template))
- 六、索引生命周期管理(ILM)
- [七、数据流(Data Streams)](#七、数据流(Data Streams))
- 八、避坑指南
一、常用API速查
1.1 _cat API
_cat API提供人性化的集群信息查看方式,适合快速排查问题。
| API | 说明 | 示例 |
|---|---|---|
_cat/nodes |
查询节点分配情况 | GET _cat/nodes?v |
_cat/nodeattrs |
查询节点属性 | GET _cat/nodeattrs |
_cat/shards |
查询分片分配情况 | GET _cat/shards?v |
_cat/allocation |
查看节点磁盘占用 | GET _cat/allocation?v |
_cat/count/<index> |
查看索引文档数量 | GET _cat/count/my_index |
_cat/health |
查看集群健康状态 | GET _cat/health?v |
_cat/indices |
查看索引列表和信息 | GET _cat/indices?v |
_cat/plugins |
查看已安装插件 | GET _cat/plugins |
_cat/templates |
查看索引模板 | GET _cat/templates |
常用示例:
bash
# 查看所有索引(带表头)
GET _cat/indices?v
# 查看索引文档数并按大小排序
GET _cat/indices?v&s=store.size:desc
# 查看集群健康状态
GET _cat/health?v
1.2 _cluster API
_cluster API提供集群级别的管理和监控。
| API | 说明 |
|---|---|
_cluster/allocation/explain |
查看分片分配详情,排查未分配原因 |
_cluster/health |
集群健康状态 |
_cluster/state |
集群状态元数据 |
_cluster/stats |
集群统计信息(_cat API的汇总) |
分片分配排查示例:
bash
# 查看某个分片为什么未分配
GET _cluster/allocation/explain
{
"index": "my_index",
"shard": 0,
"primary": true
}
二、索引压缩(Shrink)
2.1 什么是索引压缩?
索引压缩(Shrink)是通过减少分片数量来优化索引的过程,生成新索引而非在原有索引上压缩。
原理:
- 创建新目标索引,定义与源索引相同但分片更少
- 将段从源索引硬链接到目标索引
- 恢复目标索引
使用场景:
- 历史数据不再写入,需要减少分片数
- 优化存储和查询性能
2.2 前提条件
- 源索引必须是只读状态
- 所有主分片必须在同一节点
- 索引健康状态必须为 green
- 目标索引不能已存在
- 目标分片数必须是源分片数的约数(如源12分片,目标可以是6/4/3/2/1)
- 文档数不能超过 2,147,483,519(单分片最大限制)
- 目标节点必须有足够磁盘空间
2.3 操作步骤
步骤1:备份数据(可选但推荐)
bash
POST _reindex
{
"source": {
"index": "source_index"
},
"dest": {
"index": "target_index_backup"
}
}
步骤2:删除副本(可选)
bash
PUT source_index/_settings
{
"index.number_of_replicas": 0
}
步骤3:设置只读
bash
# 设置索引为只读
PUT source_index/_settings
{
"index.blocks.write": true
}
其他阻塞选项:
index.blocks.read_only: true- 索引和元数据只读index.blocks.read: true- 禁止读操作index.blocks.write: true- 禁止写操作
步骤4:迁移数据到同一节点
bash
PUT source_index/_settings
{
"index.routing.allocation.require._name": "target_node_name"
}
等待分片分配完成,确保健康状态为green
步骤5:执行压缩
bash
POST /source_index/_shrink/target_index
{
"settings": {
"index.number_of_replicas": 1,
"index.number_of_shards": 3,
"index.codec": "best_compression"
}
}
步骤6:恢复索引(可选)
bash
PUT target_index/_settings
{
"index.routing.allocation.require._name": null,
"index.blocks.write": false
}
三、索引别名(Alias)
3.1 什么是索引别名?
索引别名是用于引用一个或多个现有索引的辅助名称,大多数ES API都支持使用别名代替索引名。
作用:
- 保护索引:真实索引名对调用者隐藏
- 无缝切换:重建索引时可以零停机切换
- 过滤路由:搜索时自动应用过滤器
3.2 基本用法
添加别名
bash
POST /_aliases
{
"actions": [
{
"add": {
"index": "product",
"alias": "product_template"
}
}
]
}
移除并添加别名(原子操作)
bash
POST /_aliases
{
"actions": [
{ "remove": { "index": "product", "alias": "product_template" } },
{ "add": { "index": "product", "alias": "product_real" } }
]
}
一个别名绑定多个索引
bash
POST /_aliases
{
"actions": [
{ "add": { "index": "product", "alias": "product_real2" } },
{ "add": { "index": "product2", "alias": "product_real2" } }
]
}
带过滤器的别名
bash
PUT /test
{
"aliases": {
"alias_1": {},
"alias_2": {
"filter": {
"term": { "user.id": "kimchy" }
}
}
}
}
3.3 使用场景
零停机重建索引:
bash
# 1. 创建新索引
PUT product_v2
# 2. 将数据从旧索引导入新索引
POST _reindex
{
"source": { "index": "product_v1" },
"dest": { "index": "product_v2" }
}
# 3. 原子切换别名
POST /_aliases
{
"actions": [
{ "remove": { "index": "product_v1", "alias": "product" } },
{ "add": { "index": "product_v2", "alias": "product" } }
]
}
# 4. 删除旧索引
DELETE product_v1
四、滚动索引(Rollover)
4.1 什么是滚动索引?
滚动索引在满足指定条件时自动创建新索引,常用于日志、时序数据等场景。
4.2 触发条件
- max_age:索引达到指定时间(如7天)
- max_docs:文档数达到指定数量(如100万)
- max_size:索引大小达到指定值(如5GB)
4.3 使用步骤
步骤1:创建索引并设置别名
bash
PUT /my_logs-000001
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "english"
}
}
},
"aliases": {
"logs_write": {} // 写入别名
}
}
步骤2:写入数据
bash
PUT logs_write/_bulk
{"index":{}}
{"title":"test data 1"}
{"index":{}}
{"title":"test data 2"}
步骤3:执行滚动
bash
# logs_write必须是别名
POST /logs_write/_rollover
{
"conditions": {
"max_age": "7d",
"max_docs": 1000000,
"max_size": "5gb"
}
}
执行结果:
- 如果任一条件满足,创建新索引
my_logs-000002 - 别名
logs_write指向新索引 - 旧索引保持不变,可继续查询
五、索引模板(Index Template)
5.1 什么是索引模板?
索引模板是告诉Elasticsearch在创建索引时如何配置索引的方法。常用于配合滚动索引、ILM、数据流一起使用。
5.2 基本用法
bash
PUT /index_a
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "english"
}
}
}
}
# 复制索引结构
POST _reindex
{
"source": {
"index": "index_a"
},
"dest": {
"index": "index_b"
}
}
5.3 索引模板(v2版本)
bash
PUT _index_template/my_template
{
"index_patterns": ["test_ilm_index_*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"index.lifecycle.name": "test_ilm"
}
}
}
六、索引生命周期管理(ILM)
6.1 什么是ILM?
ILM(Index Lifecycle Management)自动管理索引,根据性能、可伸缩性和保留要求执行操作。
典型场景:
- 索引达到特定大小或文档数时启动新索引
- 每天/每周/每月创建新索引并归档旧索引
- 删除过时的索引执行数据保留标准
6.2 生命周期阶段
| 阶段 | 说明 |
|---|---|
| Hot | 索引正在活跃更新和查询 |
| Warm | 不再更新但仍被查询 |
| Cold | 不再更新,查询很少,允许较慢响应 |
| Frozen | 极少查询,允许极慢响应 |
| Delete | 索引不再需要,安全删除 |
6.3 各阶段支持的操作
Hot Phase:
- Set Priority、Unfollow、Rollover、Read-Only、Shrink、Force Merge、Searchable Snapshot
Warm Phase:
- Set Priority、Unfollow、Read-Only、Allocate、Migrate、Shrink、Force Merge
Cold Phase:
- Set Priority、Unfollow、Read-Only、Searchable Snapshot、Allocate、Migrate、Freeze
Frozen Phase:
- Searchable Snapshot
Delete Phase:
- Wait For Snapshot、Delete
6.4 ILM配置示例
步骤1:创建ILM策略
bash
PUT _ilm/policy/test_ilm
{
"policy": {
"phases": {
"hot": {
"actions": {
"set_priority": {
"priority": 100
}
}
},
"warm": {
"min_age": "10s",
"actions": {
"set_priority": {
"priority": 50
}
}
},
"cold": {
"min_age": "20s",
"actions": {
"set_priority": {
"priority": 0
}
}
},
"delete": {
"min_age": "30s",
"actions": {
"delete": {
"delete_searchable_snapshot": true
}
}
}
}
}
}
步骤2:创建索引模板引用ILM
bash
PUT _index_template/my_template
{
"index_patterns": ["test_ilm_index_*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"index.lifecycle.name": "test_ilm"
}
}
}
步骤3:创建索引使用模板
bash
PUT test_ilm_index_000001
{
"aliases": {
"test-alias": {
"is_write_index": true
}
}
}
七、数据流(Data Streams)
7.1 什么是数据流?
数据流是管理时序数据的抽象概念,适合日志、指标等追加型数据,自动管理索引创建和生命周期。
7.2 数据流使用步骤
步骤1:创建ILM策略(必须)
bash
PUT _ilm/policy/test_ilm
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_primary_shard_size": "50mb",
"max_age": "30m",
"max_docs": 2
},
"set_priority": {
"priority": 100
}
}
},
"warm": {
"min_age": "5s",
"actions": {
"set_priority": {
"priority": 50
},
"allocate": {
"require": {
"hot_warm_cold": "warm"
}
}
}
},
"cold": {
"min_age": "15s",
"actions": {
"set_priority": {
"priority": 0
},
"allocate": {
"require": {
"hot_warm_cold": "cold"
}
}
}
},
"delete": {
"min_age": "20s",
"actions": {
"delete": {
"delete_searchable_snapshot": true
}
}
}
}
}
}
步骤2:创建组件模板
bash
# 映射组件模板
PUT _component_template/my-mappings
{
"template": {
"mappings": {
"properties": {
"@timestamp": {
"type": "date",
"format": "date_optional_time||epoch_millis"
},
"message": {
"type": "wildcard"
}
}
}
}
}
# 设置组件模板
PUT _component_template/my-settings
{
"template": {
"settings": {
"index.lifecycle.name": "test_ilm",
"number_of_replicas": 0
}
}
}
步骤3:创建索引模板
bash
PUT _index_template/my-index-template
{
"index_patterns": ["my-data-stream*"],
"data_stream": {},
"composed_of": ["my-mappings", "my-settings"],
"priority": 500
}
步骤4:创建数据流
方式一:写入数据自动创建
bash
PUT my-data-stream_1/_bulk
{ "create": {} }
{ "@timestamp": "2099-05-06T16:21:15.000Z", "message": "192.0.2.42 - - [06/May/2099:16:21:15 +0000] \"GET /images/bg.jpg HTTP/1.0\" 200 24736" }
{ "create": {} }
{ "@timestamp": "2099-05-06T16:25:42.000Z", "message": "192.0.2.255 - - [06/May/2099:16:25:42 +0000] \"GET /favicon.ico HTTP/1.0\" 200 3638" }
方式二:使用_data_stream API
bash
PUT _data_stream/my-data-stream
八、避坑指南
8.1 Rollover与ILM时间关系
坑点:配置了Rollover时,ILM阶段的min_age计时受Rollover影响。
规则:
- 未配置Rollover:Hot→Warm的流转仅取决于Warm的min_age
- 配置了Rollover:必须等待Rollover触发后,min_age才开始计时
示例:
json
// Rollover配置
"rollover": {
"max_primary_shard_size": "50gb",
"max_age": "100m",
"max_docs": 5
}
// Warm配置
"warm": {
"min_age": "10s"
}
如果100分钟内Rollover未触发(文档数<5且大小<50GB),则Hot→Warm的实际时间为:100m + 10s
建议:非必要不配置Rollover,避免时间计算错误。
8.2 node.roles配置注意事项
坑点 :显式配置node.roles会"阉割"未配置的角色。
规则:
- 不配置
node.roles:节点拥有所有角色 - 显式配置
node.roles:只拥有配置的角色
过时写法(不要使用):
yaml
node.master: true
node.data: true
正确写法:
yaml
node.roles: [master, data]
单节点集群必须同时配置:
yaml
node.roles: [master, data] # 或 data_content
8.3 data_content角色的理解
坑点 :配置了data_hot/data_warm/data_cold,还需要配置data_content。
关系图:
data
├── data_content (内容数据,基础角色)
├── data_hot (热数据,需配合data_content)
├── data_warm (温数据,需配合data_content)
└── data_cold (冷数据,需配合data_content)
正确配置示例:
yaml
# Hot节点
node.roles: [master, data_hot, data_content]
# Warm节点
node.roles: [data_warm, data_content]
# Cold节点
node.roles: [data_cold, data_content]
8.4 索引压缩注意事项
- 分片数必须是约数:源索引12分片,目标只能是6/4/3/2/1
- 质数分片只能压缩到1分片:如源索引11分片,目标只能是1分片
- 文档数限制:单分片最大2,147,483,519个文档
- 磁盘空间:目标节点必须有足够空间
总结
本文全面介绍了Elasticsearch索引管理的核心技术:
| 功能 | 使用场景 |
|---|---|
| _cat/_cluster API | 日常监控和问题排查 |
| 索引压缩(Shrink) | 减少历史索引分片数 |
| 索引别名(Alias) | 零停机重建索引、路由过滤 |
| 滚动索引(Rollover) | 自动创建新索引(日志场景) |
| 索引模板 | 统一索引配置 |
| ILM生命周期管理 | 自动化数据生命周期管理 |
| 数据流 | 时序数据管理(日志、指标) |
掌握这些技术,可以高效管理大规模ES集群,降低运维成本。
关键词:Elasticsearch, ES索引管理, 索引压缩, 索引别名, 滚动索引, ILM生命周期管理, 数据流, Rollover, Shrink, 索引模板
如果本文对你有帮助,欢迎点赞、收藏、关注!有任何ES索引管理问题,欢迎在评论区留言讨论。