ILM 索引生命周期管理
1. 创建资源
开始实验之前,您需要先创建实验相关资源。
- 在实验室页面,单击创建资源。
- (可选)在实验室页面左侧导航栏中,单击云产品资源列表,可查看本次实验资源相关信息(例如IP地址、子用户信息等)。
说明:资源创建过程需要3~5分钟(视资源不同开通时间有所差异,ACK等资源开通时间较长)。完成实验资源的创建后,您可以在云产品资源列表查看已创建的资源信息,例如:子用户名称、子用户密码、AK ID、AK Secret、资源中的项目名称等。
实验环境一旦开始创建则进入计时阶段,建议学员先基本了解实验具体的步骤、目的,真正开始做实验时再进行创建。
资源创建成功,可在左侧的资源卡片中查看相关资源信息以及RAM子账号信息
2. 部署冷热分层集群
在 Elasticsearch 7.10 中引入了 data tiers(数据层)的概念,对数据节点类型做进一步的细分,分为 data_content, data_host, data_warm, data_cold, data_frozen,同一数据层的节点通常拥有相同硬件配置和性能。不同数据层的定义如下:
- 内容层(content tier): 内容层往往存储常态化的数据,与时间序列数据不同,这类数据的价值随着时间的推移相对保持恒定,例如产品目录或者商品种类。
- 热层(hot tier): 热层存储最新的时间序列数据,这类数据也是被查询最多的数据,因此热层中的节点在写入和读取时都需要快速,因此热层的节点通常拥有更好的 CPU、内存资源和更快的存储(例如 SSD 固态硬盘)。
- 温层(warm tier): 一旦查询查询时间序列数据的频率开始低于热层中最近写入的数据,那么便可以将这些数据转移至温层。温层通常保留最近几周的数据,一般不会再对这些数据进行更新,温层的节点不需要像热层中的节点一样快。
- 冷层(cold tier): 冷层存储访问频率较低的数据,我们通常会将冷层的数据设置为只读的,并且随着数据过渡到冷层,还可以对其进行压缩和去副本以节省存储空间。
- 冻结层(frozon tier): 一旦数据不再被查询,便可以将数据从冷层移动到冻结层。在冻结层中可以选择以挂载索引的方式将数据存储在快照存储库中,可以省去副本的存储空间,当需要搜索时,再去快照存储库中提取数据,因此查询的速度通常较慢。
需要确保集群中至少有一个 data_hot 和 data_content 节点,即使它们是同一个节点,否则新索引将无法被分配。 新创建的索引默认将分配到 data_content 节点上。
在本实验中,我们将部署一个由 4 个节点组成的冷热分离架构的 Elasticsearch 集群,节点的角色分配如下。
节点 |
角色 |
说明 |
es01 |
master, data_content, data_hot |
内容层,热层 |
es02 |
master, data_content, data_hot |
内容层,热层 |
es03 |
master, data_warm |
温层 |
es04 |
master, data_cold |
冷层 |
首先执行以下命令修改系统参数以满足 Elasticsearch 的运行条件。
# 增加进程可使用的最大内存映射区域数 cat >> /etc/sysctl.conf << EOF vm.max_map_count=262144 EOF sysctl -p # 增加进程可使用的最大文件描述符数量 cat >> /etc/security/limits.conf << EOF elastic - nofile 65535 EOF ulimit -n 65535
为了方便实验,本节采用 Docker Compose 的方式快速部署 Elasticsearch 集群。执行如下命令,安装 Docker 和 Docker Compose。
curl -sSL https://get.daocloud.io/docker | sh apt install -y docker-compose
执行如下命令,获取 docker-compose.yml 配置文件,并在后台启动 Elasticsearch 集群。
apt install -y git git clone https://gitee.com/cr7258/elastic-lab.git cd elastic-lab/2_ilm/ docker-compose up -d
执行 docker-compose ps 命令查看容器运行状态,其中 2ilm_setup_1 容器是用于创建证书以及设置 elastic 和 kibana_system 用户密码的,执行完毕后会自动退出,我们需要确保其他容器处于 Up 状态。
3. 设置 ILM 策略
浏览器输入 http://<ESC 公网 IP>:5601 访问 Kibana 界面。输入用户名 elastic,密码 elastic123,点击 Login in。其中密码是在 elastic-lab/2_ilm/.env 文件中设置的。
点击 Management -> Dev Tools -> Console,打开 Kibana Console 界面。ILM 服务会在后台定期轮询执行 Policy,默认的时间间隔为 10 分钟,为了测试更快地看到效果,这里将其修改为 1 秒。
PUT _cluster/settings { "persistent": { "indices.lifecycle.poll_interval":"1s" } }
接下来设置 ILM 策略,包含以下 4 个阶段:
- Hot 阶段:超过 5 个文档以后 rollover 创建新的索引。
- Warm 阶段:60s 后进入 warm 阶段,将副本分片数缩减为 0。
- Cold 阶段:120s 后进入 cold 阶段,将索引设置为只读。
- Delete 阶段:180s 后进入 delete 阶段,删除索引。
PUT _ilm/policy/log-ilm-policy { "policy": { "phases": { "hot": { "min_age": "0s", "actions": { "rollover": { "max_docs": 5 // 超过 5 个文档以后 rollover 创建新的索引 }, "set_priority": { "priority": 100 // 优先级最高,当节点重启后优先恢复 hot 阶段的索引 } } }, "warm": { "min_age": "60s", // 60s 后进入 warn 阶段 "actions": { "allocate": { "number_of_replicas": 0 // 将副本分片数缩减为 0 }, "set_priority": { "priority": 50 } } }, "cold": { "min_age": "120s", // 120s 后进入 cold 阶段 "actions": { "readonly" : {}, // 将索引设置为只读 "set_priority": { "priority": 0 } } }, "delete": { "min_age": "180s", // 180s 后删除索引 "actions": { "delete": {} } } } } }
4. 设置索引模板
创建索引模板,匹配 log-index- 开头的索引,关联 ILM 策略和别名,新索引的主分片数和副本分片数都设置为 1。索引模板是预先定义好的在创建新索引时自动应用的模板,在索引模板中可以定义在创建索引时为索引添加的别名、设置、字段映射以及索引应用的 ILM 策略等内容。
PUT _index_template/log-template { "index_patterns" : [ "log-index-*" // 通配符匹配索引 ], "template": { "settings" : { "index" : { "lifecycle" : { "name" : "log-ilm-policy", // 应用 ILM 策略 "rollover_alias" : "log-index" // 指定 rollover 别名 }, "number_of_shards" : "1", // 主分片数 "number_of_replicas" : "1" // 副本分片数 } } } }
5. 创建符合模板的起始索引
创建第一个索引 log-index-000001,设置索引别名为 log-index,后续在 rollover 滚动更新索引时,索引名会根据最后的序号递增,例如 log-index-000002,log-index-000003,log-index-000004 ...。is_write_index 参数设置为 true 表示往别名发送的写请求将发送到 log-index-000001 索引上。当发生 Rollover 时,Elasticsearch 会自动将新创建的索引的 is_write_index 参数设置为 true,同时将旧索引的 is_write_index 参数设置为 false,以确保往别名写入时只写入同一个索引。
PUT log-index-000001 { "aliases": { "log-index": { "is_write_index": true } } }
查看别名 log-index,可以看到该别名下目前只有 1 个索引 log-index-000001,该索引处于可写的状态,并且应用了我们设置的 ILM 策略。当新建索引时,默认情况下,Elasticsearch 会将 index.routing.allocation.include._tier_preference 参数设置为 data_content,以将索引分片自动分配给内容层。
GET log-index # 返回结果 { "log-index-000001" : { "aliases" : { "log-index" : { "is_write_index" : true // 可写 } }, "mappings" : { }, "settings" : { "index" : { "lifecycle" : { // 应用 ILM 策略 "name" : "log-ilm-policy", "rollover_alias" : "log-index" }, "routing" : { "allocation" : { "include" : { "_tier_preference" : "data_content" // 分片分配到内容层上 } } }, "number_of_shards" : "1", "provided_name" : "log-index-000001", "creation_date" : "1657374734018", "priority" : "100", "number_of_replicas" : "1", "uuid" : "kOXmUzVlRRmTZJfBxolpmg", "version" : { "created" : "8020399" } } } } }
6. 插入数据,观察效果
浏览器输入 http://<ESC 公网 IP>:9000 访问 Cerebro,在 Node address 输入框内填入 https://es01:9200,然后点击 Connect 连接 Elasticsearch 集群。
输入用户名 elastic,密码 elastic123,点击 Authenticate。
往索引中插入 5 条数据,然后观察 ILM 策略的执行效果。
POST log-index/_bulk {"index":{}} {"name":"Erlend","age":16} {"index":{}} {"name":"Brynjar","age":18} {"index":{}} {"name":"Fox","age":18} {"index":{}} {"name":"Frank","age":23} {"index":{}} {"name":"Sam","age":18} // 手动触发段合并,让 Elasticsearch 更快监测到文档数量的变化 POST log-index/_forcemerge
等待一会 Elasticsearch 发现 log-index-000001 索引中的文档数达到 5 个,会触发 Rollover,创建新的索引 log-index-000002。
往别名发起的写入请求将会写入 log-index-000002 索引中。当然此时你仍然可以指定往 log-index-000001 索引中写入数据。
GET log-index # 返回结果 { "log-index-000001" : { "aliases" : { "log-index" : { "is_write_index" : false // 被改为 false 了 } }, "mappings" : { "properties" : { "age" : { "type" : "long" }, "name" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } } } }, "settings" : { "index" : { "lifecycle" : { "name" : "log-ilm-policy", "rollover_alias" : "log-index", "indexing_complete" : "true" }, "routing" : { "allocation" : { "include" : { "_tier_preference" : "data_content" } } }, "number_of_shards" : "1", "provided_name" : "log-index-000001", "creation_date" : "1657374734018", "priority" : "100", "number_of_replicas" : "1", "uuid" : "kOXmUzVlRRmTZJfBxolpmg", "version" : { "created" : "8020399" } } } }, "log-index-000002" : { "aliases" : { "log-index" : { "is_write_index" : true // 往别名发起的写入请求将发给 log-index-000002 索引 } }, "mappings" : { }, "settings" : { "index" : { "lifecycle" : { "name" : "log-ilm-policy", "rollover_alias" : "log-index" }, "routing" : { "allocation" : { "include" : { "_tier_preference" : "data_content" } } }, "number_of_shards" : "1", "provided_name" : "log-index-000002", "creation_date" : "1657374971168", "priority" : "100", "number_of_replicas" : "1", "uuid" : "tT1hbzQxQH2Ms5luQki6gw", "version" : { "created" : "8020399" } } } } }
等待 60s,log-index-000001 索引进入 Warm 阶段,索引分片移动到 es03 节点上,此时只保留了主分片,副本分片缩减为 0。
此时发现 log-index-000001 索引的 index.routing.allocation.include._tier_preference 参数被修改为了 data_warm,data_hot,当存在 data_warm 角色的节点,则将索引分配给温层;如果不存在 data_warm 角色的节点,则将索引分配给热层。
GET log-index # 返回结果 { "log-index-000001" : { "aliases" : { "log-index" : { "is_write_index" : false } }, "mappings" : { "properties" : { "age" : { "type" : "long" }, "name" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } } } }, "settings" : { "index" : { "lifecycle" : { "name" : "log-ilm-policy", "rollover_alias" : "log-index", "indexing_complete" : "true" }, "routing" : { "allocation" : { "include" : { "_tier_preference" : "data_warm,data_hot" // 优先分配到温层 } } }, "number_of_shards" : "1", "provided_name" : "log-index-000001", "creation_date" : "1657374734018", "priority" : "50", "number_of_replicas" : "0", "uuid" : "kOXmUzVlRRmTZJfBxolpmg", "version" : { "created" : "8020399" } } } }, "log-index-000002" : { "aliases" : { "log-index" : { "is_write_index" : true } }, "mappings" : { }, "settings" : { "index" : { "lifecycle" : { "name" : "log-ilm-policy", "rollover_alias" : "log-index" }, "routing" : { "allocation" : { "include" : { "_tier_preference" : "data_content" } } }, "number_of_shards" : "1", "provided_name" : "log-index-000002", "creation_date" : "1657374971168", "priority" : "100", "number_of_replicas" : "1", "uuid" : "tT1hbzQxQH2Ms5luQki6gw", "version" : { "created" : "8020399" } } } } }
等待 120s,log-index-000001 索引进入 Cold 阶段,索引分片移动到 es04 节点上,此时索引被设置为只读状态。
此时发现 log-index-000001 索引的 index.routing.allocation.include._tier_preference 参数被修改为了 data_cold,data_warm,data_hot,索引将会被优先分配到冷层,如果没有 data_cold 角色的节点,再依次考虑分配到温层或者热层。
GET log-index # 返回结果 { "log-index-000001" : { "aliases" : { "log-index" : { "is_write_index" : false } }, "mappings" : { "properties" : { "age" : { "type" : "long" }, "name" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } } } }, "settings" : { "index" : { "lifecycle" : { "name" : "log-ilm-policy", "rollover_alias" : "log-index", "indexing_complete" : "true" }, "routing" : { "allocation" : { "include" : { "_tier_preference" : "data_cold,data_warm,data_hot" // 优先分配到冷层 } } }, "number_of_shards" : "1", "blocks" : { "write" : "true" }, "provided_name" : "log-index-000001", "creation_date" : "1657374734018", "priority" : "0", "number_of_replicas" : "0", "uuid" : "kOXmUzVlRRmTZJfBxolpmg", "version" : { "created" : "8020399" } } } }, "log-index-000002" : { "aliases" : { "log-index" : { "is_write_index" : true } }, "mappings" : { }, "settings" : { "index" : { "lifecycle" : { "name" : "log-ilm-policy", "rollover_alias" : "log-index" }, "routing" : { "allocation" : { "include" : { "_tier_preference" : "data_content" } } }, "number_of_shards" : "1", "provided_name" : "log-index-000002", "creation_date" : "1657374971168", "priority" : "100", "number_of_replicas" : "1", "uuid" : "tT1hbzQxQH2Ms5luQki6gw", "version" : { "created" : "8020399" } } } } }
等待 180s,log-index-000001 索引被删除。至此完成了整个索引生命周期流程。
实验地址:https://developer.aliyun.com/adc/scenario/5d86a903f72b49c88dd9730be7f45093