糟糕的通用dm-crypt(LUKS)写入性能


21

我正在研究一个问题,其中对块设备进行加密在写入时会带来巨大的性能损失。数小时的互联网阅读和实验并没有为我提供适当的了解,更不用说解决方案了。

简而言之,问题是:为什么在将btrfs放在块设备上时,我能获得非常快的写入速度(〜170MB / s),而在两者之间放置dm-crypt / LUKS时,写入速度却急剧下降(〜20MB / s)。文件系统和块设备,尽管该系统还能够维持足够高的加密吞吐量?

情境

/home/schlimmchen/random是一个4.0GB的文件,其中填充了/dev/urandom以前的数据。

dd if=/dev/urandom of=/home/schlimmchen/Documents/random bs=1M count=4096

读起来超级快:

$ dd if=/home/schlimmchen/Documents/random of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 6.58036 s, 648 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 0.786102 s, 5.4 GB/s

(第二次,显然是从缓存中读取了文件)。

未加密的btrfs

该设备直接使用btrfs格式化(块设备上没有分区表)。

$ sudo mkfs.btrfs /dev/sdf
$ sudo mount /dev/sdf /mnt
$ sudo chmod 777 /mnt

写入速度高达〜170MB / s:

$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test1 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 27.1564 s, 157 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test2 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 25.1882 s, 169 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test3 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 29.8419 s, 143 MB/s

读取速度远高于200MB / s。

$ dd if=/mnt/dd-test1 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 19.8265 s, 215 MB/s
$ dd if=/mnt/dd-test2 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 19.9821 s, 213 MB/s
$ dd if=/mnt/dd-test3 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 19.8561 s, 215 MB/s

块设备上的加密btrfs

该设备用LUKS格式化,结果设备用btrfs格式化:

$ sudo cryptsetup luksFormat /dev/sdf
$ sudo cryptsetup luksOpen /dev/sdf crypt
$ sudo mkfs.btrfs /dev/mapper/crypt
$ sudo mount /dev/mapper/crypt /mnt
$ sudo chmod 777 /mnt
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test1 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 210.42 s, 20.3 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test2 bs=1M 
4265841146 bytes (4.3 GB) copied, 207.402 s, 20.6 MB/s

读取速度仅受到轻微影响(为什么会这样?):

$ dd if=/mnt/dd-test1 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 22.2002 s, 192 MB/s
$ dd if=/mnt/dd-test2 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 22.0794 s, 193 MB/s

luksDump:http://pastebin.com/i9VYRR0p

块设备上btrfs上文件中的加密btrfs

写入加密文件时,写入速度“飙升”到150MB / s以上。我将一个btrfs放到块设备上,分配了一个16GB的文件,lukfsFormat并进行了安装。

$ sudo mkfs.btrfs /dev/sdf -f
$ sudo mount /dev/sdf /mnt
$ sudo chmod 777 /mnt
$ dd if=/dev/zero of=/mnt/crypted-file bs=1M count=16384 conv=fsync
17179869184 bytes (17 GB) copied, 100.534 s, 171 MB/s
$ sudo cryptsetup luksFormat /mnt/crypted-file
$ sudo cryptsetup luksOpen /mnt/crypted-file crypt
$ sudo mkfs.btrfs /dev/mapper/crypt
$ sudo mount /dev/mapper/crypt /tmp/nested/
$ dd if=/home/schlimmchen/Documents/random of=/tmp/nested/dd-test1 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 26.4524 s, 161 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/tmp/nested/dd-test2 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 27.5601 s, 155 MB/s

为什么写性能会这样提高?文件系统和块设备的这种特殊嵌套可实现什么以帮助提高写入速度?

设定

在运行相同发行版和内核的两个系统上,该问题可重现。但是,我还观察到System2上内核3.19.0的写入速度较低。

  • 设备:SanDisk Extreme 64GB USB3.0 USB记忆棒
  • 系统1:Intel NUC 5i5RYH,i5-5250U(Broadwell),8GB RAM,三星840 EVO 250GB SSD
  • 系统2:联想T440p,i5-4300M(Haswell),16GB RAM,三星850 PRO 256GB SSD
  • 发行版/内核:Debian Jessie,3.16.7
  • 加密设置:1.6.6
  • /proc/crypto对于System1:http//pastebin.com/QUSGMfiS
  • cryptsetup benchmark对于System1:http : //pastebin.com/4RxzPFeT
  • btrfs(-tools)是版本3.17
  • lsblk -t /dev/sdfhttp//pastebin.com/nv49tYWc

思想

  • 据我所知,对齐并不是原因。即使记忆棒的页面大小为16KiB,cryptsetup有效载荷起始也始终与2MiB对齐。
  • --allow-discards (对于cryptsetup的luksOpen)没有帮助,正如我所期望的那样。
  • 在进行更少的实验时,我观察到通过USB3.0适配器连接的外部硬盘驱动器的行为非常相似。
  • 在我看来,该系统正在写入64KiB块。我尝试过的systemtrap脚本至少表明了这一点。/sys/block/sdf/stat由于大量写入被合并,因此支持了该假设。所以我的猜测是,写得太小不是原因。
  • 不能将块设备队列调度程序更改为NOOP。
  • 将加密放入LVM卷中无济于事。

在每次测试之前清除磁盘高速缓存将消除它作为速度的可能原因(目前在ram之外无法实现648MB / s的声音)
Xen2050 2016年

Answers:


18

答案(如我现在所知):并发

简而言之:我的顺序写入(无论使用dd还是在复制文件时(例如...在日常使用中))都变成了伪随机写入(不好),因为在并发之后有四个线程正在同时将加密数据写入块设备加密(良好)。

缓解措施(针对“较旧”的内核)

可以通过增加IO调度程序队列中排队的请求数量来减轻负面影响,如下所示:

echo 4096 | sudo tee /sys/block/sdc/queue/nr_requests

就我而言,这是我的问题中解释的4GB随机数据测试吞吐量的近三倍(〜56MB / s)。当然,与未加密的IO相比,性能仍然不足100MB / s。

调查中

多核 blktrace

我进一步研究了将btrfs放在LUKS加密块设备顶部的问题场景。为了显示向实际块设备发出哪些写指令,我使用了blktrace这样的命令:

sudo blktrace -a write -d /dev/sdc -o - | blkparse -b 1 -i - | grep -w D

这样做是(据我所能理解的)跟踪IO请求为/dev/sdcwrite ” 类型的IO请求,然后将其解析为人类可读的输出,但进一步将输出限制为操作“ D ”,即(根据man blkparse) “ 向驱动程序发出了IO ”。

结果是这样的(请参阅多核日志的输出约5000行):

8,32   0    32732   127.148240056     3  D   W 38036976 + 240 [ksoftirqd/0]
8,32   0    32734   127.149958221     3  D   W 38038176 + 240 [ksoftirqd/0]
8,32   0    32736   127.160257521     3  D   W 38038416 + 240 [ksoftirqd/0]
8,32   1    30264   127.186905632    13  D   W 35712032 + 240 [ksoftirqd/1]
8,32   1    30266   127.196561599    13  D   W 35712272 + 240 [ksoftirqd/1]
8,32   1    30268   127.209431760    13  D   W 35713872 + 240 [ksoftirqd/1]
  • 第1列:块设备的主要,次要
  • 第2列:CPU ID
  • 第3列:序列号
  • 第4列:时间戳记
  • 第5列:进程ID
  • 列6:动作
  • 第7栏:RWBS数据(类型,扇区,长度)

这是dd将4GB随机数据加载到已挂载文件系统上时产生的输出的片段。显然,至少涉及两个过程。剩余的日志显示所有四个处理器都在实际运行。可悲的是,不再对写请求进行排序。当CPU0正在写入第38038416th个扇区的某个位置时,此后预定的CPU1正在写入第35713872nd个扇区的某个位置。那很糟。

单核 blktrace

在禁用多线程并禁用CPU的第二个内核之后,我进行了相同的实验。当然,只有一个处理器参与写入控制棒。但更重要的是,写入请求是正确顺序的,这就是为什么在其他设置相同的情况下,可以达到〜170MB / s的完整写入性能的原因。

看一下单核日志中的大约5000行输出

讨论区

现在,我知道了原因和正确的Google搜索条件,有关此问题的信息浮出水面。事实证明,我不是第一个注意到的人。

在当前内核中已修复(> = 4.0.2)

因为我(后来)发现内核提交显然针对了这个确切的问题,所以我想尝试更新的内核。[在自己编译之后,发现它已经存在了。debian/sid]事实证明,此问题确实已解决。我不知道该修复程序出现在哪个确切的内核版本中,但是原始提交将为感兴趣的任何人提供线索。

作为记录:

$ uname -a
Linux t440p 4.0.0-1-amd64 #1 SMP Debian 4.0.2-1 (2015-05-11) x86_64 GNU/Linux
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test bs=1M conv=fsync
4294967296 bytes (4.3 GB) copied, 29.7559 s, 144 MB/s

致作者Mikulas Patocka的帽子提示。


1
我在内核4.12.12的luks上使用btrfs,并且速度仍然存在!
brauliobo

为什么说减速仍然存在?您正在使用什么参考,因此没有遇到速度下降的情况?你的设置是什么?仅删除LUKS时是否检查驱动器性能?
schlimmchen


1
现在,我明白了您为什么会写关于仍然经历“减速”的文章。但是,您的问题仅与此相关,绝对不是同一问题(滞后与性能低下)。我也确实遇到了这些烦人的问题,因此,非常感谢您在这里指出您的问题!不使用LUKS不是一种选择,但是很高兴知道它似乎与原因有关。
schlimmchen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.