测试准备
测试目的
Docker在DeviceMapper这块支持两种存储模式,分别是docker默认的loop volume和Direct VLM。为了了解其中区别也是为了依据业务进行选型,所以选择了对二者进行性能测试。
测试范围
性能指标: IOPS、吞吐、IO响应(本次测试忽略)
测试环境:物理机(sas /raid50)、 Loop Container、 LVM Container
IO类型: 顺序读、顺序写、随机读、随机写、随机读写(数据读写值相加)
测试方法
测试参数:
idepth 64 bs:16k
IOPS/吞吐:
使用FIO测试一次的结果,命令行方面仅仅调整rw参数来实现不同的IO类型
fio -filename ./hello -direct=1 -iodepth 64 -thread -rw=randread -ioengine=libaio -bs=16k -size=100G -numjobs=10 -runtime=1000 -group_reporting -name=mytest |
IO响应
暂时略过
测试数据
宿主机单Container环境测试
LVM Direct的设备的顺序读写是物理的一半,而随机读写则非常接近于裸的物理磁盘。
LOOP几乎是一个超越SSD性能的数据,fio参数无法跨越外层文件系统的缓存。
这里给出一个简答数据,当单台物理机上高密集IO的Container数量增加时,loop的性能明显下降,而LVM则下降有限。
按照理论层面分析,随着系统负载的升高,loop方案的劣势将会逐渐明显,并体现在io的非常不稳定。
结论分析
Loop Volume
Docker默认会在/var/lib/docker/devicemapper/devicemapper目录下生成data和metadata两个稀疏文件,并将两个文件挂为loop设备作为块设备来使用。通过losetup ls可以查询到具体的设备。依据Device Mapper的thin pool的制作过程,有了data 和metadata两个块设备就可以开始制作DM thin pool了。由于DM是通过块映射来实现的,所以可以在DM设备上继续递归创建volume,之后每个Container的设备都是pool上的卷。
从测试结果来看loop设备的读写吞吐和iops都非常高,但是从测试过程来看绝大多数时间fio打印的实时数据都是0。从宿主机上来看增加了flush-253:1进程,本质上就是系统再为它刷缓存。
同时loop设备是不支持O_DIRECT的。
Direct LVM
从存储结构上看Direct和LVM的最大不同是创建DM thin pool的不再是通过losetup挂载的两个稀疏文件,而是两个裸的真正的块设备。可以在系统启动进程中通过–storage-op dm.datadev 和–storage-op dm.metadatadev来指定具体的块设备的来源。
Loop Volume VS Direct LVM
direct lvm直接使用dm-thin内核模块,直接使用raw分区,在高负载和高密度下具有性能优势。
direct lvm的O_DIRECT
direct lvm的读写性能表现更加稳定。
direct lvm能避免loop 的block limitation
最终结论
任何情况都应该使用Direct LVM