热门标签 | 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实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • 本文讨论了在进行 MySQL 数据迁移过程中遇到的所有 .frm 文件报错的问题,并提供了详细的解决方案和建议。 ... [详细]
  • 在机器学习领域,深入探讨了概率论与数理统计的基础知识,特别是这些理论在数据挖掘中的应用。文章重点分析了偏差(Bias)与方差(Variance)之间的平衡问题,强调了方差反映了不同训练模型之间的差异,例如在K折交叉验证中,不同模型之间的性能差异显著。此外,还讨论了如何通过优化模型选择和参数调整来有效控制这一平衡,以提高模型的泛化能力。 ... [详细]
  • FreeBSD环境下PHP GD库安装问题的详细解决方案
    在 FreeBSD 环境下,安装 PHP GD 库时可能会遇到一些常见的问题。本文详细介绍了从配置到编译的完整步骤,包括解决依赖关系、配置选项以及常见错误的处理方法。通过这些详细的指导,开发者可以顺利地在 FreeBSD 上完成 PHP GD 库的安装,确保其正常运行。此外,本文还提供了一些优化建议,帮助提高安装过程的效率和稳定性。 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • Swoole加密机制的安全性分析与破解可能性探讨
    本文深入分析了Swoole框架的加密机制,探讨了其在实际应用中的安全性,并评估了潜在的破解可能性。研究结果表明,尽管Swoole的加密算法在大多数情况下能够提供有效的安全保护,但在特定场景下仍存在被攻击的风险。文章还提出了一些改进措施,以增强系统的整体安全性。 ... [详细]
  • 在安装并配置了Elasticsearch后,我在尝试通过GET /_nodes请求获取节点信息时遇到了问题,收到了错误消息。为了确保请求的正确性和安全性,我需要进一步排查配置和网络设置,以确保Elasticsearch集群能够正常响应。此外,还需要检查安全设置,如防火墙规则和认证机制,以防止未经授权的访问。 ... [详细]
  • Flutter 2.* 路由管理详解
    本文详细介绍了 Flutter 2.* 中的路由管理机制,包括路由的基本概念、MaterialPageRoute 的使用、Navigator 的操作方法、路由传值、命名路由及其注册、路由钩子等。 ... [详细]
  • DAO(Data Access Object)模式是一种用于抽象和封装所有对数据库或其他持久化机制访问的方法,它通过提供一个统一的接口来隐藏底层数据访问的复杂性。 ... [详细]
  • 【实例简介】本文详细介绍了如何在PHP中实现微信支付的退款功能,并提供了订单创建类的完整代码及调用示例。在配置过程中,需确保正确设置相关参数,特别是证书路径应根据项目实际情况进行调整。为了保证系统的安全性,存放证书的目录需要设置为可读权限。值得注意的是,普通支付操作无需证书,但在执行退款操作时必须提供证书。此外,本文还对常见的错误处理和调试技巧进行了说明,帮助开发者快速定位和解决问题。 ... [详细]
  • 在最近的项目中,我们广泛使用了Qt框架的网络库,过程中遇到了一些挑战和问题。本文旨在记录这些经验和解决方案,以便日后参考。鉴于我们的客户端GUI完全基于Qt开发,我们期望利用其强大的网络功能进行Fiddler网络数据包的捕获与分析,以提升开发效率和应用性能。 ... [详细]
  • 在PHP中实现腾讯云接口签名,以完成人脸核身功能的对接与签名配置时,需要注意将文档中的POST请求改为GET请求。具体步骤包括:使用你的`secretKey`生成签名字符串`$srcStr`,格式为`GET faceid.tencentcloudapi.com?`,确保参数正确拼接,避免因请求方法错误导致的签名问题。此外,还需关注API的其他参数要求,确保请求的完整性和安全性。 ... [详细]
  • 在本次分享中,我将详细介绍我的网络数据爬取项目,包括使用Scrapy-Redis进行分布式爬取的具体配置和多台机器的协同工作。此外,还将探讨从Scrapy到Scrapy-Redis的迁移过程,以及在实际爬取过程中遇到的各种反爬虫策略及其应对方法。 ... [详细]
  • 本指南介绍了 `requests` 库的基本使用方法,详细解释了其七个主要函数。其中,`requests.request()` 是构建请求的基础方法,支持其他高级功能的实现。此外,我们还重点介绍了如何使用 `requests.get()` 方法来获取 HTML 网页内容,这是进行网页数据抓取和解析的重要步骤。通过这些基础方法,读者可以轻松上手并掌握网页数据抓取的核心技巧。 ... [详细]
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社区 版权所有