一、数据迁移原因
- 更改索引映射 (Mapping Changes)
- 原因: 一旦索引创建,映射(mapping)通常是不可变的。如果需要增加新的字段、修改现有字段的类型,或者调整分词器设置,必须重新创建索引并将数据重新索引。
- 具体场景: 例如,需要将一个文本字段从不分词改为分词状态,或需要改变一个数值字段的类型。
- 更改索引设置 (Settings Changes)
- 原因: 某些索引设置(如分片数量、副本数量)在索引创建后是不可更改的。如果需要修改这些设置,需要重新创建索引并重新索引数据。
- 具体场景: 例如,需要调整分片数量以提高查询性能或索引吞吐量。
- 索引优化 (Index Optimization)
- 原因: 随着索引的增长或使用,可能会产生大量的删除标记或碎片化数据,通过reindex可以创建一个新的优化后的索引。
- 具体场景: 例如,定期重建索引以删除物理上被删除的数据或优化磁盘空间使用。
- 版本升级 (Version Upgrades)
- 原因: 升级Elasticsearch版本后,新的版本可能包含一些无法向后兼容的更改,或者新版本提供了新的功能和优化,重新索引可以利用这些新特性。
- 具体场景: 例如,从一个主要版本升级到另一个版本后,建议进行reindex以确保所有数据和元数据兼容。
- 数据迁移 (Data Migration)
- 原因: 将数据从一个集群迁移到另一个集群,或在集群内部不同节点之间进行数据迁移,通常需要重新索引数据。
- 具体场景: 例如,从一个开发集群迁移到生产集群,或者将数据从一个过时的硬件节点迁移到新的硬件节点。
- 性能优化 (Performance Tuning)
- 原因: 索引结构设计不合理或者数据分布不均匀可能会影响查询性能,通过重新索引可以优化性能。
- 具体场景: 例如,通过调整分片策略或优化索引结构,以提高搜索速度和索引效率。
- 数据修复 (Data Repair)
- 原因: 如果索引数据出现损坏或不一致的情况,通过重新索引可以修复数据。
- 具体场景: 例如,由于硬件故障或软件错误导致数据损坏。
二、数据迁移
1.es的ddl语句
首先创建一个test索引,添加一条数据
然后创建一个需要格式的索引,进行迁移
以下是常用参数及其含义:
-
source:定义源索引以及查询条件。
- index:源索引的名称,可以是单个索引或索引模式。
- type(已弃用):源索引的类型。
- query:用于过滤数据的查询条件,可以使用Elasticsearch的查询DSL。
-
dest:定义目标索引。
- index:目标索引的名称。
- type(已弃用):目标索引的类型。
- op_type:操作类型,可以是 create 或 index。create 只在目标索引中不存在文档时创建新文档,index 则会覆盖已有文档。
-
script:可选,用于在重新索引时对文档进行修改。
- source:定义脚本的内容,可以使用Painless脚本语言。
- lang:脚本语言,默认是 painless。
- params:脚本参数。
-
conflicts:定义在出现冲突时的处理方式。默认值是 abort,表示在冲突时终止操作,可以设置为 proceed 以忽略冲突并继续操作。
-
size:批量大小,每次操作处理的文档数量。默认是 1000。
-
max_docs:最大文档数量,限制重新索引的文档总数。
-
scroll:定义 scroll 的保持时间,用于处理大数据集。默认是 5m(5分钟)。
-
refresh:是否在重新索引后刷新目标索引,使新文档可见。默认是 false。
-
timeout:每个批处理的超时时间,默认是 1m(1分钟)。
-
wait_for_completion:是否等待操作完成。默认是 true。
-
requests_per_second:每秒允许的请求数,默认是 -1(不限制)。
-
slices:并行度,可以指定分片数量以并行执行操作,提高速度。
注意事项:
- _reindex 操作会消耗大量的资源,特别是在处理大数据集时,因此在生产环境中使用时应小心,建议在低负载时执行。
- 确保目标索引的映射(mapping)与源索引兼容,特别是字段类型。
- 如果使用脚本进行文档修改,确保脚本正确无误,因为脚本错误可能导致数据不一致。
- 为避免影响集群性能,可以设置 requests_per_second 来限制每秒的请求数量。
POST _reindex
{
"source": {
"index": "source_index",
"query": {
"match": {
"status": "active"
}
}
},
"dest": {
"index": "dest_index"
},
"script": {
"source": "ctx._source['new_field'] = 'new_value'",
"lang": "painless"
},
"conflicts": "proceed",
"size": 500,
"refresh": true
}
- jvav代码如下
这个是reindex两个索引:
public boolean reindexData(String sourceIndex, String destIndex){
Boolean flag = true;
ReindexRequest reindexRequest = new ReindexRequest();
reindexRequest.setSourceIndices(sourceIndex);
reindexRequest.setDestIndex(destIndex);
reindexRequest.setConflicts("proceed");
try {
client.reindex(reindexRequest,RequestOptions.DEFAULT);
} catch (IOException e) {
logger.error("迁移索引"+sourceIndex+"到"+destIndex+"失败,失败原因为"+e);
flag = false;
}
return flag;
}
删除旧索引:
public Boolean renameAndDeleteOldIndex(String oldIndexName){
Boolean deleteIndex = deleteIndex(oldIndexName);
logger.info("删除旧索引"+oldIndexName+"状态"+deleteIndex);
return deleteIndex;
}
注意:这个是刷新索引,不然在添加别名或者其他操作可能会找不到
public void refreshIndex(String indexName) {
ServerEsDao serverEsDao = SpringApplicationUtils.getBean(ServerEsDao.class);
RefreshRequest refreshRequest = new RefreshRequest(indexName);
try {
RefreshResponse refreshResponse = serverEsDao.getClient().indices().refresh(refreshRequest, RequestOptions.DEFAULT);
} catch (Exception e) {
// throw new RuntimeException(e);
}
}
添加索引别名:
public boolean addAlias(String indexName, String aliasName) throws Exception {
IndicesAliasesRequest aliasesRequest = new IndicesAliasesRequest();
IndicesAliasesRequest.AliasActions aliasAction =
new IndicesAliasesRequest.AliasActions(IndicesAliasesRequest.AliasActions.Type.ADD)
.index(indexName)
.alias(aliasName);
aliasesRequest.addAliasAction(aliasAction);
org.elasticsearch.action.support.master.AcknowledgedResponse acknowledgedResponse = EsClient.getInstance().getClient().indices().updateAliases(aliasesRequest,RequestOptions.DEFAULT);
return acknowledgedResponse.isAcknowledged();
}
这个默认已经创建好模板,然后吧旧数据reindex到新索引,然后删除旧索引,进行刷新,添加别名。甚至可以再次reindex回去,自由组合