说明
下面是一个完整、可操作的 Elasticsearch 7.2 同集群内索引重组迁移示例,包含:
- ✅ 创建源索引(带旧结构)
- ✅ 插入测试数据
- ✅ 创建目标索引(带新结构)
- ✅ 执行 _reindex 迁移
- ✅ 验证数据 & 切换别名
- ✅ 清理旧索引
所有命令均可在单节点 ES 7.2 环境(如开发机或测试集群)直接运行。
环境准备
- Elasticsearch 7.2 已启动(默认端口 9200)
- 启用安全认证(如你之前使用 -u elastic:pass)
- 假设密码为:fC3!eG5#iF,若未启用安全,去掉 -u elastic:... 即可
🔹 步骤 1:创建源索引(旧结构)
xml
curl -u elastic:'fC3!eG5#iF' -X PUT "http://localhost:9200/logs-old" \
-H 'Content-Type: application/json' -d '
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"message": { "type": "text" },
"level": { "type": "text" }, // ❌ 错误:假设现在设置为text,实际应为 keyword
"timestamp": { "type": "date" }
}
}
}'
📌 问题:level 字段用 text 类型,无法用于精确聚合/过滤 → 重组需要改成 keyword
🔹 步骤 2:插入测试数据
插入数据
插入测试数据
xml
for i in {1..3}; do curl -u elastic:'fC3!eG5#iF' -X POST "http://localhost:9200/logs-old/_doc" -H 'Content-Type: application/json' -d '
{
"message": "Test log message '"$i"'",
"level": "INFO",
"timestamp": "2025-03-18T10:00:0'"$i"'Z"
}'; done
再插入 2 条 ERROR 日志
xml
curl -u elastic:'fC3!eG5#iF' -X POST "http://localhost:9200/logs-old/_doc" \
-H 'Content-Type: application/json' -d '
{
"message": "Database connection failed",
"level": "ERROR",
"timestamp": "2025-03-18T10:00:10Z"
}'
curl -u elastic:'fC3!eG5#iF' -X POST "http://localhost:9200/logs-old/_doc" \
-H 'Content-Type: application/json' -d '
{
"message": "Disk full",
"level": "ERROR",
"timestamp": "2025-03-18T10:00:11Z"
}'
验证数据:
xml
curl -u elastic:'fC3!eG5#iF' "http://localhost:9200/logs-old/_count"
# 应返回:{"count":5,"_shards":{"total":3,"successful":3,"skipped":0,"failed":0}}
创建目标索引(新结构)
xml
curl -u elastic:'fC3!eG5#iF' -X PUT "http://localhost:9200/logs-new" \
-H 'Content-Type: application/json' -d '
{
"settings": {
"number_of_shards": 2, // 减少分片数(从 3 → 2)
"number_of_replicas": 1,
"refresh_interval": "30s" // 优化写入性能
},
"mappings": {
"properties": {
"message": { "type": "text" },
"level": { "type": "keyword" }, // 修正为 keyword
"timestamp": { "type": "date" },
"env": { "type": "keyword" } // 新增字段
}
}
}'
新索引改进点:
- level → keyword(支持精确匹配)
- 分片数从 3 → 2(更合理)
- 新增 env 字段(值统一设为 "prod")
步骤 4:执行 _reindex(带数据转换)
xml
curl -u elastic:'fC3!eG5#iF' -X POST "http://localhost:9200/_reindex?wait_for_completion=false" \
-H 'Content-Type: application/json' -d '
{
"source": {
"index": "logs-old"
},
"dest": {
"index": "logs-new"
},
"script": {
"source": "ctx._source.env = \"prod\"; ctx._source.level = ctx._source.level != null ? ctx._source.level : \"UNKNOWN\";",
"lang": "painless"
}
}'
脚本说明:
- 添加新字段 env ,值固定为"prod"
- 安全处理 level 字段(防止 null):如果原值存在就保留,否则设为 "UNKNOWN"
监控并验证迁移
查看任务状态:
xml
curl -u elastic:'fC3!eG5#iF' "http://localhost:9200/_tasks?detailed=true&actions=*reindex"
{"nodes":{}}
上诉返回表示当前集群中没有任何正在运行的 reindex 任务,因为数据很少是很快的。
验证数据一致性:
xml
# 检查文档数量
curl -u elastic:'fC3!eG5#iF' "http://localhost:9200/logs-new/_count"
# 应返回 5
{"count":5,"_shards":{"total":2,"successful":2,"skipped":0,"failed":0}}
# 查看一条文档(确认 level 是 keyword,且有 env)
curl -u elastic:'fC3!eG5#iF' "http://localhost:9200/logs-new/_search?size=1&pretty"
预期输出片段:
{
"_source" : {
"level" : "INFO",
"message" : "Test log message 1",
"env" : "prod",
"timestamp" : "2025-03-18T10:00:01Z"
}
切换(使用别名实现无缝迁移)
创建别名指向新索引
xml
curl -u elastic:'fC3!eG5#iF' -X POST "http://localhost:9200/_aliases" \
-H 'Content-Type: application/json' -d '
{
"actions": [
{ "add": { "index": "logs-new", "alias": "logs-current" }}
]
}'
(可选)让应用同时写入新旧(双写过渡期)
如果应用正在写 logs-old,可先改为写 logs-current(即 logs-new)
验证别名
xml
curl -u elastic:'fC3!eG5#iF' "http://localhost:9200/logs-current/_count"
# 应返回 和上面一样的结果5
{"count":5,"_shards":{"total":2,"successful":2,"skipped":0,"failed":0}}
清理旧索引(确认无误后)
xml
# 删除旧索引
curl -u elastic:'fC3!eG5#iF' -X DELETE "http://localhost:9200/logs-old"
# 验证只剩新索引
curl -u elastic:'fC3!eG5#iF' "http://localhost:9200/_cat/indices?v"
最终效果
| 项目 | 旧索引 (logs-old) | 新索引 (logs-new) |
|---|---|---|
| 分片数 | 3 | 2 |
| level 类型 | text | keyword |
| 新增字段 | 无 | env |
| 别名 | 无 | logs-current |
| 文档数 | 5 | 5 |
关键总结
- ES 索引结构不可变 → 必须通过 _reindex 重建
- 目标索引必须预先创建(不能依赖自动创建)
- 使用别名 (_aliases) 实现零停机切换
- script 支持 Painless 脚本,可做字段转换/新增
- 同集群 reindex 无需配置白名单(仅跨集群需要)
上诉此流程适用于:
- 修改 mapping
- 调整分片数
- 索引命名规范化
- 数据清洗/增强
如有需要请自行在自己的测试环境测试。如有错误敬请指正。