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策略配置:
{
"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,但效果不佳,可能是因为这个值并不适合你的具体环境。你可以尝试不同的值,逐步调低,找到一个平衡点。
{
"settings": {
"index.routing.allocation.max_bytes_per_sec": "30mb"
}
}
结合冷/热迁移策略:可以尝试在迁移的同时,监控系统的IO 利用率,动态调整 max_bytes_per_sec 的值,确保不会导致IO打满。
3.3 方案三:硬件配置与资源分配优化
考虑升级冷节点的硬盘,从SATA 更换为性能更好的SSD,这将显著提高IO性能。
如果可能,增加热节点的数量,这样可以分摊更多的写入压力。
确保在进行迁移操作时,不影响到业务的正常读写,可以考虑使用 Elasticsearch 的 Shard Allocation Awareness,确保数据节点的合理分布和资源隔离。
参考:
3.4 方案四:提前获取消息!——监控与自动化管理
使用自动化工具来根据实时监控数据动态调整 ILM 策略。可以设置一些规则,比如在检测到IO利用率高于某个阈值时,自动暂停迁移操作,低于阈值时恢复迁移。
参考 python 脚本如下:
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 监控工具实现。
举例脚本预警脚本如下:
#!/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
小结
通过以上措施,你应该能够更好地管理热数据到冷节点的迁移过程,减少对读写操作的影响。
和27000+人一起进阶 Elastic Stack及人工智能技术!