Kaushik Iska:什么是直接 I/O,为什么 ClickHouse Managed Postgres 将其用于备份?

Kaushik Iska:什么是直接 I/O,为什么 ClickHouse Managed Postgres 将其用于备份?

💡 原文英文,约3500词,阅读约需13分钟。
📝

内容提要

ClickHouse Managed Postgres 备份使用 Direct I/O 绕过页缓存,避免驱逐数据库热数据,并减少内核拷贝与 CPU 开销。但 Direct I/O 失去预读,在 RAID0 上小读仅占用单盘。按磁盘数将读放大到整条条带(如 4 MiB),并根据硬件调整并发读者数,可恢复吞吐。实测备份延迟从基线的 4.7 倍降至 1.5 倍,CPU 节省约 14%。

🔎

延伸解读

直接 I/O 的代价与补偿

直接 I/O 绕过页缓存,避免备份驱逐数据库热数据,但也失去了内核预读。在 RAID0 上,小读请求只落在单块盘上,导致其他盘闲置。文章通过将读大小调整为覆盖整个条带(如 4 MiB),并增加并发读者数,恢复了吞吐。这说明直接 I/O 并非即插即用,需要根据存储布局调整参数。

读大小与并发读者的权衡

文章对比了不同读大小和读者数对备份性能的影响。默认 128 KiB 直接读在 24 读者下备份耗时 96 秒,而 4 MiB 读在 48 读者下仅需 71 秒。增大读大小让每次请求跨越所有盘,提高单次效率;增加读者数则提升设备利用率。但读者数并非越多越好,需考虑 CPU 和磁盘类型,例如密集 NVMe 实例可使用全部 vCPU 作为读者。

对生产环境的实际影响

在 467 GB 数据库的实测中,缓冲备份导致 40 GiB 热表被完全驱逐,查询 p99 延迟升至基线 4.7 倍,且备份结束后仍有冷读尾巴。直接 I/O 备份则未驱逐任何热数据,p99 仅 1.5 倍,备份结束延迟立即恢复。同时 CPU 使用减少约 14%。这表明直接 I/O 不仅保护了查询性能,还降低了备份对系统资源的整体占用。

配置生成与回退机制

ClickHouse Managed Postgres 根据服务器的 vCPU 数、内存、磁盘数量和是否密集 NVMe 自动生成 wal-g 配置,包括直接 I/O 开关、读块大小和并发读者数。同时提供两个特性标志作为逃生舱:一个关闭直接 I/O 回退到缓冲读,另一个回退到 wal-g 默认值。这种设计便于在遇到内核或驱动异常时快速恢复,体现了对生产环境稳定性的重视。

❓

Q&A

什么是 Direct I/O?为什么 ClickHouse Managed Postgres 在备份时要使用它?

Direct I/O 是一种通过 O_DIRECT 标志让内核跳过页缓存的读取方式。ClickHouse Managed Postgres 在备份时使用它,是为了避免备份读取把数据库的热数据从页缓存中驱逐出去,同时减少内核拷贝和 CPU 开销。

使用 Direct I/O 备份会带来什么新问题?如何解决?

Direct I/O 会失去内核预读,在 RAID0 上小读只占用单块盘,导致吞吐下降。解决方法是将每次直接读取的大小放大到覆盖整个条带(例如 4 MiB),并根据硬件调整并发读者数,从而恢复吞吐。

ClickHouse Managed Postgres 如何根据硬件配置 Direct I/O 的读取大小和并发读者数?

读取大小按磁盘数计算:每块盘 256 个 4 KiB 块,即每盘 1 MiB,四盘 RAID0 则为 4 MiB。并发读者数方面,在密集 NVMe 家族或 vCPU 数不超过 2 时使用全部 vCPU 数,其他情况使用一半 vCPU 数。

Direct I/O 备份相比缓冲备份,在延迟和 CPU 方面有哪些实测改进?

实测显示,缓冲备份使查询 p99 延迟达到基线的 4.7 倍,而 Direct I/O 备份仅 1.5 倍,且备份结束后延迟立即恢复。CPU 方面,Direct I/O 备份节省约 14% 的 CPU(从 65% 降至 60%)。

缓冲备份为什么会驱逐数据库的热数据?

缓冲备份读取的字节会进入页缓存,而页缓存有限且共享。为了给这些不会再被读取的数据腾出空间,内核会驱逐 Postgres 之前留在内存中的数据,导致后续查询需要重新从磁盘读取。

ClickHouse Managed Postgres 如何通过 cgroups 和 Direct I/O 保护数据库工作负载?

备份运行在独立的 cgroup 中,CPUWeight=25,确保数据库获得四倍 CPU 份额;内存方面,上传缓冲区限制在 RAM 的 5%;Direct I/O 则确保备份读取不进入页缓存,不干扰数据库的缓存数据。

🏷️

标签

➡️

继续阅读