为什么使用石墨碳聚合器可以做同样的工作statsd?

我一直在探索用于显示来自多个服务器的指标的Graphite绘图工具,并且似乎“推荐”的方式是首先将所有指标数据发送到StatsD。 StatsD汇总数据并将其发送到石墨(或碳)。

在我的情况下,我想要在服务器上进行简单的聚合,比如总和和平均值,并绘制石墨图。 石墨带有碳聚合器,可以做到这一点。

StatsD甚至不提供我正在谈论的那种聚合。

我的问题是 – 我应该使用statsd作为我的用例吗? 我在这里错过的任何东西?

  1. StatsD通过UDP进行操作,从而消除了carbon-aggregator.py在应用程序中响应速度慢和延迟的风险。 换句话说,松耦合。

  2. StatsD支持入站度量标准的采样,当您不希望您的聚合器采用所有数据点的100%来计算描述性统计信息时,这非常有用。 对于大批量代码段,通常使用0.5%-1%的采样率,以免超载StatsD。

  3. StatsD拥有广泛的客户端支持。

tldr:如果你想查看服务器特定的总和或平均值,你可能需要statsd(或者carbon-c-relay )。

碳聚合器被devise为将来自多个度量的值聚合成单个输出度量,通常用于增加graphics渲染性能。 statsd被devise为在一个度量中聚合多个数据点 ,否则石墨只会存储以最小存储分辨率报告的最后一个值。

statsd示例:假定您的graphite storage-schemas.conf文件的最小保留时间为10秒(默认值),并且您的应用程序每10秒向services.login.server1.count发送约100个数据点,值为1。没有统计,石墨将只存储在每个10秒桶收到的最后一个计数。 在接收到第100条消息之后,其他99个数据点将被抛出。 然而,如果您将应用程序和石墨之间进行了统计,那么在将总数发送到石墨之前,它会将所有100个数据点相加在一起。 所以,如果没有statsd,你的图只会显示在10秒间隔内是否发生login。 与statsd,它表示在该间隔期间发生了多less次login。 ( 例如 )

碳聚合器示例:假设您有200个不同的服务器报告200个单独的指标( services.login.server1.response.timeservices.login.server2.response.time等)。 在您的操作仪表板上,您将显示使用以下石墨查询的所有服务器的平均值的graphics:weightedAverage(services.login.server * .response.time,services.login.server * .response.count,2)。 不幸的是,渲染这个图需要10秒。 要解决这个问题,您可以添加一个碳聚合器规则来预先计算所有服务器的平均值,并将该值存储在新的度量标准中。 现在您可以更新仪表板来简单地提取一个指标(例如services.login.response.time )。 新的指标几乎立即呈现。

旁注:

  1. storage-aggregation.conf中的聚合规则将应用于storage-schemas.conf中的所有存储时间间隔, 每个保留string的第一个(最小)保留时间段除外 。 有可能使用碳聚合器来聚合在第一保留时间段内的度量内的数据点。 不幸的是,aggregation-rules.conf使用“blob”模式,而不是正则expression式模式。 所以您需要为每个path深度和聚合types添加一个单独的aggregation-rules.conf文件条目。 statsd的优势在于,发送度量标准的客户端可以指定聚合types,而不是在度量标准path中对其进行编码。 这使您可以灵活地随时添加新的度量标准,而不受公制path深度的影响。 如果您希望configuration碳聚合器在添加新度量标准时自动执行类似statsd的聚合,那么您的aggregation-rules.conf文件将如下所示:

    <n1>.avg (10)= avg <n1>.avg$ <n1>.count (10)= sum <n1>.count$ <n1>.<n2>.avg (10)= avg <n1>.<n2>.avg$ <n1>.<n2>.count (10)= sum <n1>.<n2>.count$ <n1>.<n2>.<n3>.avg (10)= avg <n1>.<n2>.<n3>.avg$ <n1>.<n2>.<n3>.count (10)= sum <n1>.<n2>.<n3>.count$ ... <n1>.<n2>.<n3> ... <n99>.count (10)= sum <n1>.<n2>.<n3> ... <n99>.count$ 

    注:在石墨0.10+(目前预发布)中不需要尾随的“$”,这里是github上的相关补丁 ,这里是关于聚合规则的标准文档

  2. 加权平均函数在石墨0.10中是新的,但通常情况下,只要平均负载均衡,averageSeries函数就会给出非常相似的数字。 如果你有一些服务器速度较慢,服务较less,或者你只是一个精度较高的服务器,那么你仍然可以用石墨0.9来计算一个加权平均值。 你只需要build立一个更复杂的查询,像这样:

     divideSeries(sumSeries(multiplySeries(a.time,a.count), multiplySeries(b.time,b.count)),sumSeries(a.count, b.count)) 
  3. 如果statsd运行在客户端,这也减less了networking负载。 尽pipe在理论上,你也可以在客户端运行碳聚合器。 但是,如果使用某个statsd客户端库,还可以使用采样来减less应用程序计算机cpu上的负载(例如,创buildloopback udp数据包)。 此外,statsd可以自动执行多个不同的聚合在一个单一的input度量(总和,平均,最小,最大等等)

  4. 如果您在每个应用程序服务器上使用statsd来聚合响应时间,然后使用Carbon聚合器在石墨服务器上重新聚合这些值,则最终的平均响应时间将由应用程序服务器而不是请求加权。 显然,这只对使用均值或top_90聚合规则进行聚合非常重要,而不是min,max或sum。 而且,如果你的负载不平衡,这只是意味着什么。 作为一个例子:假设你有一个100个服务器的集群,突然有1个服务器被发送99%的stream量。 因此,该服务器上的响应时间是四倍,但在其他99台服务器上保持稳定。 如果你使用客户端聚合,你的总体指标只会上涨3%左右。 但是如果你在一台服务器端碳集合器中进行所有的聚合,那么你的总体指标就会上升大约300%。

  5. 碳-c继电器本质上是c中所写的碳聚合器的直接替代品。 它提高了性能和基于正则expression式的匹配规则。 结果就是你可以在同一个简单的基于regex的configuration文件中同时进行statsd风格的数据点聚合和碳中继风格度量聚合和其他整洁的东西,如多层聚合。

  6. 如果使用氰酸盐后端而不是碳caching,则氰酸盐将在内存(从版本0.5.1开始 )或在读取时间(在版本<0.1.3体系结构中)为您进行内部度量平均。

如果Carbon聚合器提供您需要的一切,则没有理由不使用它。 它有两个基本的聚合函数(总和和平均值),实际上StatsD并不包含这些函数。 (我不确定历史,但也许碳聚合器已经存在,而StatsD作者不想重复function?)Carbon也支持通过UDP接收数据,所以你唯一会错过的是采样,如果你通过平均来聚合,这并不重要。

StatsD通过添加额外的聚合值(例如定时器:平均值,下限,上限和上限第X百分位,…)来支持不同的度量标准types。 我喜欢他们,但是如果你不需要他们,Carbon聚合器也是一个很好的select。

我一直在研究Carbon aggregator和StatsD的源代码(以及Python中的StatsD实现Bucky ),它们都非常简单,我不担心资源使用情况或性能。

看起来像碳聚合器和statsd支持不相交的function集:

  • statsd支持比率计算和求和,但不支持平均值
  • 碳聚合器支持平均,但不支持比率计算。

由于石墨具有最小分辨率,所以在定义的时间间隔内,您不能为相同的度量保存两个不同的值。 StatsD通过预先聚合来解决这个问题,而不是说“1个用户现在注册”和“1个用户现在注册”,而是说“2个用户注册”。

另一个原因是因为:

  1. 您可以通过UDP发送数据给StatsD,这是一个无火的协议,无状态,更快
  2. StatsD etsy的实现在NodeJS中也提高了很多性能。