博客/工程

如何排除远程写问题在普罗米修斯

2021年4月12日7分钟

注意:本文档中的所有链接都指向来自Prometheus v2.26.0的代码。事物的确切位置或名称可能已经改变。

Prometheus的远程写入系统有很多可调旋钮,一旦出现问题,就不清楚该调整哪些旋钮。

在这篇文章中,我们将讨论一些指标,这些指标可以帮助您诊断远程写入问题,并决定您可能想要尝试更改哪些配置参数。

远程写是如何工作的?

首先,让我们讨论远程写是如何实现的。在过去,远程写将复制进入的样本普罗米修斯通过刮。

这是有益的,因为这意味着远程写将接收样本的所有相关信息。然后,它将数据发送到远程存储端点。这里的主要问题是,如果由于任何原因,将样本发送到远程端点时出现问题,我们需要使用固定大小的缓冲区来缓冲来自刮擦的样本。

需要注意的是,我们远程写入的设计目标之一是避免数据丢失,这意味着如果可能的话,我们会尽量确保每个采集并存储在Prometheus中的样本也通过远程写入发送出去。这个固定大小的缓冲区意味着,如果我们试图添加到缓冲区而缓冲区已满,那么我们要么必须删除新的样本,要么必须删除缓冲区中已经存在的旧样本。另一种情况是,可以调整缓冲区的大小以处理更大量的示例,但在许多情况下,当远程写操作首先表现正常时,Prometheus实例正在达到或接近其内存限制。

增加缓冲区大小意味着任何干扰Prometheus发送到远程端点的中断都可能对Prometheus实例进行OOM。在这两种情况下,我们都可能丢失数据。为了减少数据丢失的机会,我们决定对远程写入进行一些设计更改。

我们做的主要改变是远程写入现在读取普罗米修斯的数据。提前写日志而不是直接缓冲从刮取的样本。

通过刮擦生成的数据被写入WAL,因此这本质上为我们提供了2到3个小时的数据缓冲区用于远程写入。RW系统现在有一个子例程《华尔街日报》而且将数据传递回远程写入

远程写仍然在内存中有一个小的缓冲区,如果不能将新数据追加到缓冲区中,那么例程读取WAL的过程就会暂停。这意味着如果缓冲区已满,我们不再丢弃数据,并且缓冲区不需要足够大来处理较长时间的停机。

只要远程端点没有停机数小时,远程写入就不再丢失数据(有一些注意事项,如Prometheus重启),因为WAL大约每两小时被截断一次。

故障排除和度量

远程写指标

可以找到远程写的指标列表在这里而且在这里

下面是一些远程写和远程写相邻的指标以及它们给我们的信息。

  • prometheus_wal_watcher_current_segment显示每个远程写实例当前正在从中读取的当前WAL段文件。这个指标可以与下面的指标进行比较,作为确定远程写是否落后的第一步。
  • prometheus_tsdb_wal_segment_current是普罗米修斯目前正在写入新数据的WAL段文件。
  • prometheus_remote_storage_highest_timestamp_in_seconds本质上显示了任何样本在WAL中存储的最高时间戳(即最新的时间戳)。
  • prometheus_remote_storage_queue_highest_sent_timestamp_seconds显示远程写入成功发送的最高时间戳。
  • prometheus_remote_storage_shards将告诉我们每个远程端点当前有多少碎片正在运行。
  • prometheus_remote_storage_shards_min而且prometheus_remote_storage_shards_max根据您当前的配置向我们展示最小/最大碎片。
  • prometheus_remote_storage_shards_desired将显示基于我们前面谈到的吞吐量和速率,分片计算希望运行多少个分片。
  • prometheus_remote_storage_retried_samples_total如果此指标有稳定的高速率,则可能表明网络或远程存储端点存在问题。这可能意味着我们需要降低远程写的吞吐量,以减少另一端的负载。
  • prometheus_remote_storage_sent_batch_duration_seconds_bucket也能给我们更多关于同样问题的线索。这是发送到远程端点的延迟的直方图。

问题和故障排除

一个常见的问题是,由于配置重新加载或Prometheus重新启动,远程写在发送到远程端点方面可能落后于WAL。

通过观察prometheus_remote_storage_highest_timestamp_in_seconds而且prometheus_remote_storage_queue_highest_sent_timestamp_seconds,您可以了解到对于给定端点,远端写入有多落后。

普罗米修斯混合蛋白包括一个警报它使用最后两个指标来提醒我们远程写入落后。

如果停机时间较长,您可以考虑查看prometheus_wal_watcher_current_segment而且prometheus_tsdb_wal_segment_current.这些值在99%的情况下应该是相同的,但是在Prometheus TSDB长时间中断和压缩的情况下,大约最老的WAL段被考虑删除。

此外,远程写使用分片来增加吞吐量。我们将需要发送的所有样本分布在一组碎片上,并根据最近的吞吐量和样本进入的速率来扩展碎片的数量。

首先,如果远程写入落后,我们应该检查是否已经运行了使用的最大碎片数量prometheus_remote_storage_shards而且prometheus_remote_storage_shards_max

我们还应该关注prometheus_remote_storage_shards_desired看它的值是否大于prometheus_remote_storage_shards_max

如果所需shards大于max shards,您可能需要考虑提高您的shardsmax_shards值。

mixin还包括一个警报对于这个。

配置选项

如果我们想增加或减少吞吐量,我们可以调整以下内容队列配置参数

  • min_shards而且max_shards通常你不会改变min_shards除非你有一个最小的分片数,你知道你的远程写总是要使用的,在这种情况下,增加这个值可以提高Prometheus重启时的恢复时间。更有可能是你想要改变max_shards,通过设置该值的限制来增加或减少最大吞吐量。例如,在远程写入落后且从未赶上的情况下,如果查看所需的shards指标并看到它大于最大shards指标,则可以考虑增加这个值。
  • max_samples_per_send这实际上是每个远程写发送的批大小。增加这个值可以提高相同#的分片和相同#的数据包的吞吐量。如果您怀疑您的网络因许多小型远程写发送而拥塞,请提高这个值。
  • 能力这是每个碎片的缓冲区大小。一般来说,这应该能够处理缓冲一些请求,基于max_samples_per_send.您可以增加这个值来增加每个分片的吞吐量,或者增加这个值,同时减少最大分片,以获得相同的吞吐量,从而减少网络开销。
  • batch_send_deadline这是发送单个分片之间的最大时间间隔。如果我们不缓冲max_samples_per_send在这段时间之前,我们发送缓冲的内容。通常你不会想要改变这个值。但是如果您打开调试日志记录,您将能够看到您的分片是否达到了这个截止日期,这可能表明您的配置允许比您需要的更多的吞吐量,或者如果您看到这些日志行加上远程写不下来分片,则可能存在一个错误。
  • min_backoff而且max_backoff它们用于从分片重试发送单个批次的样例。因为我们尽量不丢失您的数据,重试是无止境的。如果您怀疑重试发生得太频繁并增加了网络负载,您可能需要增加最大回退。

结论

远程写入仍在积极进行中,我们计划进一步改进远程写入和Prometheus所依赖的其他部分,目标是使系统更可靠。如果您遇到bug,有改进建议,或希望自己做出贡献,请联系远程存储维护人员在GitHub或任何官方普罗米修斯上讨论的平台