Elasticsearch ILM 热节点迁移至冷节点 IO 打满、影响读写解决方案探讨

2024-07-29 10:59:10 浏览数 (3)

1、实战问题

ILM(索引生命周期管理) 遇到热数据迁移至冷节点时造成 IO 打满影响读写的情况。

现在采取的方案是调整索引生命周期策略,定时的将Cold phase 开启/关闭。低峰开启,高峰关闭。

就是不知道这里面会有啥坑。

热节点:15个16C64G 1.5T SSD ,冷接点:18个 8C32G 3T SATA ,每天数据量9T左右。数据保留期5天。

不确定相比较于采用 max_bytes_per_sec 方案进行限制速度哪个会更好。(设置了50M,但是效果不佳。所以才临时采用关闭迁移的方案)有没有哪位大佬有这方面的经验的可以帮忙提提意见。感谢感谢.

——来自死磕 Elasticsearch 知识星球

https://t.zsxq.com/pYuo6

2、问题与已执行的方案梳理

从上面问题的描述,拆解问题和已做的尝试,梳理如下:

2.1 IO 打满影响读写

热数据迁移至冷节点时,IO负载过高,导致读写性能下降。

2.2 索引生命周期策略人为干预调整

通过调整索引生命周期策略(ILM),在低峰期开启 Cold phase,在高峰期关闭 Cold phase,以避免迁移过程对读写性能的影响。

2.3 更改配置看效果

当前设置 max_bytes_per_sec 为 50M,但效果不佳,导致采用关闭迁移的临时方案。

3、方案探讨

上述描述和方案验证中潜在问题与风险,梳理如下:

  • 第一:频繁手动开启/关闭 Cold phase 可能导致管理复杂度增加。
  • 第二,迁移过程中的暂停与恢复可能引起数据不一致或性能波动。
  • 第三,冷节点的IO性能瓶颈可能无法通过简单的策略调整解决,需要进一步优化硬件配置或进行集群扩展。

进一步,我们继续进行解决方案的探讨。

3.1 解决方案1——实施分批迁移数据

实施分批迁移数据的方法,可以通过调整 Elasticsearch的索引生命周期管理(ILM)策略和使用一些自动化脚本来实现。

这个方案类似写入优化中的不要一下子把 bulk 调整过大导致写入打满类似。

下面是一个详细的步骤指南:

  • 步骤1. 定义分批迁移策略

在 Elasticsearch 的ILM策略中,设置多个阶段,每个阶段处理一部分数据的迁移。可以将迁移策略按天、小时或更细的粒度分批进行。

  • 步骤2. 配置ILM策略

创建或修改ILM策略,使其支持分批迁移。

假设你的数据每天有9T,并且你希望分3次迁移,那么你可以每次迁移3T数据。

以下是一个示例ILM策略配置:

代码语言:javascript复制
{
  "policy": "my_ilm_policy",
  "phases": {
    "hot": {
      "actions": {
        "rollover": {
          "max_size": "3TB",
          "max_age": "1d"
        }
      }
    },
    "warm": {
      "min_age": "1d",
      "actions": {
        "allocate": {
          "number_of_replicas": 1
        }
      }
    },
    "cold": {
      "min_age": "2d",
      "actions": {
        "allocate": {
          "include": {
            "box_type": "cold"
          }
        }
      }
    }
  }
}

这个策略会在数据索引达到 3TB 或 1 天后进行滚动,然后在1天后进入 warm 阶段,2天后进入 cold 阶段。

这个数据迁移方案就像是一个精心设计的流水系统。想象一下,数据就像是河流中的水,它首先在“热”阶段自由流动,这是数据被频繁访问的时期。

然后,水流到达第一个水坝,这里代表“温”阶段,数据不再需要那么频繁的访问,但仍需快速可达。

最后,水流进入一个宁静的湖泊,象征着“冷”阶段,数据在这里被长期存储,不再活跃使用。

整个过程就像调节河流流量一样,通过控制和分批转移,确保数据流动既顺畅又高效。

  • 步骤3. 监控和调整

持续监控Elasticsearch集群的性能,特别是IO使用情况、CPU和内存利用率。

根据监控结果,适时调整迁移策略和时间间隔。

  • 步骤4. 优化 max_bytes_per_sec

通过以上方法,可以有效地实现分批迁移数据,平滑分摊 IO 压力,提高集群的整体性能和稳定性。

3.2 方案二:优化 max_bytes_per_sec 设置

更精细的限制:虽然你已经设置了50M,但效果不佳,可能是因为这个值并不适合你的具体环境。你可以尝试不同的值,逐步调低,找到一个平衡点

代码语言:javascript复制
{
  "settings": {
    "index.routing.allocation.max_bytes_per_sec": "30mb"
  }
}

结合冷/热迁移策略:可以尝试在迁移的同时,监控系统的IO 利用率,动态调整 max_bytes_per_sec 的值,确保不会导致IO打满。

3.3 方案三:硬件配置与资源分配优化

考虑升级冷节点的硬盘,从SATA 更换为性能更好的SSD,这将显著提高IO性能。

如果可能,增加热节点的数量,这样可以分摊更多的写入压力。

确保在进行迁移操作时,不影响到业务的正常读写,可以考虑使用 Elasticsearch 的 Shard Allocation Awareness,确保数据节点的合理分布和资源隔离。

参考:Elasticsearch:从写入原理谈写入优化

3.4 方案四:提前获取消息!——监控与自动化管理

使用自动化工具来根据实时监控数据动态调整 ILM 策略。可以设置一些规则,比如在检测到IO利用率高于某个阈值时,自动暂停迁移操作,低于阈值时恢复迁移。

参考 python 脚本如下:

代码语言:javascript复制
import subprocess
import time
import requests

# Elasticsearch 相关配置
ES_HOST = "http://localhost:9200"
ILM_POLICY_NAME = "my_ilm_policy"
ILM_PAUSE_ENDPOINT = f"{ES_HOST}/_ilm/stop"
ILM_RESUME_ENDPOINT = f"{ES_HOST}/_ilm/start"

# 监控相关配置
IO_THRESHOLD = 80  # IO 利用率阈值,百分比
CHECK_INTERVAL = 60  # 检查间隔,秒

def get_io_utilization():
    # 使用 iostat 获取 IO 利用率
    result = subprocess.run(['iostat', '-dx', '1', '1'], stdout=subprocess.PIPE)
    output = result.stdout.decode()
    
    # 提取 IO 利用率(示例仅处理一个设备)
    for line in output.split('n'):
        if 'sda' in line:  # 替换为实际的设备名称
            fields = line.split()
            utilization = float(fields[-1])
            return utilization
    return 0.0

def pause_ilm():
    response = requests.post(ILM_PAUSE_ENDPOINT)
    if response.status_code == 200:
        print("ILM 迁移操作已暂停")
    else:
        print("暂停 ILM 迁移操作失败:", response.text)

def resume_ilm():
    response = requests.post(ILM_RESUME_ENDPOINT)
    if response.status_code == 200:
        print("ILM 迁移操作已恢复")
    else:
        print("恢复 ILM 迁移操作失败:", response.text)

while True:
    io_utilization = get_io_utilization()
    print(f"当前 IO 利用率: {io_utilization}%")

    if io_utilization > IO_THRESHOLD:
        pause_ilm()
    else:
        resume_ilm()
    
    time.sleep(CHECK_INTERVAL)

https://www.elastic.co/guide/en/elasticsearch/reference/current/ilm-stop.html

设置监控报警,当IO利用率接近打满时,及时通知运维人员采取措施。可以借助 shell 脚本或者 zabbix 监控工具实现。

举例脚本预警脚本如下:

代码语言:javascript复制
#!/bin/bash

# 监控相关配置
IO_THRESHOLD=90  # IO 利用率阈值,百分比
CHECK_INTERVAL=60  # 检查间隔,秒
EMAIL="your_email@example.com"

while true; do
    # 使用 iostat 获取 IO 利用率
    IO_UTIL=$(iostat -dx 1 1 | grep 'sda' | awk '{print $NF}')  # 替换为实际的设备名称

    if (( $(echo "$IO_UTIL > $IO_THRESHOLD" | bc -l) )); then
        echo "IO utilization is high: $IO_UTIL%" | mail -s "High IO Alert" $EMAIL
    fi

    sleep $CHECK_INTERVAL
done

小结

通过以上措施,你应该能够更好地管理热数据到冷节点的迁移过程,减少对读写操作的影响。

0 人点赞