索引生命週期管理ILM看完不懂你錘我

醉魚發表於2022-11-25

閱讀完本文你可以學到什麼是索引生命週期管理,各個階段可以做的操作以及如何使用索引模版使用索引生命週期策略,下面就跟我一起來吧

基礎理論篇

索引生命週期管理(ILM)是一種可以讓我們隨著時間推移自動化的管理索引的一種方式。我們可以根據效能,索引文件數量、大小等彈性要求,文件的保留需求等方面來自定義索引生命週期管理策略,我們可以使用ILM實現如下需求

  • 當索引達到一定的大小或者一定的文件數量時生成一個新的索引
  • 每天、每週或者每個月建立一個新索引、並把之前的索引歸檔
  • 刪除歷史索引、按照資料保留標準執行是否保留索引

在ILM策略期間可以觸發的操作有:Set Priority,Unfollow,Rollover,Read-only,Shrink,Force merge,Searchable snapshot,Allocate,Migrate,Wait for snapshot,Delete

下面是每個操作具體的含義

  • Set Priority

    可應用階段:HotWarmCold

    設定步驟的優先順序

    必須引數,設定索引優先順序,大於等於0的整數;設定為null刪除優先順序;Hot階段應具有最高值,Cold應具有最低值;例如Hot 100Warm 50Cold 0;未設定此值的索引優先順序預設為1

  • Unfollow

    可應用階段:HotWarmColdFrozen

    跨叢集索引設定為標準索引,可以使shrinkrolloversearchable snapshot 操作安全的在follower索引上執行;

    在整個生命週期中移動follower索引時,也可以直接使用unfollow,對於不是follower索引的沒有影響、階段執行中只是跳轉到下一個操作

    shrinkrolloversearchable 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:從索引建立之日起開始計算時間,滿足之後觸發滾動操作。例如1d7d30d;即使我們透過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

    可應用階段:HotWarmCold

    使索引變為只讀索引,如果要在Hot階段執行Read-only操作,前提是必須執行rollover操作,如果沒有配置rollover操作,ILM將拒絕Read-only策略

  • Shrink

    可應用階段:HotWarm

    前提:將源索引設定為只讀;所有分片必須在同一個節點上;叢集健康狀態為 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

    可應用階段:HotWarm

    合併索引中的segments到指定的最大段數,此操作會將索引設定為Read-only;強制合併會盡最大的努力去合併,如果此時有的分片在重新分配,那麼該分片是無法被合併的

    如果我們要在Hot階段執行Force merge 操作,rollover操作是必須的,如果沒有配置rolloverILM會拒絕該策略

    • max_num_segments:必須的整數型別,表示要合併到的segments數量,如果要完全合併索引,需要設定值為1
    • index_codec:可選字串引數,壓縮文件的編解碼器,只能設定best_compression,它可以獲得更高的壓縮比,但是儲存效能較差。該引數預設值LZ4,如果要使用LZ4,此引數可不用設定
  • Searchable snapshot

    可應用階段:HotColdForzen

    將快照掛載為可搜尋的索引。如果索引是資料流的一部分,則掛載的索引將替換資料流中的原始索引

    Searchable snapshot操作繫結對應的資料層,也就是(Hot-Warm-Cold-Forzen-Delete),恢復資料時直接恢復到對應的資料層,該操作使用index.routing.allocation.include._tier_preference設定,在凍結層(frozen)該操作會將字首為partial-的部分資料恢復到凍結層,在其他層,會將字首為restored-的全部資料恢復到對應層

  • Allocate

    可應用階段:WarmCold

    設定副本數量,修改分片分配規則。將分片移動到不同效能特徵的節點上並減少副本的數量,該操作不可在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

    可應用階段:WarmCold

    透過更新index.routing.allocation.include._tier_preference設定,將索引移動到當前階段對應的資料層

    ILM自動的在WarmCold階段開啟該操作,如果我們不想自動開啟可以透過設定enabledfalse來關閉

    • 如果在Cold階段定義了一個可搜尋的快照(Searchable snapshot)動作,那麼將不會自動注入Migrate操作,因為MigrateSearchable snapshot使用相同的index.routing.allocation.include._tier_preference設定
    • Warm階段,Migrate操作會設定index.routing.allocation.include._tier_preferencedata_warm,data_hot。意思就是這會將索引移動到Warm層的節點上,如果Warm層沒有,那就返回到Hot層節點
    • Cold階段,Migrate操作會設定index.routing.allocation.include._tier_preferencedata_cold,data_warm,data_hot。這會將索引移動到Cold層,如果Cold層沒有返回到Warm層,如果還沒有可用的節點,返回到Hot
    • Frozen階段不允許遷移操作,Migrate操作會設定index.routing.allocation.include._tier_preferencedata_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:索引不在需要,可以安全的刪除

在上面的這幾個階段中,每個階段的執行操作是不同的以及從一個階段轉到另一個階段的時間也是不固定的

操作HotWarmColdFrozenDelete
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_policyrollover操作時別名為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-000001zuiyu-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入門你絕對可以

參考連結

ILM:https://www.elastic.co/guide/...

相關文章