今天因为上线之前,忘记提单先把es的索引新增的几个字段先建好,导致需求上线后,一些触发推送到es的数据,使得es自动根据数据类型创建索引字段类型,原本我打算增加的mapping字段是数组keyword类型的,但是es自动匹配创建类型为long,导致索引作废,可是这个es索引24小时都有人在使用,如果粗暴删除重建索引,再全量同步数据,会导致一段时间国内外用户查询数据受影响,那有什么解决方法吗?
1、先新建一个正确的索引,如下图(原索引feh-product-sit)
2、将旧索引数据同步到新的索引上
POST _reindex
{
"source": {
"index": "feh-product-sit"
},
"dest": {
"index": "feh-product-sit-v1",
"op_type": "create"
}
}
此时,数据是批量同步的,可以通过以下命令查看同步情况
GET _tasks?detailed=true&actions=*reindex&human
当同步完成时,如下图
3、将旧索引删除
4、删除完成之后马上执行以下命令,给旧索引新增别名
此时新索引就代替了旧索引的位置,这个过程要快,因为保不准此刻正在推数据,你就漏了几条生产数据了(事实上我们当时也是漏推了几条数据)
POST /_aliases
{
"actions": [{
"add": {
"index": "feh-product-sit-v1",
"alias": "feh-product-sit"
}
}
]
}
重点:
建议的解决方案,在生产中,我们不要直接使用索引的正式索引名
我们建索引feh-product-sit-v1并给他配置一个别名feh-product-sit-alias(或者直接feh-product-sit),在代码配置文件中就使用 feh-product-sit-alias,去操作es,如果遇到这种情况,我们就直接新建一个索引feh-product-sit-v2,然后按照上面的方式重推数据后,将索引feh-product-sit-v1去除别名 feh-product-sit-alias的同时将feh-product-sit-v2别名为 feh-product-sit-alias,使用如下指令
POST /_aliases
{
"actions": [{
"add": {
"index": "index-new",
"alias": "index-alias"
}
},
{
"remove": {
"index": "index-old",
"alias": "index-alias"
}
}
]
}
这样有个好处,如上是一条命令进行的原子性操作,可以减少在删除旧索引和切换新索引操作时带来的影响,使用之前方法的话如果在此期间有用户发起查询请求那么就会报错