文章采集器哪个好用(给出一个基于全部是prometheus的multi_remote_read方案)

优采云 发布时间: 2022-01-28 14:12

  文章采集器哪个好用(给出一个基于全部是prometheus的multi_remote_read方案)

  视频教程的前言今天会写一篇文章文章来分析federation的问题,并给出一个基于所有prometheus的multi_remote_read方案架构图

  

  联邦问题 联邦使用示例

  scrape_configs:

- job_name: 'federate'

scrape_interval: 15s

honor_labels: true

metrics_path: '/federate'

params:

'match[]':

- '{job="prometheus"}'

- '{__name__=~"job:.*"}'

static_configs:

- targets:

- 'source-prometheus-1:9090'

- 'source-prometheus-2:9090'

- 'source-prometheus-3:9090'

  看看上面的示例配置,作为采集的配置感觉如何?

   // web.go 的 federate Handler

router.Get("/federate", readyf(httputil.CompressionHandler{

Handler: http.HandlerFunc(h.federation),

}.ServeHTTP))

  分析下,联邦功能是读取本地存储数据处理。

  

func (h *Handler) federation(w http.ResponseWriter, req *http.Request) {

// localstorage 的query

q, err := h.localStorage.Querier(req.Context(), mint, maxt)

defer q.Close()

// 最终发送的Vector 数组

vec := make(promql.Vector, 0, 8000)

hints := &storage.SelectHints{Start: mint, End: maxt}

var sets []storage.SeriesSet

set := storage.NewMergeSeriesSet(sets, storage.ChainedSeriesMerge)

// 遍历存储中的full series

for set.Next() {

s := set.At()

vec = append(vec, promql.Sample{

Metric: s.Labels(),

Point: promql.Point{T: t, V: v},

})

for _, s := range vec {

nameSeen := false

globalUsed := map[string]struct{}{}

protMetric := &dto.Metric{

Untyped: &dto.Untyped{},

}

// Encode方法根据请求类型编码

if protMetricFam != nil {

if err := enc.Encode(protMetricFam); err != nil {

federationErrors.Inc()

level.Error(h.logger).Log("msg", "federation failed", "err", err)

return

}

}

}

protMetric.TimestampMs = proto.Int64(s.T)

protMetric.Untyped.Value = proto.Float64(s.V)

protMetricFam.Metric = append(protMetricFam.Metric, protMetric)

}

//

if protMetricFam != nil {

if err := enc.Encode(protMetricFam); err != nil {

federationErrors.Inc()

level.Error(h.logger).Log("msg", "federation failed", "err", err)

}

}

}

  最后调用压缩函数进行压缩

  type CompressionHandler struct {

Handler http.Handler

}

// ServeHTTP adds compression to the original http.Handler's ServeHTTP() method.

func (c CompressionHandler) ServeHTTP(writer http.ResponseWriter, req *http.Request) {

compWriter := newCompressedResponseWriter(writer, req)

c.Handler.ServeHTTP(compWriter, req)

compWriter.Close()

}

  如果没有过滤,那么分片的数据只是凑在一起,正确使用联邦的姿势是没有意义的,剩下的数据可以保存在本地采集器这样,pre-可以在每个federation上进行aggregation和alert,提高查询速度默认prometheus不支持下采样。实现统一查询的正确方法是使用prometheus multi_remote_read。remote_read 支持读写的存储是什么,但这和我们今天要讲的问题有什么关系呢?multi_remote_read 如果我们配置多个remote_read接口,即Multi可以实现

  remote_read:

- url: "http://172.20.70.205:9090/api/v1/read"

read_recent: true

- url: "http://172.20.70.215:9090/api/v1/read"

read_recent: true

  上面的配置代表两个后端存储并发查询,查询结果可以mergeprometheus remote_read prometheus可以感觉很多人不知道这个特性,以为remote_read必须配置第三方存储如m3db等,所以可以结合以上两个特点使用多个采集prometheus+多个无状态prometheus查询实现prometheus的高可用方案数据复制,这个方案有什么缺点

  并发查询必须等待最慢的一个返回,所以如果有慢节点,查询速度就会下降,例如

  在处理繁重的查询时,查询可能会挂起

  因为是无差别的并发查询,也就是说所有的查询都会被定向到所有的采集器s,这会导致一些采集器s总是查询这里不存在的数据。

  如果想准确的发送查询到数据及其存储分片,可以参考我之前写的路由方案:开源项目:prome-route:使用反向代理实现prometheus分片

  您可以添加一些逻辑来检测/管理采集器 以改进此解决方案

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线