场景
- 在初期设计es索引文档的时候考虑不是很周全,会多出很多无效字段。如果不删除或禁用对后续数据增量以及文档维护会有不良影响。
- 实体类定义的字段数量和es索引上定义的数量不一致
技术实现
1.查看当前所有索引
GET /*索引名称*
2.定义新索引脚本
PUT /索引名称
{
"mappings": {
"properties": {
"字段名": {
"type": "字段类型"
}
}
}
}
3.执行Reindex
# 复制旧索引数据到新索引
POST _reindex
{
"source": {
"index": "old_index_name"
},
"dest": {
"index": "new_index_name"
}
}
优化参数
POST _reindex?wait_for_completion=false # 异步执行
{
"source": {
"index": "old_index_name",
"size": 1000 # 分批处理(默认 1000)
},
"dest": {
"index": "new_index_name",
"op_type": "create" # 防止覆盖已存在文档
},
"script": {
"source": "ctx._source.remove('待删除的字段')" #移除要删除的字段
},
"conflicts": "proceed" #版本冲突照样进行
}
如果数据量特别巨大,最好安排在访问量没这么高的时刻进行。否则会影响用户使用体验
4.查看新索引迁移数据后的数量
GET /新索引/_count
4.设置索引为 strict 模式
防止程序自动添加字段,必须通过dsl语句添加
PUT /索引名称/_mapping
{
"dynamic": "true"
}
5.更新索引别名
# 创建别名
# 方式一
POST /_aliases
{
"actions": [
{
"add": {
"index": "new_index_name",
"alias": "index_alias"
}
}
]
}
# 方式二
POST /_aliases
{
"actions": [
{ "remove": { "index": "旧索引", "alias": "索引别名" } },
{ "add": { "index": "新索引", "alias": "索引别名" } }
]
}
# 验证别名
GET /_cat/aliases
6.删除旧索引
DELETE /old_index_name
风险
一.数据一致性风险
1.源索引写入冲突
-
场景:重建过程中源索引持续写入新数据,导致新旧索引数据不一致
-
解决方案
-
全量+增量迁移
# 1. 全量迁移 POST _reindex { "source": { "index": "old_index" }, "dest": { "index": "new_index" } } # 2. 增量迁移(假设存在时间字段 @timestamp) POST _reindex { "source": { "index": "old_index", "query": { "range": { "@timestamp": { "gte": "now-10m" # 同步最近10分钟的数据 } } } }, "dest": { "index": "new_index" } }
-
使用别名切换
# 1. 创建临时别名指向旧索引 POST /_aliases { "actions": [ { "add": { "index": "old_index", "alias": "temp_alias" } } ] } # 2. 重建索引后切换别名 POST /_aliases { "actions": [ { "remove": { "index": "old_index", "alias": "temp_alias" } }, { "add": { "index": "new_index", "alias": "temp_alias" } } ] }
-
2.字段类型冲突
-
场景:源索引目标索引的字段类型不匹配(如源为
text
,目标为keyword
) -
解决方案
# 1. 提前创建目标索引并指定映射 PUT /new_index { "mappings": { "properties": { "field1": { "type": "keyword" } } } } # 2. 执行 Reindex 时忽略冲突 POST _reindex { "source": { "index": "old_index" }, "dest": { "index": "new_index" }, "conflicts": "proceed" }
二.性能与资源风险
1.集群负载过高
-
重建大索引(如 TB 级) 导致 CPU/内存 使用率飙升,影响其他业务
-
解决方案:
- 分批次处理
POST _reindex?wait_for_completion=false&slice=0&num_slices=5 { "source": { "index": "old_index", "size": 10000 }, "dest": { "index": "new_index" } }
- 降低副本数
PUT /new_index/_settings { "number_of_replicas": 0 }
2.磁盘空间不足
- 场景:重建索引导致磁盘使用率超过85%,触发 es 限流
三.案例
-
reindex任务中途失败
-
源索引与目标索引的文档数量相同,但部分字段值不同
总结
通过以下策略可有效降低风险:
- 分阶段操作:全量迁移 > 增量同步 > 别名切换
- 资源隔离:使用专有节点或临时扩容集群
- 自动化验证:通过脚本对比源与目标索引的数据哈希值
- 灰度发布:先重建部分索引(如 10% 数据),验证无误后再全量执行