Elasticsearch如何修改Mapping结构并实现业务零停机
Elasticsearch 版本:6.4.0
一、疑问
在项目中后期,如果想调整索引的 Mapping 结构,比如将 ik_smart 修改为 ik_max_word 或者 增加分片数量 等,但 Elasticsearch 不允许这样修改呀,怎么办?
常规 解决方法:
- 根据最新的 Mapping 结构再创建一个索引
- 将旧索引的数据全量导入到新索引中
- 告知用户,业务要暂停使用一段时间
- 修改程序,将索引名替换成新的索引名称,打包,重新上线
- 告知用户,服务可以继续使用了,并说一声抱歉
我认为最大的弊端就是:需要修改替换程序,甚至有时候还得告知用户暂停使用业务。
有没有更好的方式去解决上面的需求呢?有!幸好,Elasticsearch 为我们提供了另外一种解决方法,可以不需要告知用户和修改程序代码。那就是通过索引别名来重建索引。
二、索引别名
索引别名可以关联一个或多个索引,并且可以在任何需要索引名称的 API 中使用。 通俗解释,别名类似于 windows 的快捷方式,linux 的软链接,mysql 的视图。别名为我们提供了极大的灵活性。它们允许我们执行以下操作:
- 在正在运行的集群上,允许一个索引与另外一个索引之间透明切换。
- 对多个索引进行分组组合。比如,有根据月份来创建的索引,别名可与近三个月的索引进行关联。这样的话,我们就可以通过 别名 来 查询近三个月索引 的全部数据。如果别名用得好,可以更好地控制检索数据量的大小,来提高查询效率,但这也需要经验的积累。
本文开头遇到的问题,就可以通过索引别名来实现,现在我们学习一下具体操作。
三、具体操作
如何在零停机(该索引所用到的程序不停止运行)的前提下,修改索引的 Mapping 字段类型呢?可大体分为三步:
1、步骤一:复制数据
使用 reindex 操作来将旧索引(dynamic_data_v2)的数据完全复制到新索引(dynamic_data_v5)上:
POST _reindex
{
"source": {
"index": "dynamic_data_v2"
},
"dest": {
"index": "dynamic_data_v5"
}
}
执行结果:

2、步骤二:修改别名关联
POST /_aliases
{
"actions": [
{ "remove": { "index": "dynamic_data_v2", "alias": "dynamic_data" }},
{ "add": { "index": "dynamic_data_v5", "alias": "dynamic_data" }}
]
}
3、步骤三:删除旧索引(可选)
DELETE dynamic_data_v2
4、小结
至此,我们达到了伪更新(对于用户来说透明化,无需停止服务)的效果。不过这里存在一个问题,如果数据量超大的话,复制数据所消费的时间比较多,所以构建索引前还是要尽量考虑周全 mapping 结构。
关于索引别名更多操作,可参考:
https://www.elastic.co/guide/en/elasticsearch/reference/6.4/indices-aliases.html
四、可修改 mapping 的个别情况
Elasticsearch 不允许修改/删除 Mapping 已存在字段是因为:其底层使用的是 lucene 库,索引和搜索要涉及分词方式等操作,更改 Mapping 将意味着使已建立索引的文档失效,所以不允许修改 已存在字段类型等设置。
但也有个别情况:Elasticsearch 允许我们 将字段添加到索引现有的 Mapping 结构中 或 更改现有字段的仅搜索设置。
1、可以新增字段
POST dynamic_data_v2/_mapping/_doc
{
"properties": {
"amount":{
"type":"text"
}
}
}
2、可以更改字段类型为 multi_field
PUT dynamic_data_v2/_mapping/_doc
{
"properties": {
"amount":{
"type":"text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 10
}
}
}
}
}
# 为 amount 增加 multi_field
# "fields": {
# "keyword": {
# "type": "keyword",
# "ignore_above": 10
# }
# }
3、可以将新 properties 添加到 “对象” 数据类型字段。
在 Mapping 的 field 里面设置 properties ,可以使字段存储 Object 的数据类型。以下的 name 可以理解为 “对象”数据类型字段:
# 新增 name 字段,附带first的properties属性
PUT dynamic_data_v2/_mapping/_doc
{
"properties": {
"name":{
"properties": {
"first": {
"type": "text"
}
}
}
}
}
# 可以支持继续新增一个名为last的properties属性
PUT dynamic_data_v2/_mapping/_doc
{
"properties": {
"name":{
"properties": {
"last": {
"type": "text"
}
}
}
}
}
如下图所示:

存储数据:
# name 的对象里面有两个字段,分别为:first 和 last,代表名和姓,比如“范闲”。
PUT dynamic_data_v2/_doc/1
{
"name": {
"first": "闲",
"last": "范"
}
}
查询数据:
GET dynamic_data_v2/_search
{
"query": {
"bool": {
"must": [
{
"match_phrase": {
"name.last": "范"
}
},
{
"match_phrase": {
"name.first": "闲"
}
}
]
}
}
}
返回结果:

上述三种方式,详情可参考:
五、总结
别名是个好东西,而索引别名只是别名的其中一个类型。一般在项目中后期,索引中有大量数据的时候,才能体会到索引别名的妙用。正如本文提及:
- 用户无感知地维护数据修改更新。
- 索引组合查询,如果使用得当,可以实现精准快速查询,提高效率。
建议: 相同索引别名的物理索引有 一致的 Mapping 和 数据结构 ,以提升检索效率。
点关注,不迷路
好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是人才。
白嫖不好,创作不易。各位的支持和认可,就是我创作的最大动力,我们下篇文章见!
如果本篇博客有任何错误,请批评指教,不胜感激 !

Elasticsearch如何修改Mapping结构并实现业务零停机的更多相关文章
- elasticsearch 修改 mapping
Elasticsearch的mapping一旦创建,只能增加字段,而不能修改已经mapping的字段.但现实往往并非如此啊,有时增加一个字段,就好像打了一个补丁,一个可以,但是越补越多,最后自己都觉得 ...
- ES 11 - 配置Elasticsearch的映射 (mapping)
目录 1 映射的相关概念 1.1 什么是映射 1.2 映射的组成 1.3 元字段 1.4 字段的类型 2 如何配置mapping 2.1 创建mapping 2.2 更新mapping 2.3 查看m ...
- mysql在线修改表结构大数据表的风险与解决办法归纳
整理这篇文章的缘由: 互联网应用会频繁加功能,修改需求.那么表结构也会经常修改,加字段,加索引.在线直接在生产环境的表中修改表结构,对用户使用网站是有影响. 以前我一直为这个问题头痛.当然那个时候不需 ...
- [20171113]修改表结构删除列相关问题4.txt
[20171113]修改表结构删除列相关问题4.txt --//连续写了3篇修改表结构删除列的相关问题,链接如下: http://blog.itpub.net/267265/viewspace-214 ...
- 第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的mapping映射管理
第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的mapping映射管理 1.映射(mapping)介绍 映射:创建索引的时候,可以预先定义字 ...
- (转)pt-online-schema-change在线修改表结构
原文:http://www.ywnds.com/?p=4442 一.背景 MySQL大字段的DDL操作:加减字段.索引.修改字段属性等,在5.1之前都是非常耗时耗力的,特别是会对MySQL服务产生影响 ...
- ElasticSearch(ES)使用Nested结构存储KV及聚合查询
自建博客地址:https://www.bytelife.net,欢迎访问! 本文为博客同步发表文章,为了更好的阅读体验,建议您移步至我的博客 本文作者: Jeffrey 本文链接: https://w ...
- MySQL数据库如何线上修改表结构
一.MDL元数据锁 在修改表结构之前,先来看下可能存在的问题. 1.什么是MDL锁 MySQL有一个把锁,叫做MDL元数据锁,当对表修改的时候,会自动给表加上这把锁,也就是不需要自己显式使用. 当对表 ...
- SQL Server 修改表结构后无法保存的老问题
在修改表结构后无法保存,这是每次重装SQL Server后都会遇到的问题,好记性不如烂笔头,在这里记一下吧. 保存修改了的表结构时会提示“不允许保存更改.您所做的更改要求删除并重新创建以下表.您对无法 ...
随机推荐
- C# 如何在项目引用x86 x64的非托管代码
因为现在的项目使用的是 AnyCpu 在 x86 的设备使用的是x86,在x64使用的是x64,但是对于非托管代码,必须要在x64使用x64的dll,在x86使用x86的dll.在C++没有和C#一样 ...
- Array数组的常用方法
1.concat()链接数组 var a = [1,2,3]; console.log(a.concat(4,5));//[1,2,3,4,5] 2.join()分隔符链接数组变字符串,如果省略该参数 ...
- Vue中的computed和watch
看了网上很多资料,对vue的computed讲解自己看的都不是很清晰,今天忙里抽闲,和同事们又闲聊起来,对computed这个属性才有了一个稍微比较清晰的认识,下面的文章有一部分是转自: https: ...
- jQuery 工具类函数-检测两个节点的包含关系
调用名为$.contains的工具函数,能检测在一个DOM节点中是否包含另外一个DOM节点,如果包含,返回true,否则,返回false值,调用格式为: $.contains (container, ...
- Linux内核 结构 struct urb
struct urb 结构中和 USB 设备驱动有关的成员是: struct usb_device *dev 指向这个 urb 要发送到的 struct usb_device 的指针. 这个变量必须被 ...
- 2018-2-13-Xamarin-Forms-进度条控件
title author date CreateTime categories Xamarin Forms 进度条控件 lindexi 2018-2-13 17:23:3 +0800 2018-2-1 ...
- Java逻辑思维训练题
两柱香问题题目:有两柱不均匀的香,每柱香燃烧完需要1个小时,问:怎样用两柱香切出一个15分钟的时间段?这个题的重点就是怎么切. 答案:将甲香的一头点着,将乙香的两头点着,当乙香燃烧完时,说明已经过了半 ...
- 牛客多校第三场 F Planting Trees
牛客多校第三场 F Planting Trees 题意: 求矩阵内最大值减最小值大于k的最大子矩阵的面积 题解: 矩阵压缩的技巧 因为对于我们有用的信息只有这个矩阵内的最大值和最小值 所以我们可以将一 ...
- 开篇 | 揭秘 Flink 1.9 新架构,Blink Planner 你会用了吗?
本文为 Apache Flink 新版本重大功能特性解读之 Flink SQL 系列文章的开篇,Flink SQL 系列文章由其核心贡献者们分享,涵盖基础知识.实践.调优.内部实现等各个方面,带你由浅 ...
- MyISAM与InnoDB的索引实现区别
一 MyISAM索引实现 1. 主键索引 MyISAM引擎使用B+树作为索引结果,叶节点的data域存放的是数据记录的地址.下图为MyISAM表的主索引,Col1为主键. 2. 辅助索引 在MyISA ...