美文网首页CephCeph
IO侦探:多进程写ceph-fuse单文件性能瓶颈侦查

IO侦探:多进程写ceph-fuse单文件性能瓶颈侦查

作者: relaX_2363 | 来源:发表于2018-12-07 15:08 被阅读108次

近期接到ceph用户报案,说是多进程direct写ceph-fuse的单个文件,性能很低,几乎与单进程direct写文件的性能一样。关乎民生,刻不容缓,笔者立即展开侦查工作~


一、复现案情,寻踪追记

笔者通过fio工具展开测试,分别测试了单进程和多进程direct随机写ceph-fuse的单个文件的性能情况。

fio -filename=/mnt/fuse/file_1T -direct=1  -rw=randwrite -ioengine=sync -bs=4K -size=1G  -numjobs=1 -runtime=180 -group_reporting -name=test
fio -filename=/mnt/fuse/file_1T -direct=1  -rw=randwrite -ioengine=sync -bs=4K -size=1G  -numjobs=16 -runtime=180 -group_reporting -name=test

结果显示,无论单进程,还是多进程,而且无论多少进程,iops结果差不多都是50左右(磁盘未开write-cache)。那么,多进程写多个文件呢,性能又是怎样的?

这里注意了,将fio的参数filename改成directory后,对于多进程,fio会为每个进程创建一个测试文件。

fio -directory=/mnt/fuse/ -direct=1  -rw=randwrite -ioengine=sync -bs=4K -size=1G -numjobs=16 -runtime=180 -group_reporting -name=test

结果显示,iops大概是800左右,正好是单进程50的16(进程数)倍,怎么这么巧?

二、分析案情,锁定可能的嫌疑人

写同一个文件,单进程和多进程具有相同的iops性能,说明多进程在io路径的某个环节变成了串行,从而导致多进程实际上也变成了单进程。

我们先来看下ceph-fuse的io链条:

用户态程序fio -> vfs -> kernel fuse -> libfuse -> ceph-fuse -> [mds] -> ceph cluster

笔者之前看过链条上一些环节的代码,但由于代码量太大,代码的细节太多,所以认知并不深入,无法直接定位到凶手。

为了帮助分析案情,这里简单描述下这条io链:
用户态程序fio通过多进程进行direct随机写,通过vfs后进入kernel fuse,kernel fuse会将io请求放入到pending队列,然后等待结果。用户态libfuse的多个进程通过/dev/fuse设备读取pending队列中请求,然后调用更底层的ceph-fuse进行处理。ceph-fuse最终将请求发送给mds或者ceph集群进行处理。

必然是上述io链条中某个环节导致了案情的发生。然而我们很难熟知于io链条中的每一环,所以我们需要根据更多已知的线索来缩小io链条的排查范围。

三、搜集线索,缩小排查范围

目前已知的线索有:

① fio多进程和单进程写同一文件性能几乎一致
② fio多进程写进程数个文件的性能 = 单进程性能 * 进程数

由于没有更多的线索,笔者开始对io链条进行排查。先从熟悉的ceph-fuse、mds和ceph cluster开始。

嫌疑人 分析
ceph cluster 对比多进程写单文件和多进程写多文件的性能,说明出现案情时,ceph cluster不是瓶颈
mds 由于fio测试是单客户端的,所以多进程的写也不会竞争fw的caps,另外fio的测试,涉及mds的请求很少,所以mds作案的可能性很小
ceph-fuse 这是笔者怀疑的重点,众所周知,ceph-fuse有把client大锁,通过阅读代码发现,ceph-fuse在发送写请求给osd后就释放了client锁,并没有持锁等待结果,这虽然对写性能有一定的影响,但不至于将多进程io串行

笔者展开更多测试,发现了一条重要的线索:

③ 16进程direct随机写16个文件时,通过kernel fuse的controlfs(/sys/fs/fuse/connections/39/waiting)看到等待的请求数一直是16,而16进程direct随机写单文件时,等待的请求数一直是1

线索③说明,在libfuse之前,多进程已经被串行化,这样可以基本排除libfuse、ceph-fuse、mds、ceph cluster的嫌疑了,笔者可以把精力放在io链条的前面了。

用户态程序fio -> vfs -> kernel fuse

静下心来,思索下...
多进程写单个文件,io被完全串行化,凭经验,要么是有文件锁,要么有inode锁。先朝这方向走一下,我们需要定位下锁在io链条的哪个环节,逐个分析下每个环节。

用户态程序fio:
通过查看fio的man page,笔者发现fio有个lockfile的参数,当lockfile设置成exclusive或者readwrite时,多进程的写会被串行化,然而该参数的默认值是none,所以可以排除用户态程序fio的嫌疑。

vfs:
vfs是内核很薄的一层,而且linux上可以通过flock和fcntl对文件进行加锁,在没有用户态程序调用的情况下,vfs显然不会私自对文件和inode加锁,并且,这个案情在kernel cephfs客户端下不存在,所以可以排除vfs的嫌疑。

排除了其他io环节,最后只剩下 kernel fuse ,是笔者熟悉程度相对比较低的模块,看来需要重点招待了。

四、搜集证据,锁定凶手

笔者重新阅读kernel fuse的io流程代码,最终拿到证据,真相是如此简单....

static ssize_t fuse_direct_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos){
    ...
    /* Don't allow parallel writes to the same file */
    mutex_lock(&inode->i_mutex);
    res = __fuse_direct_write(&io, &iov, 1, ppos);
    if (res > 0)
        fuse_write_update_size(inode, *ppos);
    mutex_unlock(&inode->i_mutex);
    ...
}

凶手作案手法:
多进程direct写io到kernel fuse的该函数后,拿到inode锁,进行io请求,io请求发送到pending队列后,会持锁等待io请求结束,从而导致多进程的direct写io被串行化。

相关文章

  • IO侦探:多进程写ceph-fuse单文件性能瓶颈侦查

    近期接到ceph用户报案,说是多进程direct写ceph-fuse的单个文件,性能很低,几乎与单进程direct...

  • PHP把session存到内存中

    php默认使用文件存储session,很容易有性能瓶颈。放到内存中io性能会高很多 memcache 官网:htt...

  • linux 下查看性能状态命令

    解决问题: 性能优化,首先分析是由于哪些瓶颈造成的性能低下, 如 cpu 瓶颈,内存瓶颈,io瓶颈, 或者程序本身...

  • IO优化

    整个IO操作由应用程序,文件系统和磁盘组成。 1:文件损坏的原因 应用程序中的IO操作不是原子操作,文件的跨进程写...

  • mmap 性能分析与优化

    最近项目中需要实现一个进程间共享的动态增长队列(单写多读),采用的是文件 mmap 的方案,有这么几点考虑: 进程...

  • 腾讯三面:进程写文件过程中,进程崩溃了,文件数据会丢吗?

    前几天,有位读者问了我这么个问题: 大概就是,进程写文件(使用缓冲 IO)过程中,写一半的时候,进程发生了崩溃,会...

  • Performance Tuning (TBD)

    性能调优是个大而复杂的系统性问题,涉及Linux系统(进程管理,文件系统,磁盘系统,网络IO处理等),内核参数调优...

  • 监控io性能、free命令、ps命令、Linux下抓包

    监控io性能 监控系统状态 iostat -x关注%util,太高就是磁盘传输速度跟不上 查看哪个进程IO读写繁忙...

  • Eelang 和Go 的对比

    轻量级进程模型: 用同步IO的方法写程序的逻辑,第二点是用尽可能多的并发进程来提升IO并发的能力。 核心思想,第...

  • 文件编程指导

    文件访问是一个很重要的性能瓶颈。 本文主要从以下几方面来提高文件访问的性能: 文件编程建议 OX文件系统介绍 文件...

网友评论

    本文标题:IO侦探:多进程写ceph-fuse单文件性能瓶颈侦查

    本文链接:https://www.haomeiwen.com/subject/husthqtx.html