存储速度适合etcd吗? 询问


关于fio和etcd的简短故事


etcd群集的性能在很大程度上取决于其存储的性能。 etcd将一些度量标准导出到Prometheus,以提供有关存储性能的必要信息。 例如,度量标准wal_fsync_duration_seconds。 etcd的文档说 :为了使存储足够快,该指标的第99个百分位数应小于10毫秒。 如果计划在Linux机器上运行etcd集群,并希望评估存储是否足够快(例如SSD),则可以使用fio (一种流行的工具来测试I / O操作)。 运行以下命令,其中test-data是存储装入点下方的目录:


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

您只需要查看结果并验证fdatasync持续时间的第99个百分位数小于10 ms。 如果是这样,您将拥有一个相当快的存储空间。 这是结果的示例:


  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] 

注意事项


  • 我们已经为特定方案配置了--size和--bs选项。 要从Fio获得有用的结果,请输入值。 在哪里买? 阅读我们如何学习如何配置fio
  • 在测试期间,整个I / O负载都来自fio。 在实际情况下,除了与wal_fsync_duration_seconds相关的请求外,其他写入请求也可能会到达存储库。 额外的负载将增加wal_fsync_duration_seconds的值。 因此,如果第99个百分位数几乎达到10毫秒,则您的存储将没有足够的速度。
  • 使用不低于3.5的fio版本 (以前的版本不显示fdatasync持续时间的百分位数)。
  • 以上只是来自fio结果的一小段。

关于fio和etcd的长篇故事


什么是etcd中的WAL


数据库通常使用预写日志 ; etcd也使用它。 在这里,我们将不详细讨论预写日志(WAL)日志。 我们只需要知道etcd集群的每个成员都将其维护在持久性存储中即可。 etcd将每个键值对操作(例如,更新)写入WAL,然后再将其应用于存储库。 如果在快照之间有一个存储成员崩溃并重新启动,则它可以使用WAL内容从上一个快照本地恢复事务。


当客户端将键添加到键值对的存储中或更新现有键的值时,etcd在WAL中记录此操作,WAL是持久性存储中的常规文件。 在继续之前,etcd必须完全确定写入WAL确实发生了。 在Linux上,单次写入系统调用不足以满足此要求,因为实际写入物理存储可能会延迟。 例如,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, ".\0\0\0\0\0\0\202\10\2\20\361\223\255\266\6\32$\10\0\20\10\30\26\"\34\"\r\n\3fo"..., 2296) = 2296 <0.000130> 21:23:09.895041 fdatasync(8) = 0 <0.008314> 

不幸的是,写入持久性存储不会立即进行。 如果fdatasync调用很慢,则etcd系统性能会下降。 etcd的文档说 ,如果在fdatasync调用的第99个百分位数中花费不到10毫秒写入WAL文件,则该存储库被认为足够快。 还有其他一些有用的存储指标,但是在本文中,我们仅讨论该指标。


用Fio评估存储


如果需要评估存储库是否适合etcd,请使用fio,这是一种非常流行的I / O负载测试工具。 应当记住,磁盘操作可能非常不同:同步和异步,许多类的系统调用等。因此,fio很难使用。 它具有许多参数,其值的不同组合会产生完全不同的I / O工作负载。 为了获得足够的etcd编号,在写入WAL文件时,应确保来自fio的测试记录加载尽可能接近来自etcd的实际加载。


因此,fio至少应以对文件的一系列顺序写操作的形式创建负载,每个记录将由一个系统调用和一个fdatasync系统调用组成。 对于顺序写操作,fio需要--rw = write选项。 为了使fio在记录时使用写系统调用而不是pwrite ,值得指定--ioengine = sync参数。 最后,对于要在每个条目之后调用fdatasync的情况,您需要添加--fdatasync = 1参数。 此示例中的其他两个选项(--size和--bs)是特定于方案的。 在下一节中,我们将向您展示如何配置它们。


为什么选择Fio,以及我们如何学习如何配置它


在这篇文章中,我们描述了真实的情况。 我们有一个Kubernetes v1.13集群,我们使用Prometheus对其进行了监视。 etcd v3.2.24托管在SSD上。 Etcd指标显示fdatasync的延迟过高,即使群集未执行任何操作。 这些指标很奇怪,我们真的不知道它们的含义。 群集由虚拟机组成,您必须了解问题所在:物理SSD或虚拟化层。 此外,我们经常更改硬件和软件配置,并且需要一种评估其结果的方法。 我们可以在每种配置中运行etcd并查看Prometheus指标,但这太麻烦了。 我们正在寻找一种评估特定配置的相当简单的方法。 我们想检查我们是否正确地从etcd理解了Prometheus指标。


但是为此,有必要解决两个问题。 首先,当写入WAL时,etcd创建的I / O负载是什么样的? 使用什么系统调用? 记录的大小是多少? 其次,如果我们回答这些问题,我该如何用fio重现类似的工作量? 不要忘记fio是一个非常灵活的工具,具有很多选项。 我们用一种方法解决了两个问题-使用lsofstrace命令。 lsof显示该进程及其关联文件使用的所有文件描述符。 使用strace,您可以研究已经运行的进程或启动一个进程并对其进行研究。 strace显示正在研究的进程(及其子进程)的所有系统调用。 后者非常重要,因为etcd只是采用类似的方法。


首先,当集群上没有负载时,我们使用strace来学习Kubernetes的etcd服务器。 我们看到几乎所有WAL记录的大小都差不多:2200-2400字节。 因此,在文章开头的命令中,我们指定了参数--bs = 2300(bs表示每个fio条目的字节大小)。 请注意,etcd条目的大小取决于etcd的版本,传递,参数值等,并影响fdatasync的持续时间。 如果您有类似情况,请使用strace检查etcd进程以找出确切的数字。


然后,为了更好地了解etcd文件系统中的操作,我们从strace和-ffttT选项开始。 因此,我们尝试研究子进程,并将每个子进程的输出写入单独的文件中,并获得有关每个系统调用的开始和持续时间的详细报告。 我们使用lsof来确认对strace输出的分析,并查看哪个文件描述符用于什么目的。 因此,使用strace我们得到了上面显示的结果。 同步时间的统计数据确认,etcd中的wal_fsync_duration_seconds指示器对应于具有WAL文件描述符的fdatasync调用。


我们研究了fio文档,并为脚本选择了选项,以便fio会生成类似于etcd的负载。 我们还通过从strace运行fio来检查系统调用及其持续时间,类似于etcd。


我们仔细选择了--size参数的值,该值代表来自fio的整个I / O负载。 在我们的例子中,这是写入存储器的总字节数。 事实证明,它与写入(和fdatasync)系统调用的数量成正比。 对于特定的bs值,对fdatasync的调用次数= size / bs。 由于我们对百分位数感兴趣,因此我们应该有足够的样本来确保可靠性,并且我们计算出10 ^ 4对我们来说就足够了(我们得到22兆字节)。 如果--size较小,则可能会出现异常值(例如,多个fdatasync调用的工作时间比平时更长,并影响第99个百分位数)。


自己尝试


我们展示了如何使用fio并找出存储是否具有足够的速度来实现高性能etcd。 现在,您可以使用IBM Cloud中带有SSD存储的虚拟机自己尝试进行实践。

Source: https://habr.com/ru/post/zh-CN450892/


All Articles