您好,登錄后才能下訂單哦!
EleasticSearch中怎么利用索引按日期分割,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
文檔中有時間字段,方便按日期切割
index的mapping配置中,_source需為 true(默認),以保證es存入了源文檔,而不僅僅是docId,便于執行reindex!
curl -XGET "localhost:9200/your_index_name/_mapping"
# 如果沒有顯示 _source, 代表"_source": false
1
2
2. 刪文檔(不建議)
這第一個想到的方法,將最老舊的日志刪掉,如只保留近3個月的,采用 delete_by_query 接口
curl -X POST "localhost:9200/twitter/_delete_by_query" -H 'Content-Type: application/json' -d'
{
"query": {
"range" : {
"day" : {
"lt" : "2018-12-01"
}
}
}
}
'
1
2
3
4
5
6
7
8
9
10
11
但是,es的delete,并不是真正的物理刪,磁盤使用率(utilization)并不會下降。刪除的文檔僅僅被標記,es將文檔存入一個個segment file中,其file數量隨著文檔的寫入不斷增加,es因此會有合并segment file的操作,將多個小的segment合并成一個大的segment file,當segment合并的時候,標記的文檔才會真正的物理刪除。
這種方案,只適合在 項目早期、文檔量少、且機器負載不高 情況下進行,因為批量讀寫會導致cpu utilization的飆升,造成系統負載加重,可以在晚上業務量不高的時候進行
3. 磁盤擴容 (短期有效)
那如果標記刪除不能立即解決問題,那就對磁盤擴容吧!1T 到 2T,2T 到 4T,由于升級磁盤需要重啟機器,所以,如何做到優雅滾動關停es至關重要!
3.1 停止es集群服務
常見就是ps看一下es的進程,然后kill,先等一下!在此之前,需對集群進行配置,方便更加快速的服務重啟
3.1.1 停止分片分配
由于es中的index是分布式存儲,所以一個index分成了多個shard,分布在各個節點node上,每個shard都可以單獨提供服務,同時每個shard可以配置多個副本(replicas),保證集群的高可用,提高了查詢效率。同時,es在管理這些分片時,有一套自有的均衡算法,保證shard均勻分散在各個node上,同時保證每個shard和其對應的replica不在同一node上。正是這種機制,使得當node離開和重新加入的時候,分片的分配會copy文件,會造成大量的io,因為node重啟很快就回來,所以暫時關掉自動分片分配,詳情參見另一篇文章,介紹集群重啟步驟。這里選擇直接停止分配
curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'
{
"persistent": {
"cluster.routing.allocation.enable": "none"
}
}'
1
2
3
4
5
6
這樣,在node停掉的時候,不會出現分片分配重新均衡了。
3.1.2 掛載新盤
由于機器是云上資源,因此按照各個云上的擴容文檔操作即可,無論是自有機房還是云上機器,無非是下面幾個步驟:
reboot重啟
df -h 看一下現在的掛載點(如/dev/vdb)和 掛載路徑(如/data/es/)
fdisk -l 可以進一步確認盤的信息
fdisk /dev/vdb,對新盤進行重新掛載,命令中可能涉及到的選項,不分區的話,大部分按回車默認選項:d n p 1 wq
其他操作 如e2fsck -f /dev/vdb,resize2fs /dev/vdb
mount /dev/vdb /data 重新掛載即可
3.1.3 恢復分配分配
curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'
{
"transient": {
"cluster.routing.allocation.enable": "all"
}
}
'
1
2
3
4
5
6
7
這一步,會有部分io,等到recovery結束,集群恢復正常。如果有 Unassigned 狀態的shard,需要手動執行分片分配,對應的命令reroute,這個不難,正常情況下,幾乎不會出現 Unassigned 的shard。
執行完上述操作,磁盤體積翻倍。在短期內,可以保證服務正常。
4. 索引拆分(最佳實踐)
無論標記刪除,還是磁盤擴容,都沒有真正的解決索引過大的問題,隨著文檔數的增加,索引勢必會變得更大。針對大索引,標記刪除以及擴容后分片恢復的操作時間,也會大幅增加,可能會從幾小時到一兩天。上述方法不可行!
因為es對index的刪除是物理刪除,是立即的,既然不能直接刪除原索引,得想辦法把大索引拆成小索引,然后再刪除老舊的。那么es有么有這種api,將大的索引按照某種條件(按天、按月)進行拆分呢?為此,我找了很多博客,最后發現,很多博客里介紹的api都很老舊,還是官網的文檔最實在,文檔是英文,不過理解起來并不復雜。墻裂推薦看官方文檔。為此,我調研了這些api:_rollover,alias,template,reindex,大家可以有針對的深入學習這幾個api,細節這里就不講了,先看我怎么用的吧~
4.1. 錯誤嘗試
_rollover 當看到這個api時,我以為找到了最接近需求的api,這個api介紹如下
The rollover index API rolls an alias over to a new index when the existing index is considered to be too large or too old.
顯然被 too large 和 too old 吸引了。。。
curl -X PUT "localhost:9200/logs-000001" -H 'Content-Type: application/json' -d'
{
"aliases": {
"logs_write": {}
}
}
'
# Add > 1000 documents to logs-000001
curl -X POST "localhost:9200/logs_write/_rollover" -H 'Content-Type: application/json' -d'
{
"conditions": {
"max_age": "7d", #當文檔創建時間大于7天
"max_docs": 1000, #當文檔數量超過上限1000
"max_size": "5gb" #當索引大小超過5GB
}
}
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
思路:
先給 index 建一個別名 alias,再 rollover,當執行時,滿足任一個條件即可創建新索引,同時別名 alias 指向新的,除此之外,_rollover還可以按日期生成新索引
問題:
拆分只在api執行時生效,后面不會自動拆分,如果按天索引,則必須每天定時執行,增加維護成本,如果定時任務失敗…
當別名滾向新的索引后,舊索引不能通過 alias 再訪問
并沒有將歷史的索引按天生成,只是在此api執行后,新文檔才會進新index
4.2 最佳實踐
假設原索引name knight-log,當前月份 2019-02
思路:
創建別名alias:alias-knight-log
為舊的 knight-log 關聯別名 alias-knight-log
創建索引模板template: template-knight-log,該模板匹配所有 knight-log.* 索引,在模板中定義settings和mappings,以及自動關聯別名 alias-knight-log
此外,將項目中讀寫es的操作分別設置:
讀 alias-knight-log,可以查詢所有關聯索引
寫 knight-log.2019-02,在原索引后append月份即可!調用Java api進行索引時,接口規定每條文檔需要指定index name,因此將原來的 name 變為 name + current_month 即可,其他語言同理!
更新業務代碼,重新上線后,新文檔會進入到形如 knight-log.2019-02 的索引中,原 knight-log 將不會有寫請求,讀請求也經過別名 alias-knight-log 代理了
經過上述步驟,舊的index只讀不寫,寫請求全部進入 knight-log.2019-02 的索引中,保障了這一點,我們就可以對 knight-log 按時間粒度以大化小,逐個刪除了!
Sad,沒有這種直接的api,不過,不起眼的reindex卻承擔起這個重任,一開始我覺得跟這個api應該沒有關系,不僅不省空間,反而還翻倍,直到發現可以按條件reindex后,眼前一亮!我按時間條件reindex不就好了嘛~~
# 將 2019-01 月的文檔, 全部 reindex 到 knight-log.2019-01 中
curl -X POST "localhost:9200/_reindex" -H 'Content-Type: application/json' -d'
{
"source": {
"index": "knight-log",
"type": "your_doc_type",
"query": {
"bool": {
"filter": {
"range": {
"day": {
"gte": "2019-01-01",
"lt": "2019-02-01"
}
}
}
}
}
},
"dest": {
"index": "knight-log.2019-01"
}
}
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
tips1: 在reindex到新index之前,為了加快索引,可以對新index設置,常規的批量索引設置注意項,這里也適用,如:replicas=0,refresh_interval=-1
tips2:第一次使用reindex,沒有開啟slice(相當于多線程),io和cpu雖然都不高,但很慢,可適當開啟,但注意slice不要超過index的shard數,看官方文檔,此處不多提!
tips3:如果一個月的文檔數太多,不放心一次性操作,你可以嘗試先按天reindex到新月份index中,這樣可以觀察cup和io,然后適當調整reindex相關參數后,再把當月余下天數的文檔全部reindex到新index中
tips4:當進行完一次reindex,恢復 refresh_interval 后,可以對新舊索引同時查詢,看文檔數是否一致!確保無異常!
tips5:手誤執行reindex,可以中途取消本次task
將 knight-log 的replicas數從默認的1 變為 0,這樣整個index省掉一半大小(非必須,剩余磁盤多可以忽略),然后,對 knight-log 按月份進行reindex,這樣反復操作幾次,可完成近幾月的備份,形如 knight-log.2019-01,knight-log.2018-12 等(不要忘記2月的舊文檔哦,同樣需要reindex,這樣2月的index才會完整),同時因為模板的特性,月份索引會自動加上 alias-knight-log 這個別名,一舉兩得!
reindex完必要的數據后(如近3月),就可以直接刪掉 knight-log!
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。