今天因为上线之前,忘记提单先把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"
			}
		}
	]
}

这样有个好处,如上是一条命令进行的原子性操作,可以减少在删除旧索引和切换新索引操作时带来的影响,使用之前方法的话如果在此期间有用户发起查询请求那么就会报错

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐