如何使用 fio 检查磁盘以获得足够的 etcd 性能

笔记。 翻译。:本文是 IBM Cloud 工程师为寻找与 etcd 数据库操作相关的实际问题的解决方案而进行的小型研究的结果。 类似的任务与我们相关,但是,在更广泛的背景下,作者的思考和行动过程可能很有趣。

如何使用 fio 检查磁盘以获得足够的 etcd 性能

全文小结:fio和etcd

etcd 集群的性能高度依赖于底层存储的速度。 etcd 导出各种 Prometheus 指标来监控性能。 其中之一是 wal_fsync_duration_seconds. 在 etcd 的文档中 如果该指标的第 99 个百分位数小于 10 毫秒,则可以认为存储速度足够快……

如果您正在考虑在 Linux 机器上设置 etcd 集群并想要检查驱动器(例如 SSD)是否足够快,我们建议使用名为 FIO. 运行以下命令就足够了(目录 test-data 必须位于测试驱动器的已安装分区中):

fio --rw=write --ioengine=sync --fdatasync=1 --directory=test-data --size=22m --bs=2300 --name=mytest

它仍然只是查看输出并检查第 99 个百分位数是否适合 fdatasync 在 10 毫秒内如果是这样,那么您的驱动器运行速度足够快。 这是一个示例输出:

fsync/fdatasync/sync_file_range:
  sync (usec): min=534, max=15766, avg=1273.08, stdev=1084.70
  sync percentiles (usec):
   | 1.00th=[ 553], 5.00th=[ 578], 10.00th=[ 594], 20.00th=[ 627],
   | 30.00th=[ 709], 40.00th=[ 750], 50.00th=[ 783], 60.00th=[ 1549],
   | 70.00th=[ 1729], 80.00th=[ 1991], 90.00th=[ 2180], 95.00th=[ 2278],
   | 99.00th=[ 2376], 99.50th=[ 9634], 99.90th=[15795], 99.95th=[15795],
   | 99.99th=[15795]

几点说明:

  1. 在上面的例子中,我们调整了参数 --size и --bs 对于特定情况。 从中获得有意义的结果 fio,指定适合您的用例的值。 下面将讨论如何选择它们。
  2. 仅在测试期间 fio 加载磁盘子系统。 在现实生活中,其他进程很可能会写入磁盘(除了那些与 wal_fsync_duration_seconds). 这种额外的负载可以增加 wal_fsync_duration_seconds. 换句话说,如果来自测试的第 99 个百分位数 fio, 仅略小于 10 毫秒,很可能是存储性能不足。
  3. 对于测试,您将需要版本 fio 不低于3.5,因为旧版本不汇总结果 fdatasync 以百分位数的形式。
  4. 以上结论只是一般结论的一小部分 fio.

更多关于 fio 和 etcd

关于 WAL etcd 的几句话

通常,数据库使用 主动记录 (预写日志记录,WAL)。 etcd 也受到影响。 WAL 的讨论超出了本文的范围,但出于我们的目的,您需要知道每个 etcd 集群成员都将 WAL 存储在持久存储中。 etcd 在执行之前将一些键值存储操作(例如更新)写入 WAL。 如果节点在快照之间崩溃并重新启动,etcd 可以根据 WAL 的内容恢复自上一个快照以来的事务。

因此,每次客户端将键添加到 KV 存储或更新现有键的值时,etcd 都会将操作的描述添加到 WAL,WAL 是持久存储中的常规文件。 etcd 必须 100% 确定 WAL 条目在继续之前已实际保存。 要在 Linux 上实现这一点,仅使用系统调用是不够的 write,因为对物理介质的写操作本身可能会延迟。 例如,Linux 可能会在内存中的内核缓存(例如,页面缓存)中保留 WAL 条目一段时间。 为确保数据写入介质,必须在写入后调用系统调用 fdatasync - 这正是 etcd 所做的(正如您在以下输出中看到的那样) strace; 这里 8 - WAL 文件描述符):

21:23:09.894875 lseek(8, 0, SEEK_CUR)   = 12808 <0.000012>
21:23:09.894911 write(8, ".20210220361223255266632$1020103026"34"rn3fo"..., 2296) = 2296 <0.000130>
21:23:09.895041 fdatasync(8)            = 0 <0.008314>

不幸的是,写入持久存储需要一些时间。 长时间执行 fdatasync 调用会影响 etcd 的性能。 在存储库文档中 被指出,为了获得足够的性能,所有调用持续时间的第 99 个百分位数是必要的 fdatasync 写入 WAL 文件时少于 10 毫秒。 还有其他与存储相关的指标,但本文将重点关注该指标。

使用 fio 评估存储

您可以使用该实用程序评估某个存储是否适合与 etcd 一起使用 FIO — 流行的 I/O 测试仪。 请记住,磁盘 I/O 可以以许多不同的方式发生:同步/异步、许多不同的系统调用类,等等。 硬币的另一面是 fio 极难使用。 该实用程序有很多参数,它们的值的不同组合会导致完全不同的结果。 为了得到对etcd的合理预估,需要保证fio产生的写负载尽可能接近etcd的WAL文件写负载:

  • 这意味着生成的 fio 负载至少应该是对文件的一系列连续写入,其中每次写入都包含一个系统调用 write其次是 fdatasync.
  • 要启用顺序写入,您必须指定标志 --rw=write.
  • fio 使用电话写 write (而不是其他系统调用——例如, pwrite), 使用标志 --ioengine=sync.
  • 最后是国旗 --fdatasync=1 确保每一个 write 应该 fdatasync.
  • 我们示例中的其他两个参数是: --size и --bs - 可能因具体用例而异。 下一节将描述它们的配置。

为什么我们选择 fio 以及我们如何学习如何设置它

这个笔记来自我们遇到的一个真实案例。 我们在 Kubernetes v1.13 上有一个集群,并在 Prometheus 上进行监控。 SSD 被用作 etcd v3.2.24 的存储。 etcd 指标显示延迟太高 fdatasync,即使集群处于空闲状态。 对我们来说,这些指标似乎非常可疑,我们不确定它们到底代表什么。 此外,集群由虚拟机组成,因此无法判断延迟是由于虚拟化还是 SSD 造成的。

此外,我们考虑了硬件和软件配置的各种变化,因此我们需要一种方法来评估它们。 当然,可以在每个配置中运行 etcd 并查看相应的 Prometheus 指标,但这需要大量工作。 我们需要的是一种评估特定配置的简单方法。 我们想测试我们对来自 etcd 的 Prometheus 指标的理解。

这需要解决两个问题:

  • 首先,etcd 在写入 WAL 文件时产生的 I/O 负载是什么样的? 使用了哪些系统调用? 记录块的大小是多少?
  • 其次,假设我们有上述问题的答案。 如何重现相应的负载 fio? 毕竟 fio - 具有丰富参数的极其灵活的实用程序 (这很容易验证,例如, 这里 - 约。 译).

我们使用相同的基于命令的方法解决了这两个问题 lsof и strace:

  • lsof 您可以查看进程使用的所有文件描述符,以及它们引用的文件。
  • strace 您可以分析已经运行的进程或运行进程并观察它。 该命令显示此进程进行的所有系统调用,如有必要,还显示其后代。 后者对于分叉的进程很重要,etcd 就是这样一个进程。

我们做的第一件事是使用 strace 在空闲时检查 Kubernetes 集群中的 etcd 服务器。

于是发现WAL记录块非常密集,大部分大小在2200-2400字节之间。 这就是为什么本文开头的命令使用标志 --bs=2300 (bs 是每个写入块的字节大小 fio).

请注意,etcd 写入块的大小可能因版本、部署、参数值等而异。 - 它影响持续时间 fdatasync. 如果您有类似的用例,请分析 strace 您的 etcd 进程获取最新值。

然后,为了更清晰全面地了解etcd是如何与文件系统一起工作的,我们从下开始 strace 带旗帜 -ffttT. 这使得捕获子进程并将每个子进程的输出写入单独的文件成为可能。 此外,还获取了有关每个系统调用的开始时间和持续时间的详细信息。

我们还使用了命令 lsof确认您对输出的理解 strace 就哪个文件描述符用于哪个目的而言。 我得到了结论 strace,类似于上面的那个。 同步时间的统计操作证实了指标 wal_fsync_duration_seconds 来自 etcd 匹配调用 fdatasync 使用 WAL 文件描述符。

生成与 fio 一个类似于 etcd 的工作负载,研究了该实用程序的文档并选择了适合我们任务的参数。 我们已经验证了正确的系统调用正在进行中,并通过运行确认了它们的持续时间 fio из strace (就像在 etcd 的情况下所做的那样)。

特别注意确定参数的值 --size. 它表示 fio 实用程序生成的总 I/O 负载。 在我们的例子中,这是写入媒体的总字节数。 与调用次数成正比 write (和 fdatasync). 对于特定的 bs 通话次数 fdatasyncsize / bs.

由于我们对百分位数感兴趣,因此我们旨在确保样本数量足够大以达到统计显着性。 并决定 10^4 (对应于 22 MB 的大小)就足够了。 较小的参数值 --size 发出更明显的噪音(例如,电话 fdatasync,这比平时花费的时间长得多,并且会影响第 99 个百分位)。

由你决定

文章展示了如何使用 fio 可以判断用于 etcd 的媒体是否足够快。 现在由你决定! 您可以在服务中探索具有基于 SSD 存储的虚拟机 IBM Cloud.

译者PS

有现成的用例 fio 有关其他任务,请参阅 文件资料 或直接到 项目库 (它们比文档中提到的要多得多)。

来自译者的PPS

另请阅读我们的博客:

来源: habr.com

添加评论