Elasticsearch 是一个实时的分布式搜索分析引擎。Teambition 使用 Elastisearch 做为搜索引擎,为用户提供搜索服务,当咱们决定存储某种数据时,咱们须要使用PUT /teambition
建立索引,在建立索引的时候须要将数据结构完整肯定下来,于此同时索引的设定和不少固定配置将用不能改变。当须要改变数据结构时,就须要从新创建索引,为此,Elastic团队提供了不少辅助工具帮助开发人员进行重建索引。git
重建时至关痛苦的,若是没有很好的基础,服务可能中断,当数据量很是大时,重建恢复时间可能很长,甚至在重建过程当中出错等等。因此,没有万不得已的状况下仍是尽可能避免重建索引。Teambition 重建索引的理由略,由于这并不重要。github
kibana 是 Elasticsearch 的最佳拍档,从 ES 5.0 开始,Kibana 强大的功能可以替代几乎全部旧时代 ES 1.x 和 ES 2.x 的插件。关键是人家仍是免费的! json
正在运行的服务必须使用别名(alias)来访问索引(index),缘由很简单,搜索服务最终要使用重建的索引,原始的索引将被删除。若是你的服务正在直接使用索引名,在重建前建立别名,更新服务。api
POST /_aliases
{
"actions": [
{
"add": {
"index": "teambition", // 原有索引
"alias": "teambition_latest" // 服务的别名
}
}
]
}
复制代码
记得查看 Elasticsearch 的 Disk Usage
,若是不够,请先申请好足够的空间。bash
和建立普通索引同样建立新索引。这里值得一提的时,当数据量很大的时候,须要设置刷新时间间隔,在此期间写入的数据不能搜到,从而提升重建速度:refresh_intervals = -1, number_of_replicas = 0
。实践告诉我,大概会提升100% ~ 400%
的提高。数据结构
PUT /teambition_20180328
{
"settings": {...},
"mapping": {...}
}
复制代码
Teambition使用Kafka把MongoDB中的数据导入到Elasticsearch中,若是没有kafka,亦可读取oplog的数据写入Elasticsearch。不管使用哪一种同步数据的方式,都须要记录同步数据的offset。重建索引可能很是耗时,在这段时间内,同步进程仍然在向旧索引更新数据,此时重建索引是没法更新这些新数据的。这里记录的方法就很少说了,Teambition 使用 kafka-admin 的API记录 offset。app
使用 Elasticsearch 团队提供的 reindex api 就能够将数据 copy 到新索引中。这里几条路能够选:分布式
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 开始同步)
须要在同时绑定创建的新索引以及解绑旧索引,语句以下:
POST _aliases
{
"actions": [{"add": {
"index": "teambition_20180328",
"alias": "teambition_latest"
}}, {"remove": {
"index": "teambition",
"alias": "teambition_latest"
}}]
}
复制代码
删除旧的 index,释放磁盘空间;中止原有同步进程。
DELETE teambition
复制代码
修改索引真的是一件费时费力的工做,特别是若是发生了错误,整我的都很差了。因此仍是在建立索引的时候尽可能想好可否知足需求,固然你们都知道这几乎是不可能的,由于存在着万恶的产品经理。
这里还有一个很重要的内容没有详细介绍就是同步进程,前面提到同步进程是将 MongoDB 的数据同步到 ES 中去的程序,这个程序同时还须要有能力暂停同步,重复同步的等能力。