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": "闲"
}
}
]
}
}
}

返回结果:

上述三种方式,详情可参考:

https://www.elastic.co/guide/en/elasticsearch/reference/6.4/indices-put-mapping.html#updating-field-mappings

五、总结

别名是个好东西,而索引别名只是别名的其中一个类型。一般在项目中后期,索引中有大量数据的时候,才能体会到索引别名的妙用。正如本文提及:

  • 用户无感知地维护数据修改更新。
  • 索引组合查询,如果使用得当,可以实现精准快速查询,提高效率。

建议: 相同索引别名的物理索引有 一致的 Mapping 和 数据结构 ,以提升检索效率。


点关注,不迷路

好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是人才

白嫖不好,创作不易。各位的支持和认可,就是我创作的最大动力,我们下篇文章见!

如果本篇博客有任何错误,请批评指教,不胜感激 !

Elasticsearch如何修改Mapping结构并实现业务零停机的更多相关文章

  1. elasticsearch 修改 mapping

    Elasticsearch的mapping一旦创建,只能增加字段,而不能修改已经mapping的字段.但现实往往并非如此啊,有时增加一个字段,就好像打了一个补丁,一个可以,但是越补越多,最后自己都觉得 ...

  2. ES 11 - 配置Elasticsearch的映射 (mapping)

    目录 1 映射的相关概念 1.1 什么是映射 1.2 映射的组成 1.3 元字段 1.4 字段的类型 2 如何配置mapping 2.1 创建mapping 2.2 更新mapping 2.3 查看m ...

  3. mysql在线修改表结构大数据表的风险与解决办法归纳

    整理这篇文章的缘由: 互联网应用会频繁加功能,修改需求.那么表结构也会经常修改,加字段,加索引.在线直接在生产环境的表中修改表结构,对用户使用网站是有影响. 以前我一直为这个问题头痛.当然那个时候不需 ...

  4. [20171113]修改表结构删除列相关问题4.txt

    [20171113]修改表结构删除列相关问题4.txt --//连续写了3篇修改表结构删除列的相关问题,链接如下: http://blog.itpub.net/267265/viewspace-214 ...

  5. 第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的mapping映射管理

    第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的mapping映射管理 1.映射(mapping)介绍 映射:创建索引的时候,可以预先定义字 ...

  6. (转)pt-online-schema-change在线修改表结构

    原文:http://www.ywnds.com/?p=4442 一.背景 MySQL大字段的DDL操作:加减字段.索引.修改字段属性等,在5.1之前都是非常耗时耗力的,特别是会对MySQL服务产生影响 ...

  7. ElasticSearch(ES)使用Nested结构存储KV及聚合查询

    自建博客地址:https://www.bytelife.net,欢迎访问! 本文为博客同步发表文章,为了更好的阅读体验,建议您移步至我的博客 本文作者: Jeffrey 本文链接: https://w ...

  8. MySQL数据库如何线上修改表结构

    一.MDL元数据锁 在修改表结构之前,先来看下可能存在的问题. 1.什么是MDL锁 MySQL有一个把锁,叫做MDL元数据锁,当对表修改的时候,会自动给表加上这把锁,也就是不需要自己显式使用. 当对表 ...

  9. SQL Server 修改表结构后无法保存的老问题

    在修改表结构后无法保存,这是每次重装SQL Server后都会遇到的问题,好记性不如烂笔头,在这里记一下吧. 保存修改了的表结构时会提示“不允许保存更改.您所做的更改要求删除并重新创建以下表.您对无法 ...

随机推荐

  1. 51nod 1307绳子和重物

    1307 绳子与重物  题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 有N条绳子编号 0 至 N - 1,每条绳子后 ...

  2. background:url(./images.png) no-repeat 0 center的用法

    background:url(./images.png) no-repeat 0 center; //图像地址 不重复 水平位置0 垂直位置居中 background:url(./images.png ...

  3. thinkjs解决跨域

    this.header("Access-Control-Allow-Origin", "*"); 将上面的代码在请求发送之前执行即可 如果不知道放在哪里 可以参 ...

  4. 【37.48%】【hdu 2587】How far away ?(3篇文章,3种做法,LCA之Tarjan算法)

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

  5. http://mirror2.openwrt.org/sources/

    http://mirror2.openwrt.org/sources/ Index of /sources/ ../ 1.0.4.3.arm 22-Dec-2008 20:29 93996 2.13. ...

  6. 王雅超的学习笔记-大数据hadoop集群部署(十)

    Spark集群安装部署

  7. tomcat启动慢问题

    sed -i 's/securerandom\.source\=file\:\/dev\/random/securerandom\.source\=file\:\/dev\/urandom/g' $J ...

  8. 洛谷$P4040\ [AHOI2014/JSOI2014]$宅男计划 贪心

    正解:三分+贪心 解题报告: 传送门$QwQ$ 其实很久以前的寒假就考过了,,,但那时候$gql$没有好好落实,就只写了个二分,并没有二分套三分,就只拿到了$70pts$ #include <b ...

  9. Spring 资源注入

    Spring开发中经常需要调用各种资源,包含普通文件.网址.配置文件.系统环境变量等,我们可以使用Spring表达式语言(Spring-EL)实现资源的注入. Spring主要使用@Value注解实现 ...

  10. 浅谈JSON HiJacking攻击

    JSON HiJacking攻击: JSON劫持类似于CSRF攻击,为了了解这种攻击方式,我们先看一下Web开发中一种常用的跨域获取数据的方式:JSONP. 先说一下JSON吧,JSON是一种数据格式 ...