使用 ZFS 记录大小 16k 而不是 128k 的缺点

Kam*_*mil 2 zfs performance-tuning qemu

我在专用服务器上使用 Proxmox。对于生产,我仍在使用 ext4,但我决定开始使用 ZFS。

因此,我创建了两个具有不同记录大小的独立 ZFS 存储池:

  • 除 MySQL/InnoDB 之外的所有内容均为 128k
  • MySQL/InnoDB 为 16k(因为 16k 是我使用的默认 InnoDB 页面大小)

我添加了 16k 池来检查它是否真的对 MySQL/InnoDB 数据库性能产生影响。确实如此。我每秒的事务量增加了大约 40%,延迟降低了 25%(我已经使用sysbenchtpcc对此进行了彻底测试)。

出于实际原因,目前我更愿意使用一个具有 16k 记录大小的大池,而不是两个单独的部分(16k 和 128k)。我知道,我可以在单个 ZFS 池上创建子卷并为它们提供不同的记录大小,但这也是我想避免的。我更喜欢通过 Proxmox GUI 进行管理。


我的问题:

  1. 如果我开始对所有内容使用较小的 (16k) 记录大小而不是 128k(Proxmox 上的默认值),我会遇到哪些缺点?

  2. QEMU 磁盘映像是否具有与 innodb_page_size 等效的值?如果是的话 - 它的尺寸是多少?

    我尝试用以下方法检查qemu-img info

     $ qemu-img info vm-100-disk-0.raw
     image: vm-100-disk-0.raw
     file format: raw
     virtual size: 4 GiB (4294967296 bytes)
     disk size: 672 MiB
    
    Run Code Online (Sandbox Code Playgroud)

服务器使用情况是:

  • www/php 的容器(大量小文件,但在容器磁盘文件内)
  • java/spring应用程序的容器(它们产生大量日志)
  • mysql/innodb 数据库的容器(无需解释)
  • 本地备份/恢复操作,包括压缩备份
  • 处理大型 gzip 文件(不是每天,低优先级)

sho*_*hok 7

简短的回答:这实际上取决于您预期的用例。作为一般规则,默认的 128K 记录大小是机械磁盘的不错选择(其中访问延迟主要由寻道时间 + 旋转延迟决定)。对于全 SSD 池,我可能会使用 16K 或最多 32K(前提是后者能够显着提高数据的压缩效率)。

长答案:对于 HDD 池,我建议坚持使用默认的数据集 128K 记录大小,并为 zvol 使用 128K volblocksize。其基本原理是,7.2K RPM HDD 的访问延迟主要由寻道时间决定,而寻道时间不记录大小/卷块大小而变化。让我们做一些数学计算:7.2K HDD 的平均寻道时间为 8.3ms,而读取 128K 块只需要约 1ms。因此,命令头部寻道(8ms+延迟)来读取小的 16K 块似乎很浪费,特别是考虑到对于较小的读/写,您仍然受到 r/m/w 延迟的影响。此外,较小的记录大小意味着较大的元数据开销和较差的压缩。因此,虽然 InnoDB 发出 16K IO,并且对于专用数据集,可以使用 16K 记录大小来避免 r/m/w 和写入放大,但对于混合用途数据集(即:不仅用于数据库本身,还用于更通用的数据集)工作负载)我建议保持在 128K,特别是考虑到小记录大小的压缩影响。

然而,对于 SSD 池,我会使用更小的 volblocksize/recordsize,可能在 16-32K 范围内。理由是 SSD 的访问时间要短得多,但耐用性有限,因此为较小的写入写入完整的 128K 块似乎过多。此外,大记录大小所要求的 IO 带宽放大在现代 SSD 等高 IOP 设备上更令人担忧(即:在达到 IOP 限制之前,您可能面临带宽饱和的风险)。