为什么使用statsd,当graphite的Carbon聚合器可以完成相同的工作?

70

我一直在探索Graphite图形工具,它可以显示来自多个服务器的指标,而"推荐"的方法似乎是先将所有指标数据发送到StatsD。 StatsD会聚合数据并将其发送到graphite(或更确切地说是Carbon)。

在我的案例中,我想对跨服务器的指标执行简单的汇总(例如求和和平均值),并在Graphite中绘制它们。Graphite带有一个Carbon聚合器,可以做到这一点。

但是,StatsD甚至不提供我所讲述的类型的聚合功能。

我的问题是-对于我的用例,我是否应该使用StatsD?我是否遗漏了什么重要信息?

5个回答

34
  1. StatsD操作的是UDP协议,这消除了carbon-aggregator.py响应缓慢并在应用程序中引入延迟的风险。换句话说,实现了松散耦合。

  2. StatsD支持传入指标数据的抽样,当您不希望聚合器获取所有数据点并计算描述性统计信息时,它非常有用。在高负载的代码段中,通常使用0.5%-1%的采样率以避免StatsD过载。

  3. StatsD拥有广泛的客户端支持,请参见此处


10
谢谢。除了第二点之外,所有内容也适用于 Carbon。Carbon 可以配置成监听 UDP,并且有广泛的客户端支持。 - talonx

32
TLDR:如果您希望查看服务器特定的总和或平均值,您可能会需要使用statsd(或carbon-c-relay)。
Carbon聚合器旨在将多个指标的值汇总到一个输出指标中,通常是为了提高图形呈现性能。而Statsd旨在将多个数据点汇总到一个指标中,否则Graphite只会存储最后一个报告的值在最小存储分辨率中。 statsd示例: 假设您的graphite存储模式配置文件具有最小保留时间为10秒(默认值),并且您的应用程序每10秒向services.login.server1.count发送大约100个数据点,值为1。如果没有statsd,graphite将仅在每个10秒桶中存储收到的最后一个计数。在接收到第100条消息之后,其他99个数据点将被丢弃。但是,如果您在应用程序和graphite之间放置了statsd,则它将在将总计发送到graphite之前将所有100个数据点相加。因此,没有statsd时,您的图表仅指示在10秒间隔期间是否发生了登录。有了statsd,则表示在该间隔期间发生了多少次登录。(例如碳汇聚器示例:假设您有200个不同的服务器报告200个单独的指标(services.login.server1.response.timeservices.login.server2.response.time等)。在您的运营仪表板上,您使用此Graphite查询显示所有服务器的平均值图表:weightedAverage(services.login.server*.response.time, services.login.server*.response.count, 2)。不幸的是,呈现此图表需要10秒钟。为解决此问题,您可以添加一个碳汇聚器规则来预先计算所有服务器的平均值并将该值存储在新指标中。现在,您可以更新您的仪表板以简单地拉取单个指标(例如services.login.response.time)。新指标几乎即时呈现。 附注:
  1. the aggregation rules in storage-aggregation.conf apply to all storage intervals in storage-schemas.conf except the first (smallest) retention period for each retention string. it is possible to use carbon-aggregator to aggregate data points within a metric for that first retention period. unfortunately, aggregation-rules.conf uses "blob" patterns rather than regex patterns. so you need to add a separate aggregation-rules.conf file entry for every path depth and aggregation type. the advantage of statsd is that the client sending the metric can specify the aggregation type rather than encoding it in the metric path. that gives you the flexibility to add a new metric on the fly regardless of metric path depth. if you wanted to configure carbon-aggregator to do statsd-like aggregation automatically when you add a new metric, your aggregation-rules.conf file would look something like this:

    <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$
    

    notes: the trailing "$" is not needed in graphite 0.10+ (currently pre-release) here is the relevant patch on github and here is the standard documentation on aggregation rules

  2. the weightedAverage function is new in graphite 0.10, but generally the averageSeries function will give a very similar number as long as your load is evenly balanced. if you have some servers that are both slower and service fewer requests or you are just a stickler for precision, then you can still calculate a weighted average with graphite 0.9. you just need to build a more complex query like this:

    divideSeries(sumSeries(multiplySeries(a.time,a.count), multiplySeries(b.time,b.count)),sumSeries(a.count, b.count))
    
  3. if statsd is run on the client box this also reduces network load. although, in theory, you could run carbon-aggregator on the client side too. however, if you use one of the statsd client libraries, you can also use sampling to reduce the load on your application machine's cpu (e.g. creating loopback udp packets). furthermore, statsd can automatically perform multiple different aggregations on a single input metric (sum, mean, min, max, etcetera)

  4. if you use statsd on each app server to aggregate response times, and then re-aggregate those values on the graphite server using carbon aggregator, you end up with an average response time weighted by app server rather than request. obviously, this only matters for aggregating using a mean or top_90 aggregation rule, and not min, max or sum. also, it only matters for mean if your load is unbalanced. as an example: assume you have a cluster of 100 servers, and suddenly 1 server is sent 99% of the traffic. consequentially, the response times quadruple on that 1 server, but remain steady on the other 99 servers. if you use client side aggregation, your overall metric would only go up about 3%. but if you do all your aggregation in a single server-side carbon aggregator, then your overall metric would go up by about 300%.

  5. carbon-c-relay is essentially a drop-in replacement for carbon-aggregator written in c. it has improved performance and regex-based matching rules. the upshot being that you can do both statsd-style datapoint aggregation and carbon-relay style metric aggregation and other neat stuff like multi-layered aggregation all in the same simple regex-based config file.

  6. if you use the cyanite back-end instead of carbon-cache, then cyanite will do the intra-metric averaging for you in memory (as of version 0.5.1) or at read time (in the version <0.1.3 architecture).


10
如果Carbon聚合器提供了你需要的一切,那么没有理由不使用它。它有两个基本的聚合功能(求和和平均值),而这些功能确实没有被StatsD覆盖。(我不确定历史情况,但也许Carbon聚合器已经存在,而StatsD的作者不想复制这些功能?)Carbon也支持通过UDP接收数据,所以您唯一会错过的是采样,如果您通过平均值聚合,则无关紧要。

StatsD通过添加额外的聚合值来支持不同的指标类型(例如,对于计时器:平均值、下限、上限和上X个百分位数等)。我喜欢它们,但如果您不需要它们,Carbon聚合器也是一个不错的选择。

我一直在查看Carbon聚合器和StatsD(以及Python中的Bucky,它是一个StatsD实现)的源代码,它们都非常简单,所以我不会担心任何一种选择的资源使用或性能问题。


没错。我的问题实质上是由于怀疑许多人可能会选择基于其酷炫因素和许多人在此配置中使用它的statsd。这是一个很棒的工具,但考虑到我的用例,不需要作为中间人。 - talonx

4

看起来 carbon aggregator 和 statsd 支持不同的功能集:

  • statsd 支持速率计算和累加,但不支持平均值
  • carbon aggregator 支持平均值,但不支持速率计算。

-1

由于Graphite具有最小分辨率,因此在定义的时间间隔内无法为同一指标保存两个不同的值。 StatsD通过预先聚合它们来解决此问题,而不是说“现在注册了1个用户”和“现在注册了1个用户”,它会说“已注册2个用户”。

另一个原因是性能,因为:

  1. 您可以通过UDP将数据发送到StatsD,这是一种即发即忘的协议,无状态,速度更快
  2. StatsD etsy的实现是在NodeJS中,这也大大提高了性能。

2
你能指出任何关于graphite最小分辨率的链接吗?对于其他几点-(1) Carbon也支持UDP (https://answers.launchpad.net/graphite/+question/216002) (2) 数据最终会进入Carbon,因此statsd是否高效并不重要(除非我们始终使用statsd进行聚合,因此Carbon最终获得的数据比直接与其通信时少)。 - talonx
这里是您所请求的链接:https://github.com/etsy/statsd/blob/master/docs/graphite.md#correlation-with-statsds-flush-interval - rogercampos
你发的链接讨论了为什么不应该将数据从_statsd_推到graphite快于每10秒一次。但是它并没有说graphite的最小分辨率是10秒。graphite的文档有这样说吗? - talonx
2
实际上,Graphite的最小分辨率是1秒,而不是10秒-请参见https://dev59.com/cHfZa4cB1Zd3GeqPR3jn#19150080 - talonx
2
// @rogercampos,请您更新这篇文章好吗? - Nathan Basanese

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接