rollover
Elasticsearch 從 5.0 開始,為日志場景的用戶提供了一個很不錯的接口,叫 rollover。其作用是:當某個別名指向的實際索引過大的時候,自動將別名指向下一個實際索引。
因為這個接口是操作的別名,所以我們依然需要首先自己創建一個開始滾動的起始索引:
# curl -XPUT 'http://localhost:9200/logstash-2016.11.25-1' -d '{
"aliases": {
"logstash": {}
}
}'
然后就可以嘗試發起 rollover 請求了:
# curl -XPOST 'http://localhost:9200/logstash/_rollover' -d '{
"conditions": {
"max_age": "1d",
"max_docs": 10000000
}
}'
上面的定義意思就是:當索引超過 1 天,或者索引內的數據量超過一千萬條的時候,自動創建並指向下一個索引。
這時候有幾種可能性:
- 條件都沒滿足,直接返回一個 false,索引和別名都不發生實際變化;
{
"old_index" : "logstash-2016.11.25-1",
"new_index" : "logstash-2016.11.25-1",
"rolled_over" : false,
"dry_run" : false,
"acknowledged" : false,
"shards_acknowledged" : false,
"conditions" : {
"[max_docs: 10000000]" : false,
"[max_age: 1d]" : false
}
}
- 還沒滿一天,滿了一千萬條,那么下一個索引名會是:
logstash-2016.11.25-000002
; - 還沒滿一千萬條,滿了一天,那么下一個索引名會是:
logstash-2016.11.26-000002
。
shrink
Elasticsearch 一直以來都是固定分片數的。這個策略極大的簡化了分布式系統的復雜度,但是在一些場景,比如存儲 metric 的 TSDB、小數據量的日志存儲,人們會期望在多分片快速寫入數據以后,把老數據合並存儲,節約過多的 cluster state 容量。從 5.0 版本開始,Elasticsearch 新提供了 shrink 接口,可以成倍數的合並分片數。
注:所謂成倍數的,就是原來有 15 個分片,可以合並縮減成 5 個或者 3 個或者 1 個分片。
整個合並縮減的操作流程,大概如下:
- 先把所有主分片都轉移到一台主機上;
- 在這台主機上創建一個新索引,分片數較小,其他設置和原索引一致;
- 把原索引的所有分片,復制(或硬鏈接)到新索引的目錄下;
- 對新索引進行打開操作恢復分片數據。
- (可選)重新把新索引的分片均衡到其他節點上。
准備工作
- 因為這個操作流程需要把所有分片都轉移到一台主機上,所以作為 shrink 主機,它的磁盤要足夠大,至少要能放得下一整個索引。
- 最好是一整塊磁盤,因為硬鏈接是不能跨磁盤的。靠復制太慢了。
- 開始遷移:
# curl -XPUT 'http://localhost:9200/metric-2016.11.25/_settings' -d '
{
"settings": {
"index.routing.allocation.require._name": "shrink_node_name",
"index.blocks.write": true
}
}'
shrink 操作
curl -XPOST 'http://localhost:9200/metric-2016.11.25/_shrink/oldmetric-2016.11.25' -d'
{
"settings": {
"index.number_of_replicas": 1,
"index.number_of_shards": 3
},
"aliases": {
"metric-tsdb": {}
}
}'
這個命令執行完會立刻返回,但是 Elasticsearch 會一直等到 shrink 操作完成的時候,才會真的開始做 replica 分片的分配和重均衡,此前分片都處於 initializing 狀態。
注意:Elasticsearch 有一個硬編碼限制,單個分片內的文檔總數不得超過 2147483519 個。一般來說這個限制在日志場景下是不太會觸發的,但是如果做 TSDB 用,則需要多加注意!