Graphite的百萬Metrics實踐之路

jopen 9年前發布 | 67K 次閱讀 Graphite

來自:http://calvin1978.blogcn.com/articles/graphite.html

Graphite作為Metrics界的大哥

  • 它是RRDTool的Network Service版,和RRD一樣支持Metrics的精度遞減,比如一天之內10秒一條,7天之內聚合到1分鐘一條,一年之內聚合到1小時一條。
  • 它支持豐富的查詢函數,從簡單的min/max/avg/sum 到 rate、top N等等,以Restful API提供。
  • 它有整個生態圈的插件支持,而且簡單的TCP Plain Text協議,自己來插入數據也很簡單。
  • 它有漂亮的DashBoard -- Grafana
  • 它有完整的HA和Scalable 方案 -- Carbon-Relay
  • 它有數據預聚合方案 -- Carbon-Aggregator
  • </ul>

    上面的一切,都只靠配置文件就能搞定, 不需要編一行代碼。

    但是,等你在服務器、應用的監控之外,真的將海量的業務Metrics也交給它,想不寫一行代碼就賺回一個看起來不錯的報表系統時,問題來了。

    百萬Metrics......

    每個Metrics在硬盤里都是一個文件。metrics的個數,最大估算值是所有維度大小的乘積,維度的增加讓文件的個呈量級的增加。

    寫入的時候,依賴于Graphite自己很自豪的架構:Cluster Sharding分攤每臺服務器上的Metric個數以及Carbon-Cache里的延時聚合批量寫入同一個文件的機制持,對百萬Metrics的支持并不困難。(唯一問題就是如果Carbon-Cache崩了,內存中未寫入的數據會丟失)

    但查詢的時候......如果Dashboard里看的并不是某一個Metrics,而是某些維度下的一個合計,每次查詢可能動不動都要打開上萬個文件,就是件痛苦的事情。

    解決方法之一是使用Carbon-Aggregator,像我們在報表系統里常做的那樣,先做一些維度下的聚合。

    比如,計數器只在每臺Web服務器的內存里累加,metrics nam就是 traffic.server1.userlogin.count,因為我們只關心總用戶登錄數,就將20臺server的數據聚合在一起,形成 traffic.all.userlogin.count再發給carbon-cache,而原來屬于每臺server的記錄則丟棄掉不再往后傳,這樣我們就少了20倍的metrics數量。

    又比如 我們有時候會專門看某個app的使用情況,有時候又想看全部app的情況,則可以既新增一條allApp的聚合數據,也保留每一條app的數據。

    好,鋪墊完了。

    讀取百萬Metrics時的真正問題

    真正的問題1:carbon-aggregator是python寫的基于Twisted的應用,見鬼的GIL問題,居然只能用到單核CPU。有時候單CPU核根本不夠用。在Java里完全沒想過會遇到的問題,別人說多核編程的時候總是很茫然,本來就多核的呀。。。。

    真正的問題2:有些無法預先聚合的場景,比如要從2000個app中找出使用量最大的5個,則必須打開2000個app對應的全部文件。

    真正的讀取問題3: Sharding之后,查詢時需要聚合多臺服務器的結果,比如數據分布在三臺機器上,第一臺機命中了100個metrics,平均值是3;第二臺命中了20個,平均值是2;第三臺命中了10個,平均值是1。
    首先決不能把三個平均值做平均。像MysqlCluster那種會做執行計劃分析的,會只要求每臺機上傳sum 和 count 一共6條數據。但Graphite做不到這一點,只能讓每臺機把命中的metrics即130條數據都傳上來。在0.9.12版中,如何批量上傳數據還是個問題,在始終不肯發布的0.9.13 Snapshot版里此問題總算解決了。
    但計算聚合時,再次遇到Python的單CPU核問題......

    Graphite作者在宣布支持百萬Metrics的時候,好像很少考慮這些問題。
     

    要拋棄Graphite么?

    現在,堅定一下繼續留在Graphite的決心。能掀桌子把Graphite干掉嗎? 一個選型的借鑒是Grafana作者合伙創業開的公司Raintank,它提供一個關于Metrics的SAAS平臺,看the promising KairosDBinfluxdb: first impressions這兩篇博客,也沒太好的能下定決心的選擇。

    1. OpenTSDB
    基于HBase,不支持RRD風格的數據精度遞減,函數有限比如根本就沒有Top N這種功能,運維復雜。

    2. Kairosdb
    基于Cassandra,8個月沒更新了,似乎很不活躍。因為是從OpenTSDB fork出來的,所以不支持RRD與函數有限的問題依然在。

    3. InfluxDB
    用Go語言編寫,是我最看好的一個alternative。但看好它快一年半了,還是沒有成熟。最過份是,0.8版與還沒發布的0.9版之間,居然幾乎是重寫。關于Cluster的文檔也沒寫好讓人不清楚底細。而且依然不支持RRD,只支持數據超過某個時間段就直接刪除。

    所以,近期還是留在Graphite吧,繼續討論優化吧。

    可選的優化方法列表

    兩份有用的參考資料:

    • http://www.iamsysadmin.ninja/2014/12/graphite-scaling-and-my-evaluation-of.html
    • https://wikitech.wikimedia.org/wiki/Graphite/Scaling
    • </ul>

      還有一個增強信心的案例,Booking.com(攜程網的山寨對象),經過改造的Graphite,支持90臺Server,50TB數據的方案。

      1. 使用SSD

      因為要寫入和讀取大量不同的文件,用SSD無疑會快很多。
      但SSD的價格貴,而且Booking.com的視頻里也說。在頻繁讀寫下,一塊SSD盤的壽命也就一年半。

      2. 使用pypy代替python
      看官方數據speed.pypy.org,twisted_tcp中比CPython快3倍,一快解千愁,可緩解很多問題了。

      Python把py文件編譯成字節碼(pyc文件),再交給PVM執行,就像Java的JVM一樣。但PVM沒有JIT,每次都要把字節碼翻譯成機器碼再執行,而JVM可以把解釋后機器碼保存下來。pypy提供了JIT,讓Ruby社區一片羨慕。

      3. 接受現實,減少數據精度

      比如最初的一天之內就不要10秒一條記錄了,降到30秒或一分鐘,大大減少relay,aggregate, 寫入的壓力和文件的大小。

      4. 使用Carbon-Agggrator方案做預聚合

      Aggregator能減少不必要的存儲,預聚合某些維度,見前。

      5. 處理Carbon-Aggrator/Carbon-Relay的單CPU瓶頸

      方法1: 前面提到的pypy應該有幫助。

      方法2: Booking.com用C重寫的,能使用多核的carbon-c-relay ,或者這個用Go重寫的carbon-relay-ng,都是很活躍很值得嘗試的項目。

      方法3: 如果不想有任何改變,那多開幾個carbon-aggregator,每個aggreator只負責少量的規則,甚至sharding出幾個 aggreator來完成同一條規則(如果該規則允許分區的話),aggregator會為每個要在聚合后吐出來的Metrics建立一個任務,用 LoopingCall不斷調用,所以要吐出的Metrics數量進行拆分。部署結構越來越復雜了。。。。用Docker在單機上多啟動幾個 aggregator效果更好。

      6. Sharding

      Sharding能減少每個節點上要讀寫文件的數量,Graphite作者預訂的方案。

      7. 處理Graphite-Web聚合Sharding時的單CPU瓶頸

      暫時無法解決。只能期待前面pypy的提升。

      Booking.com提供全套用go重寫的方案,carbonserver, carbonzipper,carbonapi一起連用,它們都是重新實現了Graphite各部件的功能,但改動好像太大了,暫不推薦。

      8. 最后一招,后臺預查詢預cache數據
      可能有些慢查詢要30秒才出結果,那就預先在后臺查詢一次,cache在Graphite-Web說連接的Memcached里。不過這時就只支持一些固定的時間段,不能支持last 15 minutes這種相對時間了。

      其他優化

      1. 將Whisper存儲換成其他backend方案

      用Cassandra的graphite-cyanite,Vimeo的同學寫的用Influxdb的graphite-influxdb, 但看起來都不成熟也沒多少用戶,不敢試。

      2. 將Graphite-Web換成Graphite-Api

      Graphite-Api與Graphite-Web相比,少了用戶管理,數據庫與PNG渲染,只保留最核心的Query功能,而且有自己的一套plugin架構,比如raintank就寫了個Kairosdb的backend

      小結

      InfluxDB真正超車之前,我們仍將嘗試各種優化,繼續實現我們不寫一行代碼,光靠配置獲得一個不錯的報表系統的愿望。

      </div>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!