本文介紹在阿里云Elasticsearch集群上,通過生命周期管理ILM(Index Lifecycle Management)功能,實(shí)現(xiàn)冷熱數(shù)據(jù)分離的實(shí)踐流程。通過本實(shí)踐,您既可以實(shí)現(xiàn)在保證集群讀寫性能的基礎(chǔ)上,自動(dòng)維護(hù)集群上的冷熱數(shù)據(jù),又能通過優(yōu)化集群架構(gòu),降低企業(yè)生產(chǎn)成本。

背景信息

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

注意事項(xiàng)

  • Elasticsearch索引生命周期策略需密切貼近業(yè)務(wù)模型。例如,對(duì)多個(gè)不同結(jié)構(gòu)的索引進(jìn)行生命周期管理,建議各個(gè)索引配置獨(dú)立的別名和生命周期策略,以便于管理。
  • 使用rollover滾動(dòng)索引,初始索引應(yīng)以自增數(shù)字結(jié)尾(-000001),否則策略不生效,長(zhǎng)度要求為6。例如,定義初始索引為myindex-000001,則rollover后的索引是myindex-000002,以此類推進(jìn)行遞增。如果集群中索引名不符合規(guī)范,建議進(jìn)行索引重建。
  • hot階段主要處理數(shù)據(jù)寫入。業(yè)務(wù)中需保證數(shù)據(jù)是按照時(shí)間順序?qū)懭氲模幱趙arm和cold階段的索引不建議進(jìn)行數(shù)據(jù)寫入。例如,在warm階段配置actionsshrinkread only,那么索引進(jìn)入warm階段后將處于只讀狀態(tài),數(shù)據(jù)無法寫入。

操作流程

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

步驟一:創(chuàng)建冷熱集群并查看節(jié)點(diǎn)的冷熱屬性

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

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

  1. 在Kibana控制臺(tái)中,執(zhí)行如下命令,通過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": {}
            }
          }
        }
      }
    }
    參數(shù) 說明
    hot 該策略設(shè)置索引只要滿足其中任一條件:數(shù)據(jù)寫入達(dá)到1 GB、使用超過1天、doc數(shù)超過1000,就會(huì)觸發(fā)索引滾動(dòng)更新。此時(shí)系統(tǒng)將創(chuàng)建一個(gè)新索引,該索引將重新啟動(dòng)策略,而舊索引將在滾動(dòng)更新后等待30分鐘進(jìn)入warm階段。
    注意 目前Elasticsearch支持在rollover中配置三種歸檔策略:max_docs、max_size、max_age,滿足其中任何一個(gè)條件都會(huì)觸發(fā)索引歸檔操作。
    warm 索引進(jìn)入warm階段后,ILM會(huì)將索引收縮到1個(gè)分片,強(qiáng)制合并為1個(gè)段。完成該操作后,索引將在1小時(shí)(從滾動(dòng)更新時(shí)算起)后進(jìn)入cold階段。
    cold 索引進(jìn)入cold階段后,ILM將索引從hot節(jié)點(diǎn)移動(dòng)到warm(冷數(shù)據(jù))節(jié)點(diǎn)。完成操作后,索引將在2小時(shí)后進(jìn)入delete階段。
    delete 索引進(jìn)入delete階段后被刪除。
    說明
    • 策略名創(chuàng)建后將無法更改。
    • 您也可以在Kibana控制臺(tái)上創(chuàng)建策略,但是Kibana上指定的max_age最小單位為小時(shí),而通過API方式,可指定最小單位為秒。
  2. 創(chuàng)建索引模板。
    settings中指定冷熱屬性,數(shù)據(jù)寫入后存儲(chǔ)在hot節(jié)點(diǎn)上。
    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"
      }
    }
    參數(shù) 說明
    index.routing.allocation.require.box_type 指定索引新建時(shí)所分配的節(jié)點(diǎn)。
    index.lifecycle.name 指定生命周期策略名稱。
    index.lifecycle.rollover_alias 指定rollover別名。
  3. 基于序號(hào)創(chuàng)建初始索引。
    PUT gamestabes-000001
    {
    "aliases": {
        "gamestabes":{
           "is_write_index": true
            }
          }
    }

    您也可以基于時(shí)間創(chuàng)建索引,詳情請(qǐng)參見using date math

  4. 通過別名寫入數(shù)據(jù)。
    當(dāng)數(shù)據(jù)達(dá)到rollover條件,并觸發(fā)ILM檢測(cè)周期后,索引將進(jìn)行滾動(dòng)更新。
    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默認(rèn)10分鐘檢測(cè)一次符合策略標(biāo)準(zhǔn)的索引,當(dāng)達(dá)到rollover條件后,索引將滾動(dòng)到下一階段,同時(shí)配置indices.lifecycle.poll_interval參數(shù),修改檢測(cè)周期
  5. 根據(jù)生命周期階段過濾索引,并查看索引詳細(xì)配置。
    1. 在左側(cè)導(dǎo)航欄,單擊Management
    2. Elasticsearch區(qū)域中,單擊Index Management
    3. Index management中,單擊Lifecycle status右側(cè)的Lifecycle phase,從下拉列表中選擇生命周期階段進(jìn)行過濾。
      根據(jù)生命周期過濾索引
    4. 單擊過濾后的索引,查看索引詳細(xì)信息。
      查看索引詳細(xì)信息

步驟三:驗(yàn)證數(shù)據(jù)分布

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

步驟四:更新ILM策略

  1. 更新正在運(yùn)行的ILM策略。
    更新ILM策略
  2. 查看更新后的策略版本。
    1. 在左側(cè)導(dǎo)航欄,單擊Management
    2. Elasticsearch區(qū)域中,單擊Index Lifecycle Policies
    3. Index lifecycle policies中,查看更新后的策略版本。
      更新后策略的版本號(hào)增加1,此時(shí)正在滾動(dòng)寫入的索引依舊使用舊策略,新策略將在下次滾動(dòng)更新時(shí)生效。查看更新后的ILM策略版本

步驟五:切換ILM策略

  1. 創(chuàng)建新策略。
    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"
      }
    }
    注意
    • 切換策略后,新策略不會(huì)立即生效。當(dāng)前正在滾動(dòng)寫入的索引依舊使用舊策略,直到當(dāng)前索引rollover生成新索引,新策略才會(huì)生效。
    • 應(yīng)用舊策略創(chuàng)建的索引,依舊綁定舊策略。如果您需要為這些索引綁定新策略,可執(zhí)行PUT gamestabes-*/_settings命令,詳情請(qǐng)參見switching policies for an index

常見問題

Q:如何設(shè)置ILM策略周期?

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