磁盘io隔离&监控

需求背景

目前我们hadoop集群是混部署方式,一台服务器上有dn,nm,shuffle服务,经常在作业高峰期的时候,出现集群服务器磁盘io使用100%的情况,
但又没有日志可以追踪到是那个服务引起的,或那个作业引起的。这样就会导致这台物理机上的所有服务有读写100% io磁盘的数据时,都会卡顿,互相影响。
所以我们需要启用cgroup来隔离使用磁盘io的限制,并采集到磁盘使用数据,来对服务进行优化。

cgroup blkio 文档参考

kernel内核文档

https://docs.kernel.org/admin-guide/cgroup-v1/index.html

alibaba cgroup参数参考

https://www.alibabacloud.com/help/zh/alinux/support/differences-between-cgroup-v1-and-cgroup-v2

NM中启用cgroups

https://github.com/apache/hadoop/blob/trunk/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java#L1798

实现方案

确定服务器磁盘信息

lsblk -o NAME,MAJ:MIN,SIZE,TYPE,MOUNTPOINT  | grep disk | grep -v 8:0
sdf      8:80    3.7T disk 
sdd      8:48    3.7T disk 
sdm      8:192   3.7T disk 
sdb      8:16    3.7T disk 
sdk      8:160   3.7T disk 
sdi      8:128   3.7T disk 
sdg      8:96    3.7T disk 
sde      8:64    3.7T disk 
sdc      8:32    3.7T disk 
sdl      8:176   3.7T disk 
sdj      8:144   3.7T disk 
sdh      8:112   3.7T disk

配置cgroup blkio

权重

cgroup基于bw值的限制 : – bw (Bandwidth) - 带宽
– io (I/O) - 输入/输出总量
– 计算公式
bw = io / run_time
67.2 MiB/s = 4065 MiB / 60.529 s
4065 ÷ 60.529 ≈ 67.2 ✓

配置

有了上面的介绍和相关数据,就可以根据情况进行配置

echo "8:0 10485760" > /cgroup/blkio/test/blkio.throttle.write_bps_device

配置效果
alt text

完整的自动配置脚本参考:
安装配置:https://github.com/liangrui198/groups-blkio/blob/main/cgroupv1/hadoop_cg_blkio_init.sh
移除:https://github.com/liangrui198/groups-blkio/blob/main/cgroupv1/remove_cg.sh
自动识别服务&加入cgroup: https://github.com/liangrui198/groups-blkio/blob/main/cgroupv1/set_pid_blkio_cg.sh
部署&监控指标采集: https://github.com/liangrui198/groups-blkio/blob/main/cgroupv1/deploy.sh

效果展示

主要采集到的blkio监控指标信息

https://yunlzheng.gitbook.io/prometheus-book/part-ii-prometheus-jin-jie/exporter/commonly-eporter-usage/use-prometheus-monitor-container

# IO服务字节数(读写量)
container_blkio_device_usage_total{operation="Read"}   # 读取字节数
container_blkio_device_usage_total{operation="Write"}  # 写入字节数
container_blkio_device_usage_total{operation="Async"}  # 异步IO
container_blkio_device_usage_total{operation="Sync"}   # 同步IO

# IO操作次数
container_blkio_io_serviced_total{operation="Read"}    # 读操作次数
container_blkio_io_serviced_total{operation="Write"}   # 写操作次数

# IO队列和时间
container_blkio_io_queue_total     # IO队列大小
container_blkio_io_service_time_total # IO服务时间
container_blkio_io_wait_time_total    # IO等待时间

配置到grafana

测试

缺点

总结与 Cgroup v2 的改进
以上限制不严格的缺点在cgroup v2中有改进,但升级系统内核服务需要运维支持,这个先不考虑,我们主要是能够获取服务读写磁盘的监控数据来优化服务为目的。
alt text

Cgroup v1 的blkio子系统是一个在其历史背景下产生的、带有明显设计妥协的方案。它的主要缺点源于其控制策略的分离性以及对缓存写入限制的失效性。这些问题在高性能、高隔离需求的容器化环境中变得尤为突出。

ubuntu22.04 启用 cgroup v2

系统查看和启用

注意事项

需要考虑当前服务器其它服务是否有用cgroup v1,两都版本差别很大,需要做兼容处理。
我们当前环境中是yarn启用了cgroup v1,改了代码支持超配内存,所以不能大量用cgroup v2做监控磁盘写数据。
yarn的cgroup v2当前时间还是补丁中,hadoop3.5.0才会上全。
详见:https://issues.apache.org/jira/browse/YARN-11669

线上监控发现问题并修复案例

问题发现(HDFS)

从监控上看,发现这台服务器的/data9磁盘 02:00-02:05之间卡顿了5分钟的ioutil 100%,服务的读写磁盘都很小,但iops偏高。
alt text 发生了什么呢?从运维系统上的监控啥都不知道,打开我们内部的监控,可以精确到服务的读写磁盘数据。发现磁盘的数据很低的,10M/s以下。 但是iops的指标较高,对应的服务是datanode服务。
alt text
各种调试,各种调试…..略过过程

问题定位

突然发现iotop中的时而出现一个root用户 du -sk /data*/xx datanode数据磁盘目录的统计。

# 以千字节为单位,汇总显示指定目录(及其包含的所有内容)所占用的总磁盘空间。
du -sk  /data3/hadoop/dfs/data/current/BP-1056920250-10.21.118.31-1568114378684  

这是个啥玩意?各种猜测,各种调试………………… alt text
手动写了一个监控脚本,出现后找到对应的父进程。发现是指向datanode服务?
alt text
在hadoop源码里发现这个诡异的操作,在社区补丁里也找到了对应的修复bug
alt text

问题修复

对应的补丁修复:(我们的hdfs当前版本3.1.1) alt text
https://issues.apache.org/jira/browse/HDFS-14313
causes to 14313
https://issues.apache.org/jira/browse/HDFS-14986

合并后单元测试成功 alt text
测试环境已验证,服务没有问题
配置项:

# fs.du.interval =600000  #默认10分钟   当前线上3600000 1小时。
# fs.getspaceused.classname=org.apache.hadoop.fs.DU(default),
# fs.getspaceused.jitterMillis=60000  #1分钟

# update 减少统计频率到10分钟统计一次,并使用hdfs内部副本内存中统计已用空间
fs.getspaceused.jitterMillis=600000    
fs.getspaceused.classname=org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.ReplicaCachingGetSpaceUsed   

最终修复后上线成功

hdfs补丁优化效果

hdfs统计存储量磁盘卡顿问题,已全量灰度完成,目前服务正常。task长尾和推测过多天异常量从最高2万+个降低到1.3万+个,集群高峰时段的pedding数也有相应的降低,作业平均时长也相应的降低了。
alt text
alt text

大纲: