溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

EleasticSearch中怎么利用索引按日期分割

發(fā)布時(shí)間:2021-06-21 15:05:58 來源:億速云 閱讀:754 作者:Leah 欄目:大數(shù)據(jù)

EleasticSearch中怎么利用索引按日期分割,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

文檔中有時(shí)間字段,方便按日期切割
index的mapping配置中,_source需為 true(默認(rèn)),以保證es存入了源文檔,而不僅僅是docId,便于執(zhí)行reindex!
curl -XGET "localhost:9200/your_index_name/_mapping"
# 如果沒有顯示 _source, 代表"_source": false
1
2
2. 刪文檔(不建議)
這第一個(gè)想到的方法,將最老舊的日志刪掉,如只保留近3個(gè)月的,采用 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)并不會(huì)下降。刪除的文檔僅僅被標(biāo)記,es將文檔存入一個(gè)個(gè)segment file中,其file數(shù)量隨著文檔的寫入不斷增加,es因此會(huì)有合并segment file的操作,將多個(gè)小的segment合并成一個(gè)大的segment file,當(dāng)segment合并的時(shí)候,標(biāo)記的文檔才會(huì)真正的物理刪除。

這種方案,只適合在 項(xiàng)目早期、文檔量少、且機(jī)器負(fù)載不高 情況下進(jìn)行,因?yàn)榕孔x寫會(huì)導(dǎo)致cpu utilization的飆升,造成系統(tǒng)負(fù)載加重,可以在晚上業(yè)務(wù)量不高的時(shí)候進(jìn)行

3. 磁盤擴(kuò)容 (短期有效)
那如果標(biāo)記刪除不能立即解決問題,那就對(duì)磁盤擴(kuò)容吧!1T 到 2T,2T 到 4T,由于升級(jí)磁盤需要重啟機(jī)器,所以,如何做到優(yōu)雅滾動(dòng)關(guān)停es至關(guān)重要!

3.1 停止es集群服務(wù)
常見就是ps看一下es的進(jìn)程,然后kill,先等一下!在此之前,需對(duì)集群進(jìn)行配置,方便更加快速的服務(wù)重啟

3.1.1 停止分片分配
由于es中的index是分布式存儲(chǔ),所以一個(gè)index分成了多個(gè)shard,分布在各個(gè)節(jié)點(diǎn)node上,每個(gè)shard都可以單獨(dú)提供服務(wù),同時(shí)每個(gè)shard可以配置多個(gè)副本(replicas),保證集群的高可用,提高了查詢效率。同時(shí),es在管理這些分片時(shí),有一套自有的均衡算法,保證shard均勻分散在各個(gè)node上,同時(shí)保證每個(gè)shard和其對(duì)應(yīng)的replica不在同一node上。正是這種機(jī)制,使得當(dāng)node離開和重新加入的時(shí)候,分片的分配會(huì)copy文件,會(huì)造成大量的io,因?yàn)閚ode重啟很快就回來,所以暫時(shí)關(guān)掉自動(dòng)分片分配,詳情參見另一篇文章,介紹集群重啟步驟。這里選擇直接停止分配

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停掉的時(shí)候,不會(huì)出現(xiàn)分片分配重新均衡了。

3.1.2 掛載新盤
由于機(jī)器是云上資源,因此按照各個(gè)云上的擴(kuò)容文檔操作即可,無論是自有機(jī)房還是云上機(jī)器,無非是下面幾個(gè)步驟:

reboot重啟

df -h 看一下現(xiàn)在的掛載點(diǎn)(如/dev/vdb)和 掛載路徑(如/data/es/)

fdisk -l 可以進(jìn)一步確認(rèn)盤的信息

fdisk /dev/vdb,對(duì)新盤進(jìn)行重新掛載,命令中可能涉及到的選項(xiàng),不分區(qū)的話,大部分按回車默認(rèn)選項(xiàng):d n p 1 wq

其他操作 如e2fsck -f /dev/vdb,resize2fs /dev/vdb

mount /dev/vdb /data 重新掛載即可

3.1.3 恢復(fù)分配分配
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
這一步,會(huì)有部分io,等到recovery結(jié)束,集群恢復(fù)正常。如果有 Unassigned 狀態(tài)的shard,需要手動(dòng)執(zhí)行分片分配,對(duì)應(yīng)的命令reroute,這個(gè)不難,正常情況下,幾乎不會(huì)出現(xiàn) Unassigned 的shard。
執(zhí)行完上述操作,磁盤體積翻倍。在短期內(nèi),可以保證服務(wù)正常。

4. 索引拆分(最佳實(shí)踐)
無論標(biāo)記刪除,還是磁盤擴(kuò)容,都沒有真正的解決索引過大的問題,隨著文檔數(shù)的增加,索引勢(shì)必會(huì)變得更大。針對(duì)大索引,標(biāo)記刪除以及擴(kuò)容后分片恢復(fù)的操作時(shí)間,也會(huì)大幅增加,可能會(huì)從幾小時(shí)到一兩天。上述方法不可行!

因?yàn)閑s對(duì)index的刪除是物理刪除,是立即的,既然不能直接刪除原索引,得想辦法把大索引拆成小索引,然后再刪除老舊的。那么es有么有這種api,將大的索引按照某種條件(按天、按月)進(jìn)行拆分呢?為此,我找了很多博客,最后發(fā)現(xiàn),很多博客里介紹的api都很老舊,還是官網(wǎng)的文檔最實(shí)在,文檔是英文,不過理解起來并不復(fù)雜。墻裂推薦看官方文檔。為此,我調(diào)研了這些api:_rollover,alias,template,reindex,大家可以有針對(duì)的深入學(xué)習(xí)這幾個(gè)api,細(xì)節(jié)這里就不講了,先看我怎么用的吧~

4.1. 錯(cuò)誤嘗試
_rollover 當(dāng)看到這個(gè)api時(shí),我以為找到了最接近需求的api,這個(gè)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", #當(dāng)文檔創(chuàng)建時(shí)間大于7天
    "max_docs":  1000, #當(dāng)文檔數(shù)量超過上限1000
    "max_size":  "5gb" #當(dāng)索引大小超過5GB
  }
}
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
思路:

先給 index 建一個(gè)別名 alias,再 rollover,當(dāng)執(zhí)行時(shí),滿足任一個(gè)條件即可創(chuàng)建新索引,同時(shí)別名 alias 指向新的,除此之外,_rollover還可以按日期生成新索引

問題:

拆分只在api執(zhí)行時(shí)生效,后面不會(huì)自動(dòng)拆分,如果按天索引,則必須每天定時(shí)執(zhí)行,增加維護(hù)成本,如果定時(shí)任務(wù)失敗…
當(dāng)別名滾向新的索引后,舊索引不能通過 alias 再訪問
并沒有將歷史的索引按天生成,只是在此api執(zhí)行后,新文檔才會(huì)進(jìn)新index
4.2 最佳實(shí)踐
假設(shè)原索引name knight-log,當(dāng)前月份 2019-02

思路:

創(chuàng)建別名alias:alias-knight-log
為舊的 knight-log 關(guān)聯(lián)別名 alias-knight-log
創(chuàng)建索引模板template: template-knight-log,該模板匹配所有 knight-log.* 索引,在模板中定義settings和mappings,以及自動(dòng)關(guān)聯(lián)別名 alias-knight-log
此外,將項(xiàng)目中讀寫es的操作分別設(shè)置:

讀 alias-knight-log,可以查詢所有關(guān)聯(lián)索引
寫 knight-log.2019-02,在原索引后append月份即可!調(diào)用Java api進(jìn)行索引時(shí),接口規(guī)定每條文檔需要指定index name,因此將原來的 name 變?yōu)?name + current_month 即可,其他語言同理!
更新業(yè)務(wù)代碼,重新上線后,新文檔會(huì)進(jìn)入到形如 knight-log.2019-02 的索引中,原 knight-log 將不會(huì)有寫請(qǐng)求,讀請(qǐng)求也經(jīng)過別名 alias-knight-log 代理了

經(jīng)過上述步驟,舊的index只讀不寫,寫請(qǐng)求全部進(jìn)入 knight-log.2019-02 的索引中,保障了這一點(diǎn),我們就可以對(duì) knight-log 按時(shí)間粒度以大化小,逐個(gè)刪除了!

Sad,沒有這種直接的api,不過,不起眼的reindex卻承擔(dān)起這個(gè)重任,一開始我覺得跟這個(gè)api應(yīng)該沒有關(guān)系,不僅不省空間,反而還翻倍,直到發(fā)現(xiàn)可以按條件reindex后,眼前一亮!我按時(shí)間條件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之前,為了加快索引,可以對(duì)新index設(shè)置,常規(guī)的批量索引設(shè)置注意項(xiàng),這里也適用,如:replicas=0,refresh_interval=-1

tips2:第一次使用reindex,沒有開啟slice(相當(dāng)于多線程),io和cpu雖然都不高,但很慢,可適當(dāng)開啟,但注意slice不要超過index的shard數(shù),看官方文檔,此處不多提!

tips3:如果一個(gè)月的文檔數(shù)太多,不放心一次性操作,你可以嘗試先按天reindex到新月份index中,這樣可以觀察cup和io,然后適當(dāng)調(diào)整reindex相關(guān)參數(shù)后,再把當(dāng)月余下天數(shù)的文檔全部reindex到新index中

tips4:當(dāng)進(jìn)行完一次reindex,恢復(fù) refresh_interval 后,可以對(duì)新舊索引同時(shí)查詢,看文檔數(shù)是否一致!確保無異常!

tips5:手誤執(zhí)行reindex,可以中途取消本次task

將 knight-log 的replicas數(shù)從默認(rèn)的1 變?yōu)?0,這樣整個(gè)index省掉一半大?。ǚ潜仨?,剩余磁盤多可以忽略),然后,對(duì) knight-log 按月份進(jìn)行reindex,這樣反復(fù)操作幾次,可完成近幾月的備份,形如 knight-log.2019-01,knight-log.2018-12 等(不要忘記2月的舊文檔哦,同樣需要reindex,這樣2月的index才會(huì)完整),同時(shí)因?yàn)槟0宓奶匦?,月份索引?huì)自動(dòng)加上 alias-knight-log 這個(gè)別名,一舉兩得!

reindex完必要的數(shù)據(jù)后(如近3月),就可以直接刪掉 knight-log!

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI