ElasticSearch如何应对索引字段修改
的有关信息介绍如下:随着业务的发展,难免会遇到ES索引字段类型发生变更的需求,但是ES是不支持索引字段类型变更的,原因是一个字段的类型进行修改之后,ES会重新建立对这个字段的索引信息,影响到ES对该字段分词方式,相关度,TF/IDF倒排创建等,本篇文章解决了在ES不停止服务的情况下使得ES索引字段类型发生变更的问题,以下以商品编码由Long类型修改为String类型例举说明该问题
创建关于商品的ES索引
PUT item_index/_mapping/_doc
{
"properties": {
"itemId": { "type": "long"}
}
}
给item_index索引添加别名
PUT item_index/_alias/item_index_alias
{}
使用别名操作索引(查询或者写入)的好处是使得操作ES索引的程序与索引名称隔离,即当索引名称发生变化的时候,不需要修改代码程序也能实现ES索引的迁移
使用ES的reindex功能实现索引字段类型变更
基本步骤是:通过es的reindex功能把旧索引的数据reindex到新索引,然后为新索引建立旧索引的别名,最后删除旧索引。
1.创建一个新的商品索引
PUT item_new_index/_mapping/_doc
{
"properties": {
"itemId": { "type": "keyword"}
}
}
2.执行reindex操作,把旧索引的数据复制到新索引
POST _reindex
{
"source": { "index": "item_index" },
"dest": { "index": "item_new_index" }
}
3.将旧索引的别名切换至新的索引(即删除旧索引别名的同时给新索引添加别名)
POST _aliases/d
{
"actions": [
{ "remove": {
"alias": "item_index_alias",
"index": "item_index"
}},
{ "add": {
"alias": "item_index_alias",
"index": "item_new_index"
}}
]
}
4.删除旧索引
POST item_index/_forcemerge?only_expunge_deletes=true
DELETE item_index
关于reIndex的注意点
1.查询reIndex进度
GET _tasks?detailed=true&actions=*reindex
2.取消reIndex任务
POST _tasks/node_id:task_id/_cancel
3.默认情况下,_reindex使用1000进行批量操作,可以在source中调整batch_size提升reIndex速度
POST _reindex{ "source": { "index": "source", "size": 5000 }, "dest": { "index": "dest", "routing": "=cat" }}
通过给item_index索引增加新字段的方式实现索引字段类型变更
1.执行一下语句给item_index新增字段itemNo
PUT item_index/_mapping/_doc
{
"properties": {
"itemNo": {
"type": "keyword"
}
}
}
2.使用代码程序初始化字段itemNo,即将老的索引字段itemId值刷新到itemNo中
3.修改代码程序,使用itemNo代替itemId
4.itemId字段废弃不使用了但是会保留在item_index索引中
针对以上修改索引字段类型的方法修改考虑的点
1.进行以上操作的时候,建议先对索引建立快照备份。
2.如果item_index索引中文档很多,reindex操作会耗时比较久,耗费ES服务的资源,影响ES服务的的性能。
3.查询ES的磁盘空间是否足够reindex新的索引。
3.reindex过程中,原索引新增的数据,是没有被reindex过去,考虑到是否由数据丢失。
5.在reindex索引代价比较大的时候可以使用给索引新增字段的方式实现索引字段类型的变更。