閱讀完本文你可以學到什麼是索引生命週期管理,各個階段可以做的操作以及如何使用索引模版使用索引生命週期策略,下面就跟我一起來吧
基礎理論篇
索引生命週期管理(ILM)是一種可以讓我們隨著時間推移自動化的管理索引的一種方式。我們可以根據效能,索引文件數量、大小等彈性要求,文件的保留需求等方面來自定義索引生命週期管理策略,我們可以使用ILM實現如下需求
- 當索引達到一定的大小或者一定的文件數量時生成一個新的索引
- 每天、每週或者每個月建立一個新索引、並把之前的索引歸檔
- 刪除歷史索引、按照資料保留標準執行是否保留索引
在ILM策略期間可以觸發的操作有:Set Priority,Unfollow,Rollover,Read-only,Shrink,Force merge,Searchable snapshot,Allocate,Migrate,Wait for snapshot,Delete
下面是每個操作具體的含義
Set Priority
可應用階段:
Hot
,Warm
,Cold
設定步驟的優先順序
必須引數,設定索引優先順序,大於等於
0
的整數;設定為null
刪除優先順序;Hot
階段應具有最高值,Cold
應具有最低值;例如Hot 100
,Warm 50
,Cold 0
;未設定此值的索引優先順序預設為1
Unfollow
可應用階段:
Hot
,Warm
,Cold
,Frozen
跨叢集索引設定為標準索引,可以使
shrink
、rollover
、searchable snapshot
操作安全的在follower
索引上執行;在整個生命週期中移動
follower
索引時,也可以直接使用unfollow
,對於不是follower
索引的沒有影響、階段執行中只是跳轉到下一個操作當
shrink
、rollover
、searchable snapshot
應用於follower
索引時,該操作會自動觸發follower
索引安全轉換為標準索引需要滿足以下條件leader
索引index.lifecycle.indexing_complete
設定為true
。如果是rollover
操作,則會自動設定此設定,或者使用index settings api
手動設定- 對
leader
索引執行的操作都已經複製到follower
索引,這樣可以確保在轉換索引時不會丟失任何操作
當上述條件都滿足後,
unfollow
將執行以下操作- 暫停
follower
索引的索引 - 關閉
follower
索引 - 取消
leader
索引 - 開啟
follower
索引(此時是標準索引)
Rollover
滾動策略,也就是按照策略遞增的實現方式;
當前索引達到一定的大小、或者一定文件的數量或者年齡時自動建立一個新的寫索引
可應用階段:
Hot
如果該操作是在
follower
索引上執行,那麼該操作將等待leader
索引執行該操作完成rollover
的目標可以是資料流或者索引別名當滾動目標是
資料流
時,這個生成的新索引將成為資料流的寫入索引,並且索引名是遞增
的當滾動目前是
索引別名
時,別名以及其寫索引需要滿足以下條件(重要!!!重要!!!重要!!!)- 索引名稱必須滿足如下匹配規則
^.\*-\d+$
- 索引的滾動目標別名
index.lifecycle.rollover_alias
必須要設定 - 該索引必須是索引的
寫入
索引
例如:索引
my-index-001
別名為my_data
,如下配置是必須的PUT my-index-001 { "settings": { "index.lifecycle.name": "my_policy", "index.lifecycle.rollover_alias": "my_data" }, "aliases": { "my_data": { "is_write_index": true } } }
上面我們看到
rollover
的操作需要滿足一種條件,那麼我們必須至少設定一種捲軸件max_age
:從索引建立之日起開始計算時間,滿足之後觸發滾動操作。例如1d
,7d
,30d
;即使我們透過index.lifecycle.parse_origination_date
或者index.lifecycle.origination_date
來設定索引的起始日期,計算時也是按照索引建立時的日期max_docs
:達到指定的最大文件數量之後觸發滾動操作。上一次refresh
之後的文件不計數,副本分片中的文件也不計數max_size
:當索引中所有的主分片之和達到一定的大小時觸發滾動操作,副本分片不計算入最大索引大小在使用
_cat API
時,pri.store.size
的值就是主分片的大小max_primary_shard_size
:當索引中最大的主分片達到一定的大小時觸發滾動操作,這是索引中最大主分片的最大大小。與max_size
一樣,副本分片大小也不計入其中
- 索引名稱必須滿足如下匹配規則
Read-only
可應用階段:
Hot
,Warm
,Cold
使索引變為只讀索引,如果要在
Hot
階段執行Read-only
操作,前提是必須執行rollover
操作,如果沒有配置rollover
操作,ILM將拒絕Read-only
策略Shrink
可應用階段:
Hot
,Warm
前提:將源索引設定為只讀;所有分片必須在同一個節點上;叢集健康狀態為
Green
;減少索引分片的數量或者減少主分片的數量,生成的索引名為
shrink-<random-uuid>-<original-index-name>
,分片數量使用如下引數控制number_of_shards
:可選整數型別,必須為現有索引分片數整除的數字,與max_primary_shard_size
不相容,只能設定一個max_primary_shard_size
:可選位元組單位(b,kb,mb,gb,tb,pb),目標索引的最大主分片的大小,用於查詢目標索引的最大分片數,設定此引數後,每個分片在目標索引的儲存佔用不會大於該引數
Force merge
可應用階段:
Hot
,Warm
合併索引中的
segments
到指定的最大段數,此操作會將索引設定為Read-only
;強制合併會盡最大的努力去合併,如果此時有的分片在重新分配,那麼該分片是無法被合併的如果我們要在
Hot
階段執行Force merge
操作,rollover
操作是必須的,如果沒有配置rollover
,ILM會拒絕該策略max_num_segments
:必須的整數型別,表示要合併到的segments
數量,如果要完全合併索引,需要設定值為1
index_codec
:可選字串引數,壓縮文件的編解碼器,只能設定best_compression
,它可以獲得更高的壓縮比,但是儲存效能較差。該引數預設值LZ4
,如果要使用LZ4
,此引數可不用設定
Searchable snapshot
可應用階段:
Hot
,Cold
,Forzen
將快照掛載為可搜尋的索引。如果索引是資料流的一部分,則掛載的索引將替換資料流中的原始索引
Searchable snapshot操作繫結對應的資料層,也就是(Hot-Warm-Cold-Forzen-Delete),恢復資料時直接恢復到對應的資料層,該操作使用
index.routing.allocation.include._tier_preference
設定,在凍結層(frozen)該操作會將字首為partial-
的部分資料恢復到凍結層,在其他層,會將字首為restored-
的全部資料恢復到對應層Allocate
可應用階段:
Warm
,Cold
設定副本數量,修改分片分配規則。將分片移動到不同效能特徵的節點上並減少副本的數量,該操作不可在
Hot
階段執行,初始的分配必須透過手動設定或者索引模版設定。如果配置該設定必須指定副本的數量,或者至少指定如下操作的一個(include,exclude,require),如果不設定分配策略即空的分配策略是無效的number_of_replicas
:整數型別,分配給索引的副本數total_shards_per_node
:單個ES節點上索引最大分片數,-1
代表沒有限制include
:為至少具有一個自定義屬性的節點分配索引exclude
:為沒有指定自定義屬性的節點分配索引require
:為具有所有指定自定義屬性的節點分配索引
elasticsearch.yml
中自定義屬性# 節點增加屬性,在elasticsearch.yml裡面 node.attr.{attribute}: {value} # 例如:增加一個node_type屬性 node.attr.node_type: hot # 索引分配過濾器設定 index.routing.allocation.include.{attribute} index.routing.allocation.exclude.{attribute} index.routing.allocation.require.{attribute}
Migrate
可應用階段:
Warm
,Cold
透過更新
index.routing.allocation.include._tier_preference
設定,將索引移動到當前階段對應的資料層ILM自動的在
Warm
和Cold
階段開啟該操作,如果我們不想自動開啟可以透過設定enabled
為false
來關閉- 如果在
Cold
階段定義了一個可搜尋的快照(Searchable snapshot)動作,那麼將不會自動注入Migrate
操作,因為Migrate
與Searchable snapshot
使用相同的index.routing.allocation.include._tier_preference
設定 - 在
Warm
階段,Migrate
操作會設定index.routing.allocation.include._tier_preference
為data_warm
,data_hot
。意思就是這會將索引移動到Warm
層的節點上,如果Warm
層沒有,那就返回到Hot
層節點 - 在
Cold
階段,Migrate
操作會設定index.routing.allocation.include._tier_preference
為data_cold
,data_warm
,data_hot
。這會將索引移動到Cold
層,如果Cold
層沒有返回到Warm
層,如果還沒有可用的節點,返回到Hot
層 - 在
Frozen
階段不允許遷移操作,Migrate
操作會設定index.routing.allocation.include._tier_preference
為data_frozen
,data_cold
,data_warm
,data_hot
。凍結階段直接使用此配置掛載可搜尋的映象,這會將索引移動到(frozen
)凍結層,如果凍結層沒有節點,它會返回Cold
層,依次是Warm
層,Hot
層 - 在
Hot
階段是不被允許遷移操作的,初始的索引分配是自動執行的,我們也可以透過索引模版配置
該階段可選的配置引數如下
enabled
:可選布林值,控制ILM是否在此階段遷移索引,預設true
- 如果在
Wait for snapshot
可應用階段:
Delete
在刪除索引之前等待指定的
SLM
策略執行,這樣可以確保已刪除索引的快照是可用的policy
:必須的字串引數,刪除操作應等待的SLM策略的名稱
Delete
可應用階段:
Delete
永久的刪除索引
delete_searchable_snapshot
:刪除在上一個階段建立的可搜尋快照,預設true
ILM可以很輕鬆的管理索引的各個階段,常見的就是處理日誌型別或者度量值等時間序列的資料
需要注意的是,ILM要生效的前提是叢集中所有的節點都必須是使用相同的版本。雖說可以在混合版本匯中建立或者應用ILM,但是不能保證ILM按照預期的策略執行
下面我們就詳細說一下索引生命週期的幾個階段
Hot
:頻繁的查詢、更新Warm
:索引不在被更新、但是還有查詢Cold
:索引不在被更新、但是還有少量查詢,索引的內容仍然需要被檢索、檢索的速度快慢沒關係Frozen
:索引不在被更新、但是還有少量查詢,索引的內容仍然需要被檢索、檢索的速度非常慢也沒關係Delete
:索引不在需要,可以安全的刪除
在上面的這幾個階段中,每個階段的執行操作是不同的以及從一個階段轉到另一個階段的時間也是不固定的
操作 | Hot | Warm | Cold | Frozen | Delete |
---|---|---|---|---|---|
Set Priority | ✓ | ✓ | ✓ | ||
Unfollow | ✓ | ✓ | ✓ | ✓ | |
Rollover | ✓ | ||||
Read-only | ✓ | ✓ | ✓ | ||
Shrink | ✓ | ✓ | |||
Force merge | ✓ | ✓ | |||
Searchable snapshot | ✓ | ✓ | ✓ | ||
Allocate | ✓ | ✓ | |||
Migrate | ✓ | ✓ | |||
Wait for snapshot | ✓ | ||||
Delete | ✓ |
透過上面的學習我們知道了ILM相關的基本概念,下面我們進入實操環節,首先ILM策略的使用可以直接繫結索引,也可以在索引模版建立時繫結使用,下面跟我一起來操作起來吧
環境資訊
Docker
部署,yml
檔案中具體對映檔案地址自行修改,可以替換D:\zuiyuftp\docker\es8.1\
為自己本地檔案路徑
需要注意的是,ES三個節點指定不同的自定義屬性
// eshot節點
node.attr.node_type=hot
// eswarm節點
node.attr.node_type=warm
// escold節點
node.attr.node_type=cold
windows docker啟動中如遇到vm最大限制錯誤可使用如下命令修改
1、開啟終端
wsl -d desktop
sysctl -w vm.max_map_count=262144
exit
docker-compose.yml
version: '3.8' services: cerebro: image: lmenezes/cerebro:0.8.3 container_name: cerebro ports: - "9000:9000" command: - -Dhosts.0.host=http://eshot:9200 networks: - elastic kibana: image: docker.elastic.co/kibana/kibana:8.1.3 container_name: kibana environment: - I18N_LOCALE=zh-CN - XPACK_GRAPH_ENABLED=true - TIMELION_ENABLED=true - XPACK_MONITORING_COLLECTION_ENABLED="true" - ELASTICSEARCH_HOSTS=http://eshot:9200 ports: - "5601:5601" networks: - elastic eshot: image: elasticsearch:8.1.3 container_name: eshot environment: - node.name=eshot - cluster.name=es-docker-cluster - discovery.seed_hosts=eshot,eswarm,escold - cluster.initial_master_nodes=eshot,eswarm,escold - bootstrap.memory_lock=true - "ES_JAVA_OPTS=-Xms512m -Xmx512m" - xpack.security.enabled=false - node.attr.node_type=hot ulimits: memlock: soft: -1 hard: -1 volumes: - D:\zuiyuftp\docker\es8.1\eshot\data:/usr/share/elasticsearch/data - D:\zuiyuftp\docker\es8.1\eshot\logs:/usr/share/elasticsearch/logs ports: - 9200:9200 networks: - elastic eswarm: image: elasticsearch:8.1.3 container_name: eswarm environment: - node.name=eswarm - cluster.name=es-docker-cluster - discovery.seed_hosts=eshot,eswarm,escold - cluster.initial_master_nodes=eshot,eswarm,escold - bootstrap.memory_lock=true - "ES_JAVA_OPTS=-Xms512m -Xmx512m" - xpack.security.enabled=false - node.attr.node_type=warm ulimits: memlock: soft: -1 hard: -1 volumes: - D:\zuiyuftp\docker\es8.1\eswarm\data:/usr/share/elasticsearch/data - D:\zuiyuftp\docker\es8.1\eswarm\logs:/usr/share/elasticsearch/logs networks: - elastic escold: image: elasticsearch:8.1.3 container_name: escold environment: - node.name=escold - cluster.name=es-docker-cluster - discovery.seed_hosts=eshot,eswarm,escold - cluster.initial_master_nodes=eshot,eswarm,escold - bootstrap.memory_lock=true - "ES_JAVA_OPTS=-Xms512m -Xmx512m" - xpack.security.enabled=false - node.attr.node_type=cold ulimits: memlock: soft: -1 hard: -1 volumes: - D:\zuiyuftp\docker\es8.1\escold\data:/usr/share/elasticsearch/data - D:\zuiyuftp\docker\es8.1\escold\logs:/usr/share/elasticsearch/logs networks: - elastic networks: elastic: driver: bridge
啟動成功之後瀏覽器進入 http://host:5601 管理頁面,輸入
GET _cat/nodeattrs
檢視ES叢集啟動資訊,返回如下所示
ILM驗證
如果索引具有未分配的碎片,並且叢集執行狀況為黃色,則該索引仍然可以根據其索引生命週期管理策略過渡到下一階段。然而,由於Elasticsearch只能在綠色叢集上執行某些清理任務,因此可能會產生意想不到的副作用。
建立索引生命週期策略
開啟Kibana,找到Stack Management頁面開啟
開啟索引生命週期策略,點選建立策略
輸入策略名稱
配置熱階段屬性
關閉【使用建議的預設值】,配置文件數量最大為10個的時候發生滾動索引,其他暫不配置,如有需要可自行測試
配置熱階段索引優先順序
100
點選溫階段開關,開啟溫階段
配置為5分鐘後移動到此階段(實際使用根據自身場景設定,此處僅為測試)
- 點選高階設定配置溫階段高階屬性
- 配置縮小分片數量為
1
選中資料分配,配置為定製屬性
選擇節點屬性為
warm
節點配置溫階段索引優先順序
50
開啟冷階段
- 配置5分鐘後移動到該階段(實際使用根據自身場景設定,此處僅為測試)
與上一步
warm
節點類似,冷階段資料分配選擇cold
節點配置冷階段索引優先順序
0
開啟刪除階段
設定
一天
之後索引刪除儲存策略
到此、一個完整的索引生命週期策略就建立完成了,以上我們只是做測試,具體數值使用中還是要根據實際場景設定,上面演示了一個完整的索引生命週期,下面是使用語句建立,也就是上面我們圖形化建立的東西使用API建立
使用API建立ILM
PUT _ilm/policy/zuiyu_policy { "policy": { "phases": { "hot": { "actions": { "rollover": { "max_docs": 10 }, "set_priority": { "priority": 100 } }, "min_age": "0ms" }, "warm": { "min_age": "5m", "actions": { "shrink": { "number_of_shards": 1 }, "set_priority": { "priority": 50 }, "allocate": { "require": { "node_type": "warm" } } } }, "cold": { "min_age": "5m", "actions": { "set_priority": { "priority": 0 }, "allocate": { "require": { "node_type": "cold" } } } }, "delete": { "min_age": "1d", "actions": { "delete": {} } } } } }
建立索引模版
指定分片數量為3
,副本分片為0
,生命週期策略為zuiyu_policy
,rollover
操作時別名為zuiyu-index
,索引分配策略為 "node_type":"hot"
,匹配索引模式為zuiyu-
開頭的索引名
PUT _index_template/zuiyu_template
{
"index_patterns": ["zuiyu-*"],
"template":{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0,
"index.lifecycle.name": "zuiyu_policy",
"index.lifecycle.rollover_alias": "zuiyu-index" ,
"index.routing.allocation.require.node_type":"hot"
}
}
}
建立測試索引
分片數量3
,索引別名zuiyu-index
PUT zuiyu-000001
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0
},
"aliases": {
"zuiyu-index": {}
}
}
檢視分片分佈可以看到,所有的分片都按照分配策略分不到了hot
節點上,訪問cerebro可看到如下(http://host:9000)
插入測試文件
連續執行多次,大於10次即可
POST zuiyu-index/_doc
{
"id":"zuiyu index",
"content":"ilm alias insert content"
}
檢視文件數量
GET zuiyu-index/_count
// 返回結果如下
{
"count" : 21,
"_shards" : {
"total" : 3,
"successful" : 3,
"skipped" : 0,
"failed" : 0
}
}
我在上面插入了21
條資料,按照剛才我們定義的ILM,在文件數量大於10
個的時候會發生rollover操作,滾動生成一個新的索引(具體索引名規則、不生效約束檢視前文rollover小節)
驗證ILM策略
- 開啟Kibana,找到定義的
zuiyu_policy
策略
- 找到索引管理,點選生成的索引
zuiyu-000001
- 彈出的頁面中我們可以清晰的看到當前索引的相關資訊,此時處於
hot
階段
ILM策略重新整理的時間預設是10分鐘(並不是固定10分鐘,哪怕我們設定為10分鐘也可能20分鐘才能執行,甚至可能趕巧的話馬上就執行也說不準),我們可以透過如下API進行修改為10s
測試,也可以等待ILM自動執行
官網的說明如下
https://www.elastic.co/guide/...
PUT _cluster/settings
{
"transient": {
"indices.lifecycle.poll_interval": "10s"
}
}
- 等待10多分鐘之後,索引
zuiyu-000002
生成,此時索引zuiyu-000001
與zuiyu-000002
都在hot
節點
- 繼續等待約
10
分鐘,此時發現zuiyu-000001
節點已經移動到了warm節點上
- 我們呢此時也可以透過Kibana檢視ILM執行情況,也可以看到執行該操作的時間,如下
- 繼續等待約
10
分鐘,索引zuiyu-000001
已經減少分片數量為1
,並且移動到節點cold
上了
按照上面ILM策略執行的話,我們當時定義的是一天之後刪除,也就是24小時之後,移動到cold節點上的索引就會被刪除,這個大家可以自行驗證一下,這邊就不演示了,不過我本地是測試成功過的
我們還可以透過建立索引時直接繫結索引生命週期策略,API如下,測試就不測試了,感興趣的自己下面測試下吧
注意測試時別與上面的索引模版衝突覆蓋了哦
PUT zy-index-000001
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0,
"index.lifecycle.name": "zuiyu_policy",
"index.lifecycle.rollover_alias": "zy-index" ,
"index.routing.allocation.require.node_type":"hot"
},
"aliases": {
"zy-index": {}
}
}
上面我們測試了透過索引模版建立索引,並且應用索引生命週期策略,下面來測試一下資料流索引,與索引模版的類似,首先還是建立一個資料流模版
建立資料流模版
該模版會匹配zyds-
開頭的,匹配為資料流索引,建立的分片數量為3
,應用剛才我們建立的ILM策略,路由分片到hot
節點
PUT _index_template/zyds_template
{
"index_patterns": ["zyds-*"],
"data_stream": {},
"priority": 200,
"template": {
"settings": {
"number_of_shards": 3,
"number_of_replicas":0,
"index.lifecycle.name": "zuiyu_policy",
"index.routing.allocation.require.node_type": "hot"
}
}
}
建立資料流索引
PUT _data_stream/zyds-stream
檢視生成的資料流索引
此時我們在cerebro頁面輸入zyds進行過濾,並且勾選special,可以看到生成的資料流也是在hot
節點上
驗證資料流ILM策略
定義一個pipeline,方便插入資料到資料流使用,作用是生成欄位
@timestamp
PUT _ingest/pipeline/add-timestamp { "processors": [ { "set": { "field": "@timestamp", "value": "{{_ingest.timestamp}}" } } ] }
新增測試資料
點選多次,大於
10
即可,此處我點了19
次,生成了19
個文件,也是可以觸發ILM策略的POST zyds-stream/_doc?pipeline=add-timestamp { "user": { "id": "zuiyu", "name":"魚" }, "message": "zuiyu is successful!" }
等待約10分鐘,文件數量大於10,發生滾動策略,生成新索引
等待約
10
分鐘,第一個索引已經從hot
節點資料移動到warm
節點- 繼續等待約
10
分鐘,分片減少為1
個
後面就不演示了,相信大家也看到了,本篇文章耗時巨長了,感覺寫的還不錯的可以點贊分享哦
總結
透過上面的學習我們學會了ILM期間的各種操作,並且實操了索引模版,資料流模版使用索引生命週期策略的例子,相信大家看完本篇文章也有一定的收穫,畢竟我可以非常自信的說的是,看完本篇文章,你可能不會很精通ILM,但是ILM入門你絕對可以