Prometheus Remote Write 的性能

微信扫一扫,分享到朋友圈

Prometheus Remote Write 的性能

我们一般怎么去看待 Prometheus
呢?我个人会偏向于 Prometheus
是一套完整的 监控体系 的解决方案。 Prometheus
的社区中的监控的生态有很多,甚至于 我们目前的开源的框架等都会适配 Prometheus
exporter
, 也正是 很多的 exporter 完美的解决了 Prometheus
监控体系的大而广。但是,如果 Prometheus
仅仅依赖于我们的本地的文件系统,对于自身的 稳定性而言显然是不合理的,这是因为:

如果说数据不存在过期的情况,那么最先到达瓶颈的一定是 内存 。因为 Prometheus
会把 time series
先搁置到 内存里面,在做相应的 刷写操作,所以呢,如果说你的 query
里面的 series
比较多,那就完犊子了,不就 OOM 了吗。

因此 Prometheus
才有了 remote stoage
一说。我们目前使用的 remote storage
Cortex
, 使用 Cortex 的原因其实就一个: 可以分租户。当然,Cortex 还有其他的好处,比如说,集群模式,比如说,底层可以使用多种存储形式—— Cassandra
(我们目前使用的)。

remote_write

这里呢,我们使用远程写,依然会存在 瓶颈,但是这个瓶颈是在 remote_write 的过程中发生的,我们看下。

这里呢,我们先看 Prometheus 官方文档里面的定义:

url: <string>
[ remote_timeout: <duration> | default = 30s ]
write_relabel_configs:
[ - <relabel_config> ... ]
# Name of the remote write config, which if specified must be unique among remote write configs.
# The name will be used in metrics and logging in place of a generated value to help users distinguish between
# remote write configs.
[ name: <string> ]
basic_auth:
[ username: <string> ]
[ password: <secret> ]
[ password_file: <string> ]
[ bearer_token: <string> ]
[ bearer_token_file: <filename> ]
tls_config:
[ <tls_config> ]
[ proxy_url: <string> ]
queue_config:
# Number of samples to buffer per shard before we block reading of more
# samples from the WAL. It is recommended to have enough capacity in each
# shard to buffer several requests to keep throughput up while processing
# occasional slow remote requests.
[ capacity: <int> | default = 500 ]
# Maximum number of shards, i.e. amount of concurrency.
[ max_shards: <int> | default = 1000 ]
# Minimum number of shards, i.e. amount of concurrency.
[ min_shards: <int> | default = 1 ]
# Maximum number of samples per send.
[ max_samples_per_send: <int> | default = 100]
# Maximum time a sample will wait in buffer.
[ batch_send_deadline: <duration> | default = 5s ]
# Initial retry delay. Gets doubled for every retry.
[ min_backoff: <duration> | default = 30ms ]
# Maximum retry delay.
[ max_backoff: <duration> | default = 100ms ]

对于 capacity
,谷歌的解释是这个:

在阻止从 WAL 读取更多样本之前,每个分片要缓冲的样本数。 建议在每个分片中都具有足够的容量以缓冲多个请求,以在处理偶发性较慢的远程请求时保持吞吐量。

配置就这么多,大家也看的明白,我们再看看源码:

// RemoteWriteConfig is the configuration for writing to remote storage.
type RemoteWriteConfig struct {
URL                 *config_util.URL  `yaml:"url"`
RemoteTimeout       model.Duration    `yaml:"remote_timeout,omitempty"`
WriteRelabelConfigs []*relabel.Config `yaml:"write_relabel_configs,omitempty"`
Name                string            `yaml:"name,omitempty"`
// We cannot do proper Go type embedding below as the parser will then parse
// values arbitrarily into the overflow maps of further-down types.
HTTPClientConfig config_util.HTTPClientConfig `yaml:",inline"`
QueueConfig      QueueConfig                  `yaml:"queue_config,omitempty"`
}

HTTPClientConfig

type HTTPClientConfig struct {
// The HTTP basic authentication credentials for the targets.
BasicAuth *BasicAuth `yaml:"basic_auth,omitempty"`
// The bearer token for the targets.
BearerToken Secret `yaml:"bearer_token,omitempty"`
// The bearer token file for the targets.
BearerTokenFile string `yaml:"bearer_token_file,omitempty"`
// HTTP proxy server to use to connect to the targets.
ProxyURL URL `yaml:"proxy_url,omitempty"`
// TLSConfig to use to connect to the targets.
TLSConfig TLSConfig `yaml:"tls_config,omitempty"`
}

QueueConfig

// QueueConfig is the configuration for the queue used to write to remote
// storage.
type QueueConfig struct {
// Number of samples to buffer per shard before we block. Defaults to
// MaxSamplesPerSend.
Capacity int `yaml:"capacity,omitempty"`
// Max number of shards, i.e. amount of concurrency.
MaxShards int `yaml:"max_shards,omitempty"`
// Min number of shards, i.e. amount of concurrency.
MinShards int `yaml:"min_shards,omitempty"`
// Maximum number of samples per send.
MaxSamplesPerSend int `yaml:"max_samples_per_send,omitempty"`
// Maximum time sample will wait in buffer.
BatchSendDeadline model.Duration `yaml:"batch_send_deadline,omitempty"`
// On recoverable errors, backoff exponentially.
MinBackoff model.Duration `yaml:"min_backoff,omitempty"`
MaxBackoff model.Duration `yaml:"max_backoff,omitempty"`
}

这里关于 QueueConfig
咋一看,没感觉出啥,我们现在来看看 这个 QueueConfig
里面的默认的配置:

// DefaultQueueConfig is the default remote queue configuration.
DefaultQueueConfig = QueueConfig{
// With a maximum of 1000 shards, assuming an average of 100ms remote write
// time and 100 samples per batch, we will be able to push 1M samples/s.
MaxShards:         1000,
MinShards:         1,
MaxSamplesPerSend: 100,
// Each shard will have a max of 500 samples pending in it's channel, plus the pending
// samples that have been enqueued. Theoretically we should only ever have about 600 samples
// per shard pending. At 1000 shards that's 600k.
Capacity:          500,
BatchSendDeadline: model.Duration(5 * time.Second),
// Backoff times for retrying a batch of samples on recoverable errors.
MinBackoff: model.Duration(30 * time.Millisecond),
MaxBackoff: model.Duration(100 * time.Millisecond),
}

这里,我们看到 capacity
的配置说明:

每个分片在其通道中最多有500个待处理的样本,加上已入队的待处理样本。 从理论上讲,每个分片待处理的样本数应该只有600个左右。 以1000个分片计为600k。

可以看到 Prometheus
默认定义了 1000 个 queue
batch size
为 100,预期可以达到 1M samples/s
的发送速率。 Prometheus
输出了一些 queue
相关的指标,例如 failed_samples_total
, dropped_samples_total
,如果这两个指标的 rate
大于 0,就需要说明 Remote Storage
出现了问题导致发送失败,或者 队列满了导致 samples 被丢弃掉
。 这里的问题就需要 我们的 Remote Storage
进行联合的排查。如果是 Remote Storage
出现了问题,那么 Remote Storage
的数据获取上显然是不对的,这就需要有一个监控去监控到这里的数据变化。比如说,笔者这里的 Cortex
, 监控到的 Cortex-Distributor
的数据上,租户的数据很平稳,没有出现大的波动,这时候就要考虑下 是不是 Prometheus
本身的 瓶颈 了。

这样看来,我们就很好理解了为了我们的 Prometheus
在数据量大的情况下,出现很多的 failed_samples_total
的原因了,这里就是我们的 Prometheus 的一个远程写的 性能问题,这个问题的解决思路有两个:

  • 扩大 capacity
    : 保证 我们的队列处于 可用状态,这样就要求内存足够大
  • 做分片: 简单的理解就是 并发 操作
  • Prometheus
    机器,用 不同的 Prometheus
    采集不同的指标,这样,原来一个 Prometheus
    采集的指标分摊到了多个 Prometheus
    上,问题也会得到很好的解决。

分片的操作,其实还是比较麻烦的,这个等我国庆在看看。

微信扫一扫,分享到朋友圈

Prometheus Remote Write 的性能

Counterpoint:2020年第二季度全球智能手机出货量暴跌23%

上一篇

甬优2640作菜后早稻栽培的特征特性及高产栽培技术

下一篇

你也可能喜欢

Prometheus Remote Write 的性能

长按储存图像,分享给朋友