前言
使用librbd通过tgt出iscsi,多路径数据是一致的,由于环境的原因,切换为kernel rbd 出iscsi,然后通过不同的iscsi路径写入后,发现在rbd端就出现了数据没有刷新的问题
问题分析
这里有个类似的问题
https://github.com/ceph/ceph-csi/issues/461
这个是通过把rbd map到不同的节点,通过dd写入的时候发现数据不同步,需要通过增加参数direct才能保证数据一致,我们通过官网的描述和这个issue里面的回答可以看到
https://docs.ceph.com/docs/luminous/rbd/rbd-config-ref/
The kernel driver for Ceph block devices can use the Linux page cache to improve performance.
rbd内核客户端是会通过linux page cache来改善性能的,而librbd是可以通过参数关闭缓存的,这个在我以前的理解里面krbd是没有缓存的,实际上这个是存在缓存的
而通过tgt的客户端写入,数据到了tgt,而tgt可以利用kernel的rbd page缓存一点数据,然后就没下刷到后端了,从另外一个客户端读取数据的时候就看到数据是没刷过去的,这个跟把rbd格式化文件系统,然后map到两台机器,一台写入,另外一台查看,也是存在看不到数据的情况
而issue里面也说的很清楚,这个同步写的过程应该交给上层软件去控制,也就是软件去控制o_direct的写入
问题复现
复现问题比较容易,配置kernel rbd,map到服务器,然后配置tgt,两台机器配置相同的tgt,然后通过iscsi客户端连接两台tgt的iscsi server,那么iscsi的客户端机器就增加了两个盘符
直接对裸盘进行dd的写入
dd if=/dev/urandom of=/dev/sdc bs=512 count=8000
写完以后在 rbdmap的机器上面执行
sha512sum /dev/rbd/rbd/testrbd
两台机器都执行检查,这个时候默认情况下,得到的输出是不一致的
解决问题
配置文件增加一个配置
<target iqn.2008-09.com.example:server.target2>
backing-store /dev/rbd/rbd/testrbd
bsoflags direct
#write-cache off
</target>
增加一个bsoflags direct就可以保证数据一致性了,下面的写缓存应该是客户端那边的缓存,缓存客户端的数据还没来到rbd这边,来到以后也是direct的写,也是能保证一致性的,所以可以保留
测试过程中还遇到另外一个问题backing-store如果写成direct-store,下面的配置的参数就不能生效了,所以这个地方需要注意下