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 中去的程序,這個程序同時還須要有能力暫停同步,重複同步的等能力。