假设有这样一个场景,我们app open一个cephfs(以ceph-fuse挂载)的文件后,不断顺序读取4k数据,app->vfs->fuse->ceph-fuse->ceph这里IO大小的变化是怎样的?
结论
app->vfs app是buffer read,所以不断通过缺页中断从存储(磁盘)加载到pagecache,目前看到是预读了多个page(128K的整数倍),说明vfs这里检测到顺序读,执行了预读逻辑
vfs->fuse->ceph-fuse 超过128K的都会被fuse按照128K切分,所以ceph-fuse拿到的请求都是128K的
ceph-fuse->ceph ceph-fuse会检测是否是顺序读,根据顺序程度动态调整预读大小128K - 16M之间(client_readahead_min=131072 client_readahead_max_periods=4),实际情况(按照4k顺序读一个大文件)我们抓取到,33%没有预读,23%预读了128K,21%预读了384K,8%预读了1M,剩下的预读范围在[128K, 16M]之间
测试环境
cephfs client采取默认配置
"client_readahead_max_bytes": "0",
"client_readahead_max_periods": "4",
"client_readahead_min": "131072",
代码逻辑分析
fuse_ll_read
-> ll_read
-> _read
-> _read_async # 该函数这里会判断有无预读选项,合理设置当前预读大小
-> objectcacher->file_read
-> objectcacher->readx
-> objectcacher->_readx
-> bh_read