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 接收,就能够当即被访问。

相关文章
相关标签/搜索