<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
最近有做一個Prometheus metrics代理的一個小專案,暫稱為prom-proxy
,目的是為了解析特定的指標(如容器、traefik、istio等指標),然後在原始指標中加入應用ID(當然還有其他指標操作,暫且不表)。經過簡單的本地驗證,就釋出到聯調環境,跑了幾個禮拜一切正常,以為相安無事。但自以為沒事不代表真的沒事。
昨天突然老環境和新上prom-proxy
的環境都出現了資料丟失的情況,如下圖:
prom-proxy
有一個自服務指標request_total
,經觀察發現,該指標增長極慢,因而一開始懷疑是傳送端的問題(這是一個誤區,後面會講為何要增加快取功能)。
進一步排查,發現上游傳送端(使用的是victoriaMetrics的vmagent元件)出現瞭如下錯誤,說明是prom-proxy
消費的資料跟不上vmagent產生的資料:
2022-03-24T09:55:49.945Z warn VictoriaMetrics/app/vmagent/remotewrite/client.go:277 couldn't send a block with size 370113 bytes to "1:secret-url": Post "xxxx": context deadline exceeded (Client.Timeout exceeded while awaiting headers); re-sending the block in 16.000 seconds
出現這種問題,首先想到的是增加並行處理功能。當前的並行處理數為8(即後臺的goroutine數目),考慮到線上宿主機的core有30+,因此直接將並行處理數拉到30。經驗證發現毫無改善。
另外想到的一種方式是快取,如使用kafka或使用golang自帶的快取chan。但使用快取也有問題,如果下游消費能力一直跟不上,快取中將會產生大量積壓的資料,且Prometheus監控指標具有時效性,積壓過久的資料,可用性並不高又浪費儲存空間。
下面是使用了快取chan的例子,s.reqChan
的初始大小設定為5000,並使用cacheTotal
指標觀察快取的變更。這種方式下,資料接收和處理變為了非同步(但並不完全非同步)。
上面一開始有講到使用request_total
檢視上游的請求是個誤區,是因為請求統計和請求處理是同步的,因此如果請求沒有處理完,就無法接收下一個請求,request_total
也就無法增加。
func (s *Server) injectLabels(w http.ResponseWriter, r *http.Request) { data, _ := DecodeWriteRequest(r.Body) s.reqChan <- data cacheTotal.Inc() w.WriteHeader(http.StatusNoContent) } func (s *Server) Start() { go func() { for data := range s.reqChan { cacheTotal.Dec() processor := s.pool.GetWorkRequest() go func() { processor.JobChan <- data res := <-processor.RetChan if 0 != len(res.errStr) { log.Errorf("err msg:%s,err.code:%d", res.errStr, res.statusCode) return } }() } }() }
上線後觀察發現cacheTotal
的統計增加很快,說明之前就是因為處理能力不足導致request_total
統計慢。
至此似乎陷入了一個死衚衕。多goroutine和快取都是不可取的。
回顧一下,prom-proxy
中處理了cadvisor、kube-state-metrics、istio和traefik的指標,同時在處理的時候做了自監控,統計了各個型別的指標。例如:
prom-proxy_metrics_total{kind="container"} 1.0396728e+07 prom-proxy_metrics_total{kind="istio"} 620414 prom-proxy_metrics_total{kind="total"} 2.6840415e+07
在cacheTotal
迅猛增加的同時,發現request_total
增長極慢(表示已處理的請求),且istio
型別的指標處理速率很慢,,而container
型別的指標處理速度則非常快。這是一個疑點。
vmagent的一個請求中可能包含上千個指標,可能會混合各類指標,如容器指標、閘道器指標、中介軟體指標等等。
通過排查istio
指標處理的相關程式碼,發現有三處可以優化:
經過上述優化,上線後發現快取為0,效能達標!
一開始在開發完prom-proxy
之後也做了簡單的benchmark測試,但考慮到是在辦公網驗證的,網速本來就慢,因此註釋掉了寫入指標的程式碼,初步驗證效能還算可以就結束了,沒想到埋了一個深坑。
所以所有功能都需要覆蓋驗證,未驗證的功能點都有可能是坑!
喜聞樂見的後續來了。。。
由於公司有兩個大的線上叢集,暫稱為more叢集和less叢集,很不幸,效能達標的就是less叢集的,其指標資料相比more叢集來說非常less,大概是前者的十分之一。上到more叢集之後服務記憶體直接達到50G,多個副本一起吃記憶體,直接將節點搞掛了。
迫不得已(又是那句話,感覺對了的點往往不對),重新做了pprof壓力測試,發現記憶體黑洞就是下面這個函數(來自Prometheus),即便在辦公電腦下進行壓測,其記憶體使用仍然達到好幾百M。該函數主要是讀取vmagent傳來的請求,首先進行snappy.Decode
解碼,然後unmarshal
到臨時變數wr
中。低流量下完全沒有問題,但高流量下完全無法應對:
func DecodeWriteRequest(r io.Reader) (*ReqData, error) { compressed, err := ioutil.ReadAll(r) if err != nil { return nil, err } reqBuf, err := snappy.Decode(nil, compressed) if err != nil { return nil, err } var wr prompb.WriteRequest if err := proto.Unmarshal(reqBuf, &wr); err != nil { return nil, err } return &ReqData{ reqBuf: reqBuf, wr: &wr, }, nil }
解決辦法就是拿出sync.pool
大殺器,下面方式參考了victoriaMetrics的byteutil庫(程式碼路徑lib/byteutil
),有興趣的可以去看下,經過壓測,相同測試情況下記憶體降到了不足100M。
func DecodeWriteRequest(r io.Reader, callback func(*prompb.WriteRequest)) error { ctx := getPushCtx(r) defer putPushCtx(ctx) if err := ctx.Read(); err != nil { return err } bb := bodyBufferPool.Get() defer bodyBufferPool.Put(bb) var err error bb.B, err = snappy.Decode(bb.B[:cap(bb.B)], ctx.reqBuf.B) if err != nil { return err } wr := getWriteRequest() defer putWriteRequest(wr) if err := wr.Unmarshal(bb.B); err != nil { return err } callback(wr) return nil }
這樣一來效能完全達標,10core下單pod每秒可以處理250w個指標!
重新發佈線上,自然又出問題了,這次prom-proxy
服務一切正常,但導致後端vmstorage(victoriametrics的儲存服務)記憶體爆滿。經過初步定位,是由於出現了slow insert,即出現大量 active time series導致快取miss,進而導致記憶體暴增(prom-proxy
服務會在原始指標中增加標籤,並建立其他新的指標,這兩類指標數目非常龐大,都屬於active time series
)。
最終的解決方式是將修改的指標作分類,並支援設定化啟用,即如果修改的指標型別有:A、B、C、D四類。首先上線A,然後上線B,以此類推,讓vmstorage逐步處理active time series
,以此減少對後端儲存的瞬時壓力。
vmstorage有一個引數:--storage.maxDailySeries
,它可以限制active time series
的數目。但環境中正常情況下就有大量active time serials
,如果設定了這個引數,新增的active time serials
極有可能會擠掉老的active time serials
,造成老資料丟失。
以上就是victoriaMetrics代理效能優化問題解析的詳細內容,更多關於victoriaMetrics代理效能優化的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45