来自 Cloudflare 的开发人员
Cloudflare 使用 dm-crypt 来加密用于在 CDN 上缓存内容的存储设备上的数据。 Dm-crypt 在块设备级别运行,加密写入 I/O 请求并解密读取请求,充当块设备和文件系统驱动程序之间的层。
使用该包评估 dm-crypt 的性能
起初,人们怀疑内核密码系统中使用了低效算法。 但测试使用了最快的算法 aes-xts,具有 256 个加密密钥,其运行“cryptsetup benchmark”时的性能比测试 RAM 磁盘时获得的结果高出两倍多。 使用 dm-crypt 标志进行性能调整的实验没有产生结果:当使用“--perf-same_cpu_crypt”标志时,性能甚至下降到 136 MB/s,而当指定“--perf-submit_from_crypt_cpus”标志时,它仅增加至 166 MB/秒。
深入分析操作逻辑发现,dm-crypt 并不像看上去那么简单——当 FS 驱动收到写请求时,dm-crypt 并不会立即处理它,而是将其放入“kcryptd”队列中,这使得不是立即解析,而是在方便的时候解析。 请求从队列发送到 Linux Crypto API 以执行加密。 但由于 Crypto API 使用异步执行模型,加密也不会立即执行,而是绕过另一个队列。 加密完成后,dm-crypt 可能会尝试使用搜索树对挂起的写入请求进行排序
读取时,dm-crypt 首先向“kcryptd_io”队列添加一个请求,以从驱动器接收数据。 一段时间后,数据变得可用并被放置在“kcryptd”队列中进行解密。
Kcryptd 向 Linux Crypto API 发送请求,后者异步解密信息。 请求并不总是经过所有队列,但在最坏的情况下,写请求最多会进入队列 4 次,读请求最多会进入队列 3 次。 每次对队列的命中都会导致延迟,这是 dm-crypt 性能显着下降的关键原因。
使用队列是因为需要在发生中断的情况下工作。 2005 年,当 dm-crypt 当前基于队列的操作模型实现时,Crypto API 还不是异步的。 Crypto API转为异步执行模型后,本质上开始使用双重保护。 还引入了队列来节省内核堆栈消耗,但在 2014 年增加队列之后,这些优化就失去了相关性。 引入了额外的队列“kcryptd_io”来克服大量请求到达时导致等待内存分配的瓶颈。 2015年,引入了额外的排序阶段,因为多处理器系统上的加密请求可能会无序完成(而不是顺序访问磁盘,而是以随机顺序进行访问,并且CFQ调度程序无法有效工作)。 目前,当使用SSD驱动器时,排序已经失去了意义,内核中不再使用CFQ调度器。
考虑到现代驱动器变得更快、更智能,对 Linux 内核中的资源分配系统进行了修订,并重新设计了一些子系统,Cloudflare 工程师
因此,在测试 RAM 磁盘时,dm-crypt 的性能可以提高一倍以上 - 性能从 294 MB/s (2 x 147 MB/s) 增加到 640 MB/s,非常接近裸加密的性能(696 MB /秒)。
在真实服务器上测试负载时,新实施显示的性能非常接近在不加密的情况下运行的配置,并且在具有 Cloudflare 缓存的服务器上启用加密对响应速度没有影响。 未来,Cloudflare 计划将准备好的补丁转移到主 Linux 内核,但在此之前,它们需要重新设计,因为它们针对特定负载进行了优化,并且并未涵盖所有应用领域,例如低端加密。 - 为嵌入式设备供电。
来源: opennet.ru