热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[译]elasticsearch不停服务修改mapping

2019独角兽企业重金招聘Python工程师标准[译]elasticsearch-不停服务修改mapping博客分类:java搜索引擎,爬虫一个常

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

[译]elasticsearch-不停服务修改mapping 博客分类: java 搜索引擎,爬虫  

一个常见的问题是:当数据模型需要修改schema的时候,需要重建索引。如果索引很大,这个需要较长时间,因此要暂停服务,这对应用程序来说是无法接受的。有没有不停服务直接修改mappoing的方法呢?可以有。

1:问题--为什么不能修改mapping?

你只能找到你在索引中存储的信息。为了使数据可查询,就需要知道每一个field包含的数据的数据类型以及它是如何索引的。如果你将一个field的数据类型从string修改为date,这这个字段所包含的数据将全部无用。你需要重建创建索引了!这条规则不仅仅针对es,任何一个可用于查询的数据库系统都是这样。如果不用索引,就是为灵活性牺牲速度。

ES索引是不可改变的segments,每一个segmeng都是一个小的倒排索引。segment是永远不会更新的。更新一个document只是创建了一个新的document,并且在原来的document上加了删除标记。当添加新的document或者更新document的时候,新的segment就会创建。后台运行merge进程,会不停的把一些小的segment合并成一个大的segment,同时会把打有删除标记的document彻底清理。通常情况下,一个index拥有很多type,每一个type都有不同的shema和mapping。一个segment可能包括多个type的document。所有,如果想修改一个type的一个field的定义,都需要重建所有索引。

2:添加字段是免费的

segment中只是包含了这个segment中存在的document中的包含的field的数据信息。因此增加一个新的field是完全免费的,只需要put_mapping即可,无需重建索引。

3:重建索引

重建索引步骤简单,首先,创建新索引的mapping和setting:

 

curl -XPUT localhost:9200/new_index -d '
{"mappings": {"my_type": { ... new mapping definition ...}}
}
'

之后,从旧索引中把数据读取出来放到新创建的索引中,用scrolled search+buck api。许多客户端api提供了reindex方法,将会替你做这些事情。索引做完就可以删除旧索引了。

 

注意:确保你使用了search_type=scan的方式读取数据。这样不会启用sort,并且使得“deep paging”更加高效。

这个方法的问题是:新索引的名字改变了,你需要更新你的应用程序到新的索引名字。

4:不停服务重建索引

alias机制给我们提供了灵活性,使得重建索引完全在后台执行,而且使得索引切换对应用程序来说是透明的。一个alias相当于一个软链接,可以指向一个或者多个索引。

典型的工作流程是这样的:首先,创建索引,索引名称后边可以添加一个version或者时间戳。

 

curl -XPUT localhost:9200/my_index_v1 -d '
{ ... mappings ... }
'

创建alias指向这个索引:

 

 

curl -XPOST localhost:9200/_aliases -d '
{"actions": [{ "add": {"alias": "my_index","index": "my_index_v1"}}]
}
'

现在应用程序对my_index进行操作,就相当于对my_index_v1进行操作。

 

需要重建索引时,可以新建一个索引,添加一个新的version

 

curl -XPUT localhost:9200/my_index_v2 -d '
{ ... mappings ... }
'

然后利用v1的数据来填充v2,将alias指向v2即可。

 

 

curl -XPOST localhost:9200/_aliases -d '
{"actions": [{ "remove": {"alias": "my_index","index": "my_index_v1"}},{ "add": {"alias": "my_index","index": "my_index_v2"}}]
}
'

最后,删除v1

 

 

curl -XDELETE localhost:9200/my_index_v1

现在在后台完成了重建索引的操作,而无需停止服务,对应用程序来说这个过程是完全透明的。

 

以上是处理schema变化的标准步骤,还有一些其他的选项可用。

5:我并不关心老数据

如果你想修改一个field的数据类型,而且你并不关系之前的数据是否可以被搜索到。这种情况下,有以下选项

delete the mapping:

删除一个type的mapping,意味着你也删除了这个type下的所有数据。然后重新创建一个type的mapping。

这对一个含有较少数据的type去修改mapping比较有用。

rename the field:

添加新字段是free的,所以可以添加一个不同名称,不同定义的新field在将来出现的document中使用。当然,这也就意味着应用程序需要更新来使用新字段。

upgrade to a multi-field:

MultiField允许同一个字段用在不同的场景下。一点典型应用就是对同一个字段title以两种不同的方式索引:一个analyzed的string作为查询时使用,一个not_analyzed字段作为排序使用。任何一个纯字段(object和nested不属于这一类)可以升级为一个multi-field,而无需重建索引。比如,现在我们有一个string类型的字段:

 

{"created":{"type":"string"}}

我们可以升级为一个multifield,添加一个sub-field是date类型;

 

 

curl -XPUT localhost:9200/my_index/my_type/_mapping -d '
{"my_type": {"properties": {"created": {"type":   "multi_field","fields": {"created": { "type": "string" },"date":    { "type": "date"   }}}}}
}
'

前边的created的字段仍然存在,作为multi-field的主字段,可以用created或者created.created访问,而新的date类型的字段,可以用created.date来访问,注意,这个字段只对新添加的document有效。

 

6:运用alias来增加灵活性

有时上述方法仍然不足以满足需求。或许你的应用有100,000个user文档,10,000,000个blog文档(在同一个索引中,但是分为不同的type存储)。你想改变user的mapping而无需重新索引blog信息。

在不同的索引中可以存储不同的types。Es可以在不同索引中查询就像是在一个索引中一样。这样,你只需要重新索引你想改变的type所在的索引即可。有了alias,这个重新索引的过程对应用程序也是透明的。

运用以上方法,es为每一个type创建一个单独的alias。比如:不是统一对my_index创建索引,而是user数据对my_index_user创建索引,blog数据对my_index_blog创建索引。

 

curl -XPOST localhost:9200/_aliases -d '
{"actions": [{ "add": {"alias": "my_index_user","index": "my_index_v2"}},{ "add": {"alias": "my_index_blog","index": "my_index_v2"}}]
}
'

查询这样做:

 

 

curl localhost:9200/my_index_blog,my_index_user/_search

如果现在想改变user的mapping怎么做?首先用新的mapping创建一个新的索引,这个索引只存储user数据:

 

 

curl -XPUT localhost:9200/my_index_users_v1 -d '
{"settings": {"index": {"number_of_shards": 1}},"mappings": {"user": { ... new user mapping ... }}
}
'

然后将旧数据索引过来:

 

 

curl 'localhost:9200/my_index_user/user?scroll=1m&search_type=scan'-d '
{"size": 1000
}
'

更新alias:

 

 

curl -XPOST localhost:9200/_aliases -d '
{"actions": [{ "remove": {"alias": "my_index_user","index": "my_index_v2"}},{ "add": {"alias": "my_index_user","index": "my_index_user_v1"}}]
}
'

现在可以用delete-by-query把旧索引中的数据删除:

 

 

curl -XDELETE localhost:9200/my_index_v1/user

这样将来任何时候想改变user的mapping,就可以用之前的方法了。

 

(其实本质就是把type数据用alias搞出来,作为单一存在的索引而已,没什么高端的)

7:运用alias不重建索引

如果想针对改变的mapping只需要应用在新进入的docement中,仍然可以用alias实现。创建两个alias,一个针对search,一个针对新数据的index

 

curl -XPOST localhost:9200/_aliases -d '
{"actions": [{ "add": {"alias": "my_index_user","index": "my_index_user_v1"}},{ "add": {"alias": "my_index_users","index": "my_index_user_v1"}},{ "add": {"alias": "my_index_users","index": "my_index_v1"}},]
}
'

my_index_user指向新索引my_index_user_v1,用来索引数据。而my_index_users则包含旧索引my_index_v1和新索引my_index_users_v1,用来查询数据。这样旧索引让然用之前的mapping,新的mapping之会应用在新建立的数据中。

 

-------

总结一句:alias不神秘,现在只能支持索引之间的切换,上边所用的type的例子也只是把type搞到新的索引中而已。

1.4.x版本会支持带有filter的alias,这个将更有效,是否能有typefiler?这样就解放了type了。期待稳定版本。

http://m.blog.csdn.net/blog/jingkyks/41513063

http://blog.csdn.net/lvhong84/article/details/23936697


转:https://my.oschina.net/xiaominmin/blog/1599598



推荐阅读
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • Android实战——jsoup实现网络爬虫,糗事百科项目的起步
    本文介绍了Android实战中使用jsoup实现网络爬虫的方法,以糗事百科项目为例。对于初学者来说,数据源的缺乏是做项目的最大烦恼之一。本文讲述了如何使用网络爬虫获取数据,并以糗事百科作为练手项目。同时,提到了使用jsoup需要结合前端基础知识,以及如果学过JS的话可以更轻松地使用该框架。 ... [详细]
  • 开发笔记:Python之路第一篇:初识Python
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Python之路第一篇:初识Python相关的知识,希望对你有一定的参考价值。Python简介& ... [详细]
  • ORACLE空间管理实验5:块管理之ASSM下高水位的影响
    数据库|mysql教程ORACLE,空间,管理,实验,ASSM,下高,水位,影响,数据库-mysql教程易语言黑客软件源码,vscode左侧搜索,ubuntu怎么看上一页,ecs搭 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • C#多线程解决界面卡死问题的完美解决方案
    当界面需要在程序运行中不断更新数据时,使用多线程可以解决界面卡死的问题。一个主线程创建界面,使用一个子线程执行程序并更新主界面,可以避免卡死现象。本文分享了一个例子,供大家参考。 ... [详细]
  • 本文总结了在编写JS代码时,不同浏览器间的兼容性差异,并提供了相应的解决方法。其中包括阻止默认事件的代码示例和猎取兄弟节点的函数。这些方法可以帮助开发者在不同浏览器上实现一致的功能。 ... [详细]
  • Python 可视化 | Seaborn5 分钟入门 (六)——heatmap 热力图
    微信公众号:「Python读财」如有问题或建议,请公众号留言Seaborn是基于matplotlib的Python可视化库。它提供了一个高级界面来绘制有吸引力的统计图形。Seabo ... [详细]
  • Python入门后,想要从事自由职业可以做哪方面工作?1.爬虫很多人入门Python的必修课之一就是web开发和爬虫。但是这两项想要赚钱的话 ... [详细]
author-avatar
毛毛-刘庆
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有