问题
为了测试cephfs的可用性,我们对cephfs进行了几组stripe的测试,在跑自动化测试时,发现fio总是会跑一部分后hang住,而此时ceph -s输出显示read值太大,但实际环境中查看并没这么大的流量。
ceph输出
1 | # ceph -w |
分析:cephfs client io显示的信息是正确的。从后面的分析得知cephfs client一直loop着尝试read object,单次read就有64MB,object数据缓存在osd的内存里,所以ceph统计的read速率很大。
查看网络
用iftop看网络的流量只有10MB/s
1 | # iftop -B -i eth4 |
对比几个stripe
发现对64MB的无条带化的object读时,会触发这个bug:
1 | # getfattr -n ceph.file.layout dir4/tstfile |
bs=64M的fio hang住
1 | # fio -filename=/home/yangguanjun/cephfs/dir4/tstfile -size=20G -thread -group_reporting -direct=1 -ioengine=libaio -bs=64M -rw=read -iodepth=64 -iodepth_batch_submit=8 -iodepth_batch_complete=8 -name=write_64k_64q |
bs=32M的fio hang住
1 | # fio -filename=/home/yangguanjun/cephfs/dir4/tstfile -size=20G -thread -group_reporting -direct=1 -ioengine=libaio -bs=32M -rw=read -iodepth=64 -iodepth_batch_submit=8 -iodepth_batch_complete=8 -name=write_64k_64q |
bs=16M的dd hang住
1 | # dd if=tstfile of=/dev/null bs=16M count=200 |
1 | # ceph -w |
ceph cluster节点信息
在ceph cluster的一个节点上看到测试节点有读数据请求
1 | # iftop -n -i eth4 |
查看sdg没有io
1 | # iostat -kx 2 sdg |
查看文件location
测试文件的location信息,正好第一块数据就在osd 15上
1 | # cephfs tstfile show_location |
停止ceph osd 15
1 | # systemctl stop ceph-osd@15.service |
过一会查看osd 15所在节点没有与测试节点的数据流量了
这时在ceph osd 0节点,出现了与测试节点的数据流量,查看发现正好是osd 0与测试节点的数据通信
查看此时测试文件第一个object的map信息如下:
1 | # ceph osd map cephfs_data 10000000805.00000000 |
问题明确
现在这个问题很好重现了
- 创建一个
stripe_unit=67108864 stripe_count=1 object_size=67108864
的文件 - dd if=/dev/zero of=foxfile bs=64M count=1 写成功
- dd if=foxfile of=/dev/null bs=64M count=1 读就会hang住
- 查看测试节点与对应的object所在的osd有数据流量
通过strace
命令查看dd读数据时确实hang在read函数:
1 | # strace dd if=foxfile of=/dev/null bs=64M count=1 |
收集client log
参考文章 cephfs kernel client debug
收集osd log
1 | # ceph daemon /var/run/ceph/ceph-osd.<osdid>.asok config set debug_osd "20/20" |
分析log
在cephfs client的log中能循环发现如下:
1 | Jul 6 11:30:29 cephfs-client kernel: [ 2010.231008] ceph_sock_data_ready on ffff88202c987030 state = 5, queueing work |
证明cephfs client一直在尝试读取osd数据,但收到数据后却认为msg为null
在ceph osd的log中能循环发现如下:
1 | 2017-07-06 11:30:29.185056 7f1788eb2700 1 osd.20 188 ms_handle_reset con 0x7f1748c39d80 session 0x7f170f4f31c0 |
分析看出cephfs client发送read 64MB的request,ceph osd读64M数据return,但是cephfs client认为msg为null,然后重试
一直重复上面的请求,所以cephfs client的IO就hang住了
提交bug
提交该bug到ceph社区:
http://tracker.ceph.com/issues/20528
cephfs client端的配置限制了read message的最大size为16M。
in net/ceph/messenger.c
1 | static int read_partial_message(struct ceph_connection *con) |
所以我们使用cephfs中,不能配置文件的stripe_unit
大于16M。