本文介紹在阿里云Elasticsearch集群上,通過生命周期管理ILM(Index Lifecycle Management)功能,實現冷熱數據分離的實踐流程。通過本實踐,您既可以實現在保證集群讀寫性能的基礎上,自動維護集群上的冷熱數據,又能通過優化集群架構,降低企業生產成本。

背景信息

當今大數據時代,數據時刻在更新變化。尤其是隨著時間的積累,存儲在阿里云Elasticsearch中的數據會越來越多,當數據達到一定量時,必然會造成服務的內存、CPU、IO等指標上漲,影響Elasticsearch的全文檢索能力。為此Elasticsearch 6.6.0及以上版本提供了索引生命周期管理ILM功能,將索引生命周期分為4個階段:hot、warm、cold、delete。其中hot階段主要負責對索引進行滾動更新操作,warm、cold、delete階段主要負責進一步處理索引數據,詳細說明如下。
階段 描述
hot 熱數據階段。主要處理時序數據的實時寫入,可根據索引的文檔數、大小、時長決定是否調用rollover API來滾動更新索引。
warm warm階段。索引不再寫入,主要用來提供查詢。
cold 冷數據階段。索引不再更新,查詢很少,查詢速度會變慢。
delete 刪除數據階段。索引將被刪除。
您可以通過兩種方式為索引添加生命周期管理策略:
  • 為索引模板添加生命周期管理策略:將策略應用到整個別名覆蓋的索引下,本文以此為例。
  • 為單個索引添加生命周期管理策略:只能覆蓋當前索引,新滾動的索引不再受策略影響。
在時序和冷熱數據場景上應用ILM,可以大幅度節約存儲成本。本文以冷熱數據場景為例,介紹如何使用ILM功能。配置場景如下:
  1. 將索引數據實時寫入Elasticsearch。當索引數據增加到一定量時,數據自動寫入新索引。
  2. 舊索引在hot階段停留30分鐘,進入warm階段。
  3. warm階段完成Merge及Shrink操作后,索引等待1小時(從滾動更新時算起),進入cold階段。
  4. cold階段將熱節點數據遷移到冷節點,實現冷熱數據分離后,索引會在2個小時(從滾動更新時算起)后被刪除。

注意事項

  • Elasticsearch索引生命周期策略需密切貼近業務模型。例如,對多個不同結構的索引進行生命周期管理,建議各個索引配置獨立的別名和生命周期策略,以便于管理。
  • 使用rollover滾動索引,初始索引應以自增數字結尾(-000001),否則策略不生效,長度要求為6。例如,定義初始索引為myindex-000001,則rollover后的索引是myindex-000002,以此類推進行遞增。如果集群中索引名不符合規范,建議進行索引重建。
  • hot階段主要處理數據寫入。業務中需保證數據是按照時間順序寫入的,處于warm和cold階段的索引不建議進行數據寫入。例如,在warm階段配置actionsshrinkread only,那么索引進入warm階段后將處于只讀狀態,數據無法寫入。

操作流程

  1. 步驟一:創建冷熱集群并查看節點的冷熱屬性
    在創建集群時設置節點的冷熱屬性。
  2. 步驟二:為索引配置生命周期管理策略
    定義ILM策略,并將該策略應用到別名覆蓋的所有索引下。
  3. 步驟三:驗證數據分布
    驗證cold階段索引的shard是否分布在冷數據節點上。
  4. 步驟四:更新ILM策略
    更新已有策略。
  5. 步驟五:切換ILM策略
    在不同策略間實現滾動切換。

步驟一:創建冷熱集群并查看節點的冷熱屬性

冷熱集群是指在集群中包含冷、熱兩種屬性的節點,可以提高Elasticsearch的處理性能和服務穩定性。兩者區別如下。
節點類型 存儲數據要求 讀寫性能要求 規格要求 存儲要求
熱節點(hot) 近期數據,例如最近2天的日志數據。 高,例如32核64 GB 建議使用SSD云盤存儲數據,存儲空間大小需根據數據大小進行設置。
冷節點(warm) 歷史數據,例如2天之前的日志數據。 低,例如8核32 GB
  • 建議使用高效云盤存儲數據,存儲空間大小需根據數據大小進行設置。
  • 建議使用阿里云自研OpenStore存儲功能,實現海量冷數據Serverless存儲,詳細信息請參見通過OpenStore實現海量數據存儲
  1. 購買阿里云Elasticsearch實例時,啟用冷數據節點,即可創建冷熱集群。
    當您啟用了冷數據節點并購買后,系統會在節點啟動參數中加入-Enode.attr.box_type參數。
    • 熱數據節點:-Enode.attr.box_type=hot
    • 冷數據節點:-Enode.attr.box_type=warm
    說明
    • 購買實例時,只有當啟用了冷數據節點后,數據節點才會變成熱節點。
    • 本文以阿里云Elasticsearch 6.7.0版本為例,所涉及的操作及圖片僅適用于該版本,其他版本以實際界面為準。
  2. 登錄該集群的Kibana控制臺,在左側導航欄,單擊Dev Tools
    登錄Kibana控制臺的具體操作請參見登錄Kibana控制臺
  3. Console中,執行如下命令,查看集群冷熱節點屬性。
    GET _cat/nodeattrs?v&h=host,attr,value
    結果顯示集群中包含3個hot節點,2個warm節點,支持冷熱架構。冷熱架構集群

步驟二:為索引配置生命周期管理策略

  1. 在Kibana控制臺中,執行如下命令,通過API方式定義ILM策略。
    PUT /_ilm/policy/game-policy
    {
      "policy": {
        "phases": {
          "hot": {
            "actions": {
              "rollover": {
                "max_size": "1GB",
                "max_age": "1d",
                "max_docs": 1000
              }
            }
          },
          "warm": {
            "min_age": "30m",
            "actions": {
              "forcemerge": {
                    "max_num_segments":1
                  },
              "shrink": {
                    "number_of_shards":1
                  }
            }
          },
          "cold": {
            "min_age": "1h",
            "actions": {
              "allocate": {
                "require": {
                  "box_type": "warm"
                }
              }
            }
          },
          "delete": {
            "min_age": "2h",
            "actions": {
              "delete": {}
            }
          }
        }
      }
    }
    參數 說明
    hot 該策略設置索引只要滿足其中任一條件:數據寫入達到1 GB、使用超過1天、doc數超過1000,就會觸發索引滾動更新。此時系統將創建一個新索引,該索引將重新啟動策略,而舊索引將在滾動更新后等待30分鐘進入warm階段。
    注意 目前Elasticsearch支持在rollover中配置三種歸檔策略:max_docs、max_size、max_age,滿足其中任何一個條件都會觸發索引歸檔操作。
    warm 索引進入warm階段后,ILM會將索引收縮到1個分片,強制合并為1個段。完成該操作后,索引將在1小時(從滾動更新時算起)后進入cold階段。
    cold 索引進入cold階段后,ILM將索引從hot節點移動到warm(冷數據)節點。完成操作后,索引將在2小時后進入delete階段。
    delete 索引進入delete階段后被刪除。
    說明
    • 策略名創建后將無法更改。
    • 您也可以在Kibana控制臺上創建策略,但是Kibana上指定的max_age最小單位為小時,而通過API方式,可指定最小單位為秒。
  2. 創建索引模板。
    settings中指定冷熱屬性,數據寫入后存儲在hot節點上。
    PUT _template/gamestabes_template
    {
      "index_patterns" : ["gamestabes-*"],
      "settings": {
        "index.number_of_shards": 5,
        "index.number_of_replicas": 1,
        "index.routing.allocation.require.box_type":"hot",
        "index.lifecycle.name": "game-policy", 
        "index.lifecycle.rollover_alias": "gamestabes"
      }
    }
    參數 說明
    index.routing.allocation.require.box_type 指定索引新建時所分配的節點。
    index.lifecycle.name 指定生命周期策略名稱。
    index.lifecycle.rollover_alias 指定rollover別名。
  3. 基于序號創建初始索引。
    PUT gamestabes-000001
    {
    "aliases": {
        "gamestabes":{
           "is_write_index": true
            }
          }
    }

    您也可以基于時間創建索引,詳情請參見using date math

  4. 通過別名寫入數據。
    當數據達到rollover條件,并觸發ILM檢測周期后,索引將進行滾動更新。
    PUT gamestabes/_doc/1
    {
        "EU_Sales" : 3.58,
        "Genre" : "Platform",
        "Global_Sales" : 40.24,
        "JP_Sales" : 6.81,
        "Name" : "Super Mario Bros.",
        "Other_Sales" : 0.77,
        "Platform" : "NES",
        "Publisher" : "Nintendo",
        "Year_of_Release" : "1985",
        "na_Sales" : 29.08
    }
    說明 ILM默認10分鐘檢測一次符合策略標準的索引,當達到rollover條件后,索引將滾動到下一階段,同時配置indices.lifecycle.poll_interval參數,修改檢測周期
  5. 根據生命周期階段過濾索引,并查看索引詳細配置。
    1. 在左側導航欄,單擊Management
    2. Elasticsearch區域中,單擊Index Management
    3. Index management中,單擊Lifecycle status右側的Lifecycle phase,從下拉列表中選擇生命周期階段進行過濾。
      根據生命周期過濾索引
    4. 單擊過濾后的索引,查看索引詳細信息。
      查看索引詳細信息

步驟三:驗證數據分布

  1. 查詢進入cold階段的索引,并查看其配置信息。
    查詢進入cold階段的索引
  2. 查詢處于cold階段索引的shard分布。
    GET _cat/shards?shrink-gamestables-000012
    返回結果如下。根據返回結果可知,cold階段的索引數據主要分布在冷數據節點上。返回結果

步驟四:更新ILM策略

  1. 更新正在運行的ILM策略。
    更新ILM策略
  2. 查看更新后的策略版本。
    1. 在左側導航欄,單擊Management
    2. Elasticsearch區域中,單擊Index Lifecycle Policies
    3. Index lifecycle policies中,查看更新后的策略版本。
      更新后策略的版本號增加1,此時正在滾動寫入的索引依舊使用舊策略,新策略將在下次滾動更新時生效。查看更新后的ILM策略版本

步驟五:切換ILM策略

  1. 創建新策略。
    PUT /_ilm/policy/game-new
    {
      "policy": {
        "phases": {
          "hot": {
            "actions": {
              "rollover": {
                "max_size": "3GB",
                "max_age": "1d",
                "max_docs": 1000
              }
            }
          },
          "warm": {
            "min_age": "30m",
            "actions": {
              "forcemerge": {
                    "max_num_segments":1
                  },
              "shrink": {
                    "number_of_shards":1
                  }
            }
          },
          "cold": {
            "min_age": "1h",
            "actions": {
              "allocate": {
                "require": {
                  "box_type": "warm"
                }
              }
            }
          },
          "delete": {
            "min_age": "2h",
            "actions": {
              "delete": {}
            }
          }
        }
      }
    }
  2. 為模板綁定新策略。
    PUT _template/gamestabes_template
    {
      "index_patterns" : ["gamestabes-*"],
      "settings": {
        "index.number_of_shards": 5,
        "index.number_of_replicas": 1,
        "index.routing.allocation.require.box_type":"hot",
        "index.lifecycle.name": "game-new", 
        "index.lifecycle.rollover_alias": "gamestabes"
      }
    }
    注意
    • 切換策略后,新策略不會立即生效。當前正在滾動寫入的索引依舊使用舊策略,直到當前索引rollover生成新索引,新策略才會生效。
    • 應用舊策略創建的索引,依舊綁定舊策略。如果您需要為這些索引綁定新策略,可執行PUT gamestabes-*/_settings命令,詳情請參見switching policies for an index

常見問題

Q:如何設置ILM策略周期?

A:由于索引生命周期策略默認是10分鐘檢查一次符合策略的索引,因此在這10分鐘內索引中的數據可能會超出指定的閾值。例如在步驟二:為索引配置生命周期管理策略時,設置max_docs為1000,但doc數量在超過1000后才觸發索引滾動更新,此時可通過修改indices.lifecycle.poll_interval參數來控制檢查頻率,使索引在閾值范圍內滾動更新。
注意 請慎重修改該參數值,避免時間間隔太短給節點增加不必要的負載,本測試中將其改成了1m
PUT _cluster/settings
{
  "transient": {
    "indices.lifecycle.poll_interval":"1m"
  }
}