TNG 教你如何在 Elasticsearch 重建索引

序言

Elasticsearch 是一个实时的分布式搜索分析引擎。Teambition 使用 Elastisearch 作为搜索引擎,为用户提供搜索服务,当我们决定存储某种数据时,我们需要使用 创建索引,在创建索引的时候需要将数据结构完整确定下来,于此同时索引的设定和很多固定配置将用不能改变。当需要改变数据结构时,就需要重新建立索引,为此,Elastic团队提供了很多辅助工具帮助开发人员进行重建索引。

决定是否需要重建?

重建时相当痛苦的,如果没有很好的基础,服务可能中断,当数据量非常大时,重建恢复时间可能很长,甚至在重建过程中出错等等。所以,没有万不得已的情况下还是尽量避免重建索引。Teambition 重建索引的理由略,因为这并不重要。

使用正确的工具

kibana 是 Elasticsearch 的最佳拍档,从 ES 5.0 开始,Kibana 强大的功能能够替代几乎所有旧时代 ES 1.x 和 ES 2.x 的插件。关键是人家还是免费的!

先决条件1

正在运行的服务必须使用别名(alias)来访问索引(index),原因很简单,搜索服务最终要使用重建的索引,原始的索引将被删除。如果你的服务正在直接使用索引名,在重建前:创建别名,更新服务。

先决条件2

记得查看 Elasticsearch 的 Disk Usage,如果不够,请先申请好足够的空间。

创建新索引

和创建普通索引一样创建新索引。这里值得一提的时,当数据量很大的时候,需要设置刷新时间间隔,在此期间写入的数据不能搜到,从而提高重建速度: 。

实践告诉我,大概会提高100%~400%的提升。

记录同步数据的偏移值(offset)

Teambition 使用 Kafka 把 MongoDB 中的数据导入到 Elasticsearch 中,如果没有kafka,亦可读取 oplog 的数据写入 Elasticsearch。无论使用哪种同步数据的方式,都需要记录同步数据的offset。重建索引可能非常耗时,在这段时间内,同步进程仍然在向旧索引更新数据,此时重建索引是无法更新这些新数据的。这里记录的方法就不多说了,Teambition 使用 kafka-admin 的 API 记录offset。

开始重建索引

使用 Elasticsearch 团队提供的 reindex api 就可以将数据 copy 到新索引中。这里几条路可以选:

当只是改变 mapping 数据结构时,可以仅仅使用 reindex api 即可。例如:删除字段,更新字段分词方式等。

当需要写入新的字段,新的字段是由老的字段计算得到时,可以使用 参数。例如,计算某条数据某字段的总和。script 有很多坑,当 script 出错时,reindex 跑了很久之后失败,即使将数据恢复,也需要重新跑 reindex。

当含有很复杂的逻辑时,额,还是自己写程序吧。

调用 reindex 接口,接口将会在 reindex 结束后返回,而接口返回超时只有 30 秒,如果 reindex 时间过长,建议加上 的参数条件,这样 reindex 将直接返回 taskId

重建索引中

重建索引非常耗时,喝杯咖啡歇一会儿吧(顺便去打个球,睡个觉,旅个游)。

在没有设置 refresh_intervals 和 numberof_replicas 时,reindex的速度在 500~1000 doc/sec, 如果包含script时可能会更低。设置之后,可以到 4000~8000 doc/sec。 Teambition 70M Documents 大概耗时4小时。

可以使用 可以看到重建进程,其中包含耗时,剩余doc数量等信息。

如果发现错误,可以使用 接口放弃任务,从头再来。

恢复同步数据

重建索引结束后,别忘了在 中的将 和 设为原有值.启动新的同步索引的进程(从记录offset开始同步)

建立新的alias

需要在同时绑定建立的新索引以及解绑旧索引,语句如下:

删掉index

删除旧的 index,释放磁盘空间;停止原有同步进程。

总结

修改索引真的是一件费时费力的工作,特别是如果发生了错误,整个人都不好了。所以还是在创建索引的时候尽量想好能否满足需求,当然大家都知道这是不可能的,因为存在着万恶的产品经理。

这里还有一个很重要的内容没有详细介绍就是同步进程,前面提到同步进程是将 MongoDB 的数据同步到 ES 中去的程序,这个程序同时还需要有能力暂停同步,重复同步的等能力。

最后欢迎大家使用 teambition

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180417G1DNV100?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券