raid-check¶
在完成 mdadm构建RAID10 之后,运维过程中发现默认系统配置了每周一次 raid-check
,也就是在 Cron定时运行 配置了一个 /etc/cron.d/raid-check
:
# Run system wide raid-check once a week on Sunday at 1am by default
0 1 * * Sun root /usr/sbin/raid-check
在实际生产环境中,由于现代存储容量非常巨大(单块 NVMe存储 容量达到4T,组合 mdadm构建RAID10 达到数十T),这个 mdadm
的检查耗时会非常长:
默认同步速度限制为
200MB/sec
(可修改,但是我踩了一个 mdadm 同步速度 调整的坑 ),此时观察top
输出:
%Cpu(s): 0.0 us, 0.9 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 13137145+total, 11335824+free, 4092892 used, 13920332 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 11808108+avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
7608 root 20 0 0 0 0 R 42.7 0.0 5230:41 md10_raid10
112353 root 25 5 0 0 0 D 14.9 0.0 30:11.22 md10_resync
38355 root 20 0 409524 57780 8724 S 1.7 0.0 329:38.63 glusterfsd
可以看到 md10_resync
始终处于 D
状态
检查
md10
可以看到状态正常,且正在check
:
mdadm -D /dev/md10
输出显示:
/dev/md10:
Version : 1.2
Creation Time : Wed Aug 16 15:29:17 2023
Raid Level : raid10
Array Size : 22499205120 (21456.91 GiB 23039.19 GB)
Used Dev Size : 3749867520 (3576.15 GiB 3839.86 GB)
Raid Devices : 12
Total Devices : 12
Persistence : Superblock is persistent
Intent Bitmap : Internal
Update Time : Thu Nov 9 17:51:45 2023
State : clean, checking
Active Devices : 12
Working Devices : 12
Failed Devices : 0
Spare Devices : 0
Layout : near=2
Chunk Size : 512K
Check Status : 56% complete
Name : u94j03331.alipay.ea134:10 (local to host u94j03331.alipay.ea134)
UUID : 6f256e54:6534cc6a:be2241a5:f2d61129
Events : 44863
Number Major Minor RaidDevice State
0 259 6 0 active sync set-A /dev/nvme0n1p1
1 259 17 1 active sync set-B /dev/nvme1n1p1
2 259 16 2 active sync set-A /dev/nvme2n1p1
3 259 11 3 active sync set-B /dev/nvme3n1p1
4 259 24 4 active sync set-A /dev/nvme4n1p1
5 259 18 5 active sync set-B /dev/nvme5n1p1
6 259 12 6 active sync set-A /dev/nvme6n1p1
7 259 22 7 active sync set-B /dev/nvme7n1p1
8 259 23 8 active sync set-A /dev/nvme8n1p1
9 259 10 9 active sync set-B /dev/nvme9n1p1
10 259 15 10 active sync set-A /dev/nvme10n1p1
11 259 8 11 active sync set-B /dev/nvme11n1p1
排查¶
在生产环境中,当每周末1点启动 raid-check
之后,业务繁忙期间会出现较高的延迟(大约是正常状态的2倍,也就是 20ms => 40ms)
检查服务器 mdadm 同步速度 ,
md
设备同步速度:
cat /sys/block/md10/md/sync_speed_max
默认值是 200000
也就是 200MB/s
:
200000 (system)
观察服务器
top
输出,可以看到md10_resync
持续D
状态,但是iowait
始终是 0
%Cpu(s): 0.0 us, 0.9 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 13137145+total, 11335824+free, 4092892 used, 13920332 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 11808108+avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
7608 root 20 0 0 0 0 R 42.7 0.0 5230:41 md10_raid10
112353 root 25 5 0 0 0 D 14.9 0.0 30:11.22 md10_resync
38355 root 20 0 409524 57780 8724 S 1.7 0.0 329:38.63 glusterfsd
检查
md10_resync
进程堆栈:
#cat /proc/47438/stack
[<0>] msleep+0x2a/0x40
[<0>] md_do_sync+0xd39/0x1000
[<0>] md_thread+0x11f/0x160
[<0>] kthread+0xf5/0x130
[<0>] ret_from_fork+0x1f/0x30
[<0>] 0xffffffffffffffff
通过 Linux “魔力” 系统请求组合键 SysRq 获取系统所有D状态dump:
echo w >/proc/sysrq-trigger
不幸的是,陷入
D
状态的md10_resync
无法杀死,即使使用了kill -9 47438
也不行我尝试将同步速度降低到
0
,结果发现最低实际上是2MB/s
:
#sysctl -w dev.raid.speed_limit_max=0
dev.raid.speed_limit_max = 0
#cat /proc/mdstat
Personalities : [raid10]
md10 : active raid10 nvme11n1p1[11] nvme10n1p1[10] nvme9n1p1[9] nvme8n1p1[8] nvme7n1p1[7] nvme6n1p1[6] nvme5n1p1[5] nvme4n1p1[4] nvme3n1p1[3] nvme2n1p1[2] nvme1n1p1[1] nvme0n1p1[0]
22499205120 blocks super 1.2 512K chunks 2 near-copies [12/12] [UUUUUUUUUUUU]
[>....................] check = 1.8% (422515840/22499205120) finish=173123.3min speed=2124K/sec
bitmap: 1/168 pages [4KB], 65536KB chunk
unused devices: <none>
而且,即使限速以后, md10_resync
依然是 D
状态,也无法停止
也就是说,一旦启动了 raid-check
就无法停止了? 不是的
控制 mdadm
的操作是通过 md_sync_action 来实现的,通过向 sync_action
发出 idle
指令,就能停止: