序言
Elasticsearch 是一个实时的分布式搜索分析引擎。Teambition 使用 Elastisearch 作为搜索引擎,为用户提供搜索服务,当我们决定存储某种数据时,我们需要使用PUT /teambition
创建索引,在创建索引的时候需要将数据结构完整确定下来,于此同时索引的设定和很多固定配置将用不能改变。当需要改变数据结构时,就需要重新建立索引,为此,Elastic团队提供了很多辅助工具帮助开发人员进行重建索引。
决定是否需要重建?
重建时相当痛苦的,如果没有很好的基础,服务可能中断,当数据量非常大时,重建恢复时间可能很长,甚至在重建过程中出错等等。所以,没有万不得已的情况下还是尽量避免重建索引。Teambition 重建索引的理由略,因为这并不重要。
使用正确的工具
kibana 是 Elasticsearch 的最佳拍档,从 ES 5.0 开始,Kibana 强大的功能能够替代几乎所有旧时代 ES 1.x 和 ES 2.x 的插件。关键是人家还是免费的!
先决条件
正在运行的服务必须使用别名(alias)来访问索引(index),原因很简单,搜索服务最终要使用重建的索引,原始的索引将被删除。如果你的服务正在直接使用索引名,在重建前创建别名,更新服务。
POST /_aliases
{
"actions": [
{
"add": {
"index": "teambition", // 原有索引
"alias": "teambition_latest" // 服务的别名
}
}
]
}
先决条件2
记得查看 Elasticsearch 的 Disk Usage
,如果不够,请先申请好足够的空间。
创建新索引
和创建普通索引一样创建新索引。这里值得一提的时,当数据量很大的时候,需要设置刷新时间间隔,在此期间写入的数据不能搜到,从而提高重建速度:refresh_intervals = -1, number_of_replicas = 0
。实践告诉我,大概会提高100% ~ 400%
的提升。
PUT /teambition_20180328
{
"settings": {...},
"mapping": {...}
}
记录同步数据的偏移值(offset)
Teambition使用Kafka把MongoDB中的数据导入到Elasticsearch中,如果没有kafka,亦可读取oplog的数据写入Elasticsearch。无论使用哪种同步数据的方式,都需要记录同步数据的offset。重建索引可能非常耗时,在这段时间内,同步进程仍然在向旧索引更新数据,此时重建索引是无法更新这些新数据的。这里记录的方法就不多说了,Teambition 使用 kafka-admin 的API记录 offset。
开始重建索引
使用 Elasticsearch 团队提供的 reindex api 就可以将数据 copy 到新索引中。这里几条路可以选:
- 当只是改变 mapping 数据结构时,可以仅仅使用 reindex api 即可。例如:删除字段,更新字段分词方式等。
- 当需要写入新的字段,新的字段是由老的字段计算得到时,可以使用
script
参数。例如,计算某条数据某字段的总和。script 有很多坑,当 script 出错时,reindex 跑了很久之后失败,即使将数据恢复,也需要重新跑 reindex。 - 当含有很复杂的逻辑时,额,还是自己写程序吧。
调用 reindex 接口,接口将会在 reindex 结束后返回,而接口返回超时只有30秒
,如果 reindex 时间过长,建议加上wait_for_completion=false
的参数条件,这样 reindex 将直接返回taskId
POST _reindex?wait_for_completion=false
{
"source": {
"index": "teambition"
},
"dest": {
"index": "teambition_20180328"
},
"script": {...}
}
重建索引中
重建索引非常耗时,喝杯咖啡歇一会儿吧(顺便去打个球,睡个觉,旅个游)。
在没有设置 refresh_intervals
和 number_of_replicas
时,reindex 的速度在 500~1000 doc/sec, 如果包含 script 时可能会更低。设置之后,可以到 4000~8000 doc/sec。 Teambition 70M Documents 大概耗时4小时。
可以使用GET _tasks/{taskID}
可以看到重建进程,其中包含耗时,剩余doc数量等信息。
如果发现错误,可以使用PUT _tasks/{taskID}/cancel
接口放弃任务,从头再来。
恢复同步数据
重建索引结束后,别忘了在setting
中的将number_of_replicas
和refresh_intervals
设为原有值. 启动新的同步索引的进程(从记录 offset 开始同步)
建立新的alias
需要在同时绑定建立的新索引以及解绑旧索引,语句如下:
POST _aliases
{
"actions": [{"add": {
"index": "teambition_20180328",
"alias": "teambition_latest"
}}, {"remove": {
"index": "teambition",
"alias": "teambition_latest"
}}]
}
删掉index
删除旧的 index,释放磁盘空间;停止原有同步进程。
DELETE teambition
总结
修改索引真的是一件费时费力的工作,特别是如果发生了错误,整个人都不好了。所以还是在创建索引的时候尽量想好能否满足需求,当然大家都知道这几乎是不可能的,因为存在着万恶的产品经理。
这里还有一个很重要的内容没有详细介绍就是同步进程,前面提到同步进程是将 MongoDB 的数据同步到 ES 中去的程序,这个程序同时还需要有能力暂停同步,重复同步的等能力。
今天的文章教你如何在 elasticsearch 中重建索引分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/17931.html