StatsD 的使用小結


原文鏈接 http://blog.gezhiqiang.com/2017/01/25/statsd-summary/######

應用程序的監控是微服務中很重要的一環。監控主要包括四個方面的內容:指標(metrics)的采集、存儲、展示以及相應的報警機制。目前相關的解決方案以及工具非常多。今天就介紹一款用於采集數據的工具——StatsD。
Statsd 最早是 2008 年 Flickr 公司用 Perl 寫的針對 Graphite、datadog 等監控數據后端存儲開發的前端網絡應用,2011 年 Etsy 公司用 node.js 重構。
statsd狹義來講,其實就是一個監聽UDP(默認)或者TCP的守護程序,根據簡單的協議收集statsd客戶端發送來的數據,聚合之后,定時推送給后端,如graphite和influxdb等,再通過grafana等展示。
不過現在通常是指statsd系統。StatsD系統包括三部分:客戶端(client)服務器(server)和后端(backend)。客戶端植入於應用代碼中,將相應的metrics上報給StatsD server。statsd server聚合這些metrics之后,定時發送給backends。backends則負責存儲這些時間序列數據,並通過適當的圖表工具展示。

基本原理與概念

statsd采用簡單的行協議:

<bucket>:<value>|<type>[|@sample_rate] 

bucket

bucket是一個metric的標識,可以看成一個metric的變量。

value

metric的值,通常是數字。

type

metric的類型,通常有timercountergaugeset四種。

sample_rate

如果數據上報量過大,很容易溢滿statsd。所以適當的降低采樣,減少server負載。
這個頻率容易誤解,需要解釋一下。客戶端減少數據上報的頻率,然后在發送的數據中加入采樣頻率,如0.1。statsd server收到上報的數據之后,如cnt=10,得知此數據是采樣的數據,然后flush的時候,按采樣頻率恢復數據來發送給backend,即flush的時候,數據為cnt=10/0.1=100,而不是容易誤解的10*0.1=1。

UDP 和 TCP

statsd可配置相應的server為UDP和TCP。默認為UDP。UDP和TCP各有優劣。但
UDP確實是不錯的方式。

  • UDP不需要建立連接,速度很快,不會影響應用程序的性能。
  • “fire-and-forget”機制,就算statsd server掛了,也不會造成應用程序crash。
    當然,UDP更適合於上報頻率比較高的場景,就算丟幾個包也無所謂,對於一些一天已上報的場景,任何一個丟包都影響很大。另外,對於網絡環境比較差的場景,也更適合用TCP,會有相應的重發,確保數據可靠。

建議使用UDP。TCP還是有許多弊端的。

安裝

statsd的安裝非常簡單。可選擇兩種方式:克隆源碼和docker。

克隆源碼

首先需要安裝node環境。不清楚的可以參考這篇文章。然后到github克隆代碼,修改相關配置啟動即可。

1、 git clone git@github.com:etsy/statsd.git
2、 cd path/to/statsd
3、 根據exampleConfig文件定義自己的配置文件
4、 node stats.js path/to/config

這樣statsd server就搭建成功了。

docker

用docker也是個好選擇。

docker run -p 8125:8125 -p 8126:8126 --name statsd -d dockerana/statsd

statsd 默認監聽8125來收集udp包。
可以通過nc指令測試數據收發。

echo "foo:1|c" | nc -w 1 -u 127.0.0.1 8125

配置

statsd提供默認的配置文件exampleConfig.js。可以參考相應的注釋按需配置,接下來將簡單介紹一些配置項。
端口
默認為8125端口。

port: 8125

后端
默認有console、greaphite等,也有influxdb等backend。console的后端通常加上prettyprint。可以同時配置多個backends。backends都要放在代碼目錄的backends目錄下。

backends: ["./backends/console", "./backends/graphite"], console: { prettyprint: true } 

flush interval
statsd 默認是10s執行一次flush。可通過flushInterval設置,單位ms。

flushInterval: 2000 // 設為2s 

reload 配置
設置automaticConfigReload,watch配置文件,如果修改,即reload配置文件。默認為true。(然而reload配置之后,並沒有生效。)

delete系列配置
metric上報時,每次flush之后,就會重置為0(gauge是保持原有值)。如果不上報這些空閑值,可以通過delete*來設置。

deleteGauges: true,
deleteTimers: true,
deleteSets: true,
deleteCounters: true

percentThreshold
對於timer數據,會計算一個百分比的數據(過濾掉峰值數據),默認是90%。可以通過percentThreshold修改這個值或配置多個值。

//分別計算50%和80%的相關值 percentThreshold: [50, 80] 

只列舉了部分配置項,具體請參考配置文件。

指標 metric

statsd 有四種指標類型:counter、timer、gauge和set。

計數器 counter

counter類型的指標,用來計數。在一個flush區間,把上報的值累加。值可以是正數或者負數。

user.logins:10|c // user.logins + 10 user.logins:-1|c // user.logins - 1 user.logins:10|c|@0.1 // user.logins + 100 // users.logins = 10-1+100=109 

計時器 timer

timers用來記錄一個操作的耗時,單位ms。statsd會記錄平均值(mean)、最大值(upper)、最小值(lower)、累加值(sum)、平方和(sum_squares)、個數(count)以及部分百分值。

rpt:100|g

如下是在一個flush期間,發送了一個rpt的timer值100。以下是記錄的值。

count_80: 1,    
mean_80: 100,
upper_80: 100,
sum_80: 100,    
sum_squares_80: 10000, 
std: 0,     
upper: 100,
lower: 100,
count: 1,
count_ps: 0.1,
sum: 100,
sum_squares: 10000,
mean: 100,
median: 100 
 

 

對於百分數相關的數據需要解釋一下。以90為例。statsd會把一個flush期間上報的數據,去掉10%的峰值,即按大小取cnt*90%(四舍五入)個值來計算百分值。
舉例說明,假如10s內上報以下10個值。

1,3,5,7,13,9,11,2,4,8

則只取10*90%=9個值,則去掉13。百分值即按剩下的9個值來計算。

$KEY.mean_90 // (1+3+5+7+9+2+11+4+8)/9 $KEY.upper_90 // 11 $KEY.lower_90 // 1 

標量 gauge

gauge是任意的一維標量值。gague值不會像其它類型會在flush的時候清零,而是保持原有值。statsd只會將flush區間內最后一個值發到后端。另外,如果數值前加符號,會與前一個值累加。

age:10|g // age 為 10 age:+1|g // age 為 10 + 1 = 11 age:-1|g // age為 11 - 1 = 10 age:5|g // age為5,替代前一個值 

sets

記錄flush期間,不重復的值。

request:1|s // user 1 request:2|s // user1 user2 request:1|s // user1 user2 

statsd 客戶端

statsd的客戶端已經支持多種語言的實現,參看列表。nodejs相關有幾個推薦的:lynx、node-statsd和node-statsd-client,使用都差不多,星也差不多。以(node-statsd-client)[https://github.com/msiebuhr/node-statsd-client]為例:

const SDC = require('statsd-client'),
const sdc = new SDC({ host: 'localhost', port: 8125 });

//counter
sdc.counter('cnt', 10, 0.1); // 100/0.1=1000
sdc.increment('cnt', 10); // +10
sdc.decrement('cnt', 10); // -10

//gauge
sdc.gauge('rpt', 100);
sdc.gaugeDelta('rpt', -10);  // -10

//sets
sdc.set('ips', '1');

//timer
sdc.timing('rpt', 200);

//close
sdc.close()

 

總結

  • 基本原理:statsd是一個udp或tcp的守護進程。使用簡單的行協議收集客戶端的metic數據。statsd使用udp的好處。
  • 安裝及配置
  • metric類型:counter、timer、gauge和sets。
  • statsd的node客戶端。

參考

[1] StatsD Metric
[2] introduction-to-statsd
[3] Counting & Timing
[4] Measure Anything, Measure Everything
[5] 如果查看應用性能圖表是一種信仰
[6] Collecting Metrics Using StatsD, a Standard for Real-Time Monitoring



作者:莫_林
鏈接:https://www.jianshu.com/p/f6f18cc268a4
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM