Graphite 系列 #5: Carbon Caches 壓力測試

在本文中,我將對 carbon 進程進行壓力測試。這個涉及到在很是短的時間內發佈大量指標。java

增長每分鐘產生的數量閾值

carbon-cache 配置文件限制了 Whisper 文件每分鐘建立的數量。打開配置文件,並改變配置文件的設置。ios

# vi /opt/graphite/conf/carbon.conf

# Softly limits the number of whisper files that get created each minute.
# Setting this value low (like at 50) is a good way to ensure your graphite
# system will not be adversely impacted when a bunch of new metrics are
# sent to it. The trade off is that it will take much longer for those metrics'
# database files to all get created and thus longer until the data becomes usable.
# Setting this value high (like "inf" for infinity) will cause graphite to create
# the files quickly but at the risk of slowing I/O down considerably for a while.
MAX_CREATES_PER_MINUTE = 50

由於咱們即將發佈一堆指標,讓咱們修改配置文件的這部分,把值設爲 1000。git

MAX_CREATES_PER_MINUTE = 10000

注意:你須要重啓你的 carbon cache 進程使得變動生效。github

Stresser

我有一個 Stresser 應用程序能夠按期地發佈固定量的指標給 carbon-cache。它內部使用 Coda Hale 指標 library,更具體的說,它使用一個 Timer 對象收集數據。web

Stresser 接收幾個參數:緩存

  • Graphite 主機: 在咱們的示例中,服務器位於咱們的 carbon cache 主機上。
  • Graphite 端口: 在咱們的示例中,是 carbon cache 端口
  • 主機數量:爲了模擬發佈
  • 定時器數量:每一個定時器生成 15 個獨立的指標
  • 發佈間隔
  • Debug 模式:true/false - 記錄被髮布的指標

你可使用如下命令運行 Stresser:服務器

java -jar stresser.jar localhost 2003 1 128 10 false

Coda Hale 指標 library 每 timer 生成 15個獨立的指標。app

# ls -l /opt/graphite/storage/whisper/STRESS/host/ip-0/com/graphite/stresser/feg/
total 300
-rw-r--r--. 1 root root 17308 Jun  4 11:22 count.wsp
-rw-r--r--. 1 root root 17308 Jun  4 11:22 m15_rate.wsp
-rw-r--r--. 1 root root 17308 Jun  4 11:22 m1_rate.wsp
-rw-r--r--. 1 root root 17308 Jun  4 11:22 m5_rate.wsp
-rw-r--r--. 1 root root 17308 Jun  4 11:22 max.wsp
-rw-r--r--. 1 root root 17308 Jun  4 11:22 mean_rate.wsp
-rw-r--r--. 1 root root 17308 Jun  4 11:22 mean.wsp
-rw-r--r--. 1 root root 17308 Jun  4 11:22 min.wsp
-rw-r--r--. 1 root root 17308 Jun  4 11:22 p50.wsp
-rw-r--r--. 1 root root 17308 Jun  4 11:22 p75.wsp
-rw-r--r--. 1 root root 17308 Jun  4 11:22 p95.wsp
-rw-r--r--. 1 root root 17308 Jun  4 11:22 p98.wsp
-rw-r--r--. 1 root root 17308 Jun  4 11:22 p999.wsp
-rw-r--r--. 1 root root 17308 Jun  4 11:22 p99.wsp
-rw-r--r--. 1 root root 17308 Jun  4 11:22 stddev.wsp

使用以上命令,指定 128 個定時器,發佈到 carbon-cache 的獨立指標數將是 1920 (128 * 15)。打開 dashboard,做爲咱們前面文章構建的一部分。你將看到被 carbon cache 執行建立操做數量的詳細信息。我在 MAX_CREATES_PER_MINUTE 配置改變以前啓動 Stresser。當它運行的時候,我改變這個配置文件,並重啓 carbon-cache 進程。dashboard 上的建立操做圖形顯示發生了什麼。在配置變動前,少許的建立操做以每分鐘 10 個的速度執行。重啓後,在一分鐘以內,接近 1800 個建立操做發生了,由於閾值被設置成一個更高的值 10,000。webapp

此處輸入圖片的描述

你也能夠經過逐漸設置建立閾值到 10,000 並開啓 Stresser 來測試行爲。你將看到全部的 1920 個指標在同一分鐘被建立。socket

此處輸入圖片的描述

最終,每 10 秒發佈的指標總數量是 1920。Carbon 進程指標每 60s 被存儲一次。所以,被 carbon cache 每分鐘接收到的指標數量將是 11,520 (1920 * 6)。

此處輸入圖片的描述

每分鐘接收 11k 指標

如今咱們有一種方式來發布指標到 carbon cache 並可視化它的行爲,咱們能夠在限制值內發佈它。隨着指標正在被髮布,運行 iostat 命令來測量 I/O 性能,由於 carbon cache 從磁盤中讀寫數據。

我已經配置了 Stresser 來作一下事情:

  • 定時器數量: 128
  • 發佈間隔: 10 秒
  • 每 10 秒發佈的總指標: 1920 (128 * 15)
  • 每分鐘發佈的總指標: 11,520 (1920 * 6)
java -jar stresser.jar localhost 2003 1 128 10 false
Initializing 128 timers - publishing 1920 metrics every 10 seconds from 1 host(s)

此處輸入圖片的描述此處輸入圖片的描述

# iostat -x 10
Linux 2.6.32-431.11.2.el6.x86_64 (ip-10-43-138-169)     06/04/2014  _x86_64_    (4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.50    0.00    0.38    0.35    0.00   98.77

Device:         await  svctm  %util
xvdap1          5.28   0.32   0.26
xvdap1          6.56   0.39   0.16
xvdap1          40.25  0.33   3.62
xvdap1          37.94  0.31   3.13
xvdap1          6.39   0.54   0.44

每分鐘接收 23k 指標

咱們能夠增長經過 Stresser 發佈的指標數量,看它影響的 I/O 性能:

  • 定時器數量: 256
  • 發佈間隔:10 秒
  • 每 10 秒發佈的總指標:3,840 (256 * 15)
  • 每分鐘發佈的總指標: 23,040 (3,840 * 6)
java -jar stresser.jar localhost 2003 1 256 10 false
Initializing 256 timers - publishing 3840 metrics every 10 seconds from 1 host(s)

此處輸入圖片的描述此處輸入圖片的描述

# iostat -x 10
Linux 2.6.32-431.11.2.el6.x86_64 (ip-10-43-138-169)     06/04/2014  _x86_64_    (4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.08    0.00    0.08    0.04    0.00   99.80

Device:         await  svctm  %util
xvdap1          51.48   0.38   6.97
xvdap1          48.06   0.38   6.96
xvdap1          21.10   0.39   1.30
xvdap1          45.21   0.58   1.48
xvdap1          60.48   0.49  13.19

注意到在這個時間點上 CPU activity 不高也是很是重要的。

此處輸入圖片的描述

每分鐘 175K 指標

如今讓咱們大大地增長指標的發佈率來看咱們的設置是否可支撐。我將使用以下 Stresser 配置:

  • 定時器數量: 1956
  • 發佈間隔:10 秒
  • 每 10 秒發佈的總指標:29,340 (1,956 * 15)
  • 每分鐘發佈的總指標: 176,040 (29,340 * 6)
java -jar stresser.jar localhost 2003 1 1956 10 false
Initializing 1956 timers - publishing 29340 metrics every 10 seconds from 1 host(s)

此處輸入圖片的描述
此處輸入圖片的描述

# iostat -x 10
Linux 2.6.32-431.11.2.el6.x86_64 (ip-10-43-138-169)     06/04/2014  _x86_64_    (4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.08    0.00    0.08    0.04    0.00   99.80

Device:         await  svctm  %util
xvdap1          94.20   0.67  40.70
xvdap1          50.60   0.38  11.84
xvdap1          59.21   0.42  23.53
xvdap1          53.77   0.39  25.62
xvdap1          45.52   0.34  12.75

此處輸入圖片的描述

CPU 利用率和內存利用率稍稍增長了。注意 cache sizes 和 cache queues 也開始增加了在指標發率忽然增長後。

此處輸入圖片的描述
此處輸入圖片的描述

每分鐘接收 440K 指標

使用如下 Stresser 配置:

  • 定時器數量: 4887
  • 發佈間隔:10 秒
  • 每 10 秒發佈的總指標:73,305 (4,887 * 15)
  • 每分鐘發佈的總指標: 439,830 (73,305 * 6)
java -jar stresser.jar localhost 2003 1 4887 10 false
Initializing 4887 timers - publishing 73305 metrics every 10 seconds from 1 host(s)

此處輸入圖片的描述
此處輸入圖片的描述

# iostat -x 10
Linux 2.6.32-431.11.2.el6.x86_64 (ip-10-43-138-169)     06/04/2014  _x86_64_    (4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.08    0.00    0.08    0.04    0.00   99.80

Device:         await  svctm  %util
xvdap1          98.76   0.74  44.29
xvdap1          83.43   0.62  22.61
xvdap1          82.47   0.62  33.51
xvdap1          123.14  0.88  52.00
xvdap1          106.97  0.75  45.58

此處輸入圖片的描述

對比前面的測試,內存消費從 500MB 增長到 900 MB,CPU activity 略有增長。若是你凝視 htop 的輸出,你將每 10秒看到一個核心尖峯(指標發佈頻率)。

每分鐘 700K 指標

使用如下 Stresser 配置:

  • 定時器數量: 7824
  • 發佈間隔:10 秒
  • 每 10 秒發佈的總指標:117,360 (7,824 * 15)
  • 每分鐘發佈的總指標: 704,160 (117,360 * 6)
java -jar stresser.jar localhost 2003 1 7824 10 false
Initializing 7824 timers - publishing 117360 metrics every 10 seconds from 1 host(s)

此處輸入圖片的描述
此處輸入圖片的描述

# iostat -x 10
Linux 2.6.32-431.11.2.el6.x86_64 (ip-10-43-138-169)     06/05/2014  _x86_64_    (4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.93    0.00    5.53    6.40    0.49   74.65

Device:         await  svctm  %util
xvdap1          241.67 1.73   58.34
xvdap1          263.33 1.83   100.00
xvdap1          256.01 1.88   54.32
xvdap1          228.32 1.63   100.00
xvdap1          474.27 3.20   100.00

此處輸入圖片的描述

對 carbon cache 來講它花了 30 分鐘來建立全部的新指標。對比前面的測試,這使用了更多的內存和 CPU 利用率。儘管如此,I/O 性能有更大的影響,由於 await 列報告值更大,在多個點百分利用率用顯示 100%。cache queues 是很是高的可是仍然穩定, cache size 增長直到全部的指標被建立完成。而後直線圍繞 1.5M 左右。

此處輸入圖片的描述
此處輸入圖片的描述

CARBON 作了什麼?

Carbon 使用了一個動態 buffering 儘量多的數據點的策略,由於須要維持輸入數據點的速率,可能超過你的存儲能跟上的 I/O 操做速率。在咱們每分鐘發佈 11K 和 700K 指標到 Carbon cache 的以上場景中。在一個更簡單的場景,好比說咱們的 Stresser 應用程序被以如下方式方式:

  • 每分鐘發佈的總指標:60,000 獨立指標

讓咱們假設每 60,000 個不一樣的指標每分鐘有單個數據點。由於一個指標在文件系統上是以一個 Whisper 文件呈現的,Carbon 將須要每分鐘執行 60,000 次寫操做 - 每一個 Whisper 文件一個。爲了處理指標發佈率,Carbon 須要不到一毫米的時間寫一個文件。在今天,這不是問題。

儘管如此,若是指標發佈速率增長到一個很高的水平 - 像在咱們的場景每分鐘發佈 700K 個指標 - 輸入數據點的速率超過了能夠被寫入磁盤的速率。若是在 Graphite 服務器的磁盤不是 SSDs 或者有一個很低的速度時可能發生。

尋址時間

成千上萬個 Whisper 文件被使用 ~12 或者每個字節的數據頻繁寫入。磁盤明顯會花費更多時間用於尋址。

寫多個數據點

讓咱們假設磁盤的寫速率不是太大,而且它沒有大大增長,甚至若是咱們買了更快的 SSDs。使得寫更快的惟一方式就是少作,而且咱們能作的更少若是咱們 buffer 多個相關的數據點而且使用單個寫操做把他們寫入正確的 Whisper 文件。 Whisper 整理連貫的數據點連續寫入磁盤。

update_many 函數

Chris Davis 決定修改 Whisper 和增長 update_many 函數。它須要一個列表的數據點做爲單個指標並壓縮相鄰數據點到一個寫操做。即便這使得寫操做很大,它寫 10個數據點 (~120 bytes) 相對於寫一個數據點 (~12 bytes)花費的時間差別是可忽略的。在每一個寫的大小開始明顯影響延遲這將須要至關多的數據點。

Buffers

爲了在 Whisper 中使用 update_many 函數,在 Carbon 中實現了一個緩存機制。每一個進入的數據點基於它的指標名字被映射到一個隊列而後添加進隊列 - 經過 Receiver 線程。另一個線程 - Writer 線程 - 重複迭代全部的隊列,對於每個,它拉取出全部的數據點並使用 update_many 寫入合適的 Whisper 文件。若是數據點進入速率超過了寫速率,隊列將最終持有更多的數據點。惟一花費的服務器資源是內存,這是可接受的,由於每一個數據點只有幾字節。

額外的福利:彈性

這種方法的優點是必定程度上的彈性來處理臨時的 I/O 減速。若是系統須要作其餘與 Graphite 無關的 I/O 操做,這時寫速率可能減少。若是這個發生了,Carbon 隊列將緩慢增加。隊列越大,寫越大。由於數據點的總體吞吐量等於寫操做花費的每一個寫操做的平均大小比率。只要 queues 有足夠內存 Carbon 能夠持續保持。

實時圖表

若是 Carbon 維護的在內存中的數據點隊列等待被寫回磁盤,這意味着這些數據點將不會顯示在你的 graphite-webapp 圖表上,對嗎?錯了!

一個 socket 監聽器被添加到 Carbon,爲訪問緩存數據提供了一個查詢接口。graphite-webapp 在它每次須要檢索數據的時候使用這個查詢接口。graphite-webapp 這時能夠組合這些它從 Carbon 和 從在磁盤上 Whisper 文件檢索的數據點。所以你的 graphite-webapp 圖表將是實時的。一旦數據點被 Carbon 接收,就能夠當即被訪問。

相關文章
相關標籤/搜索