场景
在mysql中 我们经常遇到产品修改需求 我们可能会在原有数据库表基础上 对字段 索引 类型进行修改
比如 增加一个字段 添加一个字段的索引 又或者修改某个字段的类型
一切都看起来这么自然 不过在ES这里却是行不通的
ES的mapping一旦设置了之后 是不能修改的 因为ES默认是对所有字段进行索引 如果你修改了mapping 那么已经索引过的数据就必须全部重新索引一遍 ES没有提供这个机制
解决
不过我们有另外一种解决方案类似与运维中的滚动发布
利用别名
说穿了其实很简单
比如我们创建了一个索引张三 我们给他起一个别名A 我们在搜索的时候就可以在别名中搜索 别名会自动映射到张三
这时候如果张三满足不了我们的需求,我们要修改张三。我们可以创建一个李四的索引(修改后的张三索引mapping)
然后同步数据并索引到李四
这时候我们把别名映射 从A->张三 变成 A->李四 就可以实现无缝切换了
实际操作
创建张三索引
修改索引别名
创建李四索引(在张三的基础上增加了一个age字段)
修改别名映射
大功告成 这样搜索A索引 就是在搜索新的李四了
通过这几个步骤就实现了平滑切换 零停机
这里面切换别名的操作是原子性的 所以不用担心数据搜索错乱的问题
{
"actions" : [
{ "remove" : { "index" : "zhangsan", "alias" : "a" } },
{ "add" : { "index" : "lisi", "alias" : "a" } }
]
}