我一直在探索用于显示来自多个服务器的指标的 Graphite 绘图工具,似乎“推荐”的方式是首先将所有指标数据发送到 StatsD。StatsD 聚合数据并将其发送到石墨(或者更确切地说,碳)。
就我而言,我想对跨服务器的指标进行简单的聚合,例如求和和平均,并在石墨中绘制。Graphite 带有一个碳聚合器,可以做到这一点。
StatsD 甚至不提供我所说的那种聚合。
我的问题是 - 我应该在我的用例中使用 statsd 吗?我在这里缺少什么吗?
StatsD 通过 UDP 运行,这消除了 carbon-aggregator.py 响应缓慢和在应用程序中引入延迟的风险。换句话说,松散耦合。
StatsD 支持入站指标的采样,当您不希望聚合器采用 100% 的所有数据点来计算描述性统计数据时,这很有用。对于大容量代码部分,通常使用 0.5%-1% 的采样率,以免 StatsD 过载。
StatsD 拥有广泛的客户端支持。
tldr:如果您想查看特定于服务器的总和或平均值,您可能需要 statsd (或carbon-c-relay )。
carbon aggregator旨在将来自多个指标的值聚合到一个输出指标中,通常是为了提高图形渲染性能。statsd旨在在单个指标中聚合多个数据点,否则石墨仅存储在最小存储分辨率中报告的最后一个值。
statsd 示例: 假设您的石墨 storage-schemas.conf 文件的最短保留时间为 10 秒(默认),并且您的应用程序每 10 秒向services.login.server1.count发送大约 100 个数据点,值为 1。如果没有 statsd,graphite 只会存储每 10 秒存储桶中收到的最后一个计数。在收到第 100 条消息后,其他 99 个数据点将被丢弃。但是,如果您将 statsd 放在应用程序和石墨之间,那么它会将所有 100 个数据点加在一起,然后再将总数发送到石墨。因此,如果没有 statsd,您的图表仅指示在 10 秒间隔内是否发生了登录。使用 statsd,它表示有多少在该时间间隔内发生了登录。(例如)
碳聚合器示例:假设您有 200 个不同的服务器报告 200 个单独的指标(services.login.server1.response.time、services.login.server2.response.time等)。在您的操作仪表板上,您使用此石墨查询显示所有服务器的平均值图表:weightedAverage(services.login.server*.response.time, services.login.server*.response.count, 2)。不幸的是,渲染这个图需要 10 秒。要解决此问题,您可以添加碳聚合器规则来预先计算所有服务器的平均值并将值存储在新指标中。现在您可以更新仪表板以简单地提取单个指标(例如services.login.response.time)。新指标几乎立即呈现。
旁注:
storage-aggregation.conf 中的聚合规则适用于 storage-schemas.conf 中的所有存储间隔,除了每个保留字符串的第一个(最小)保留期。可以使用碳聚合器来聚合第一个保留期的指标内的数据点。不幸的是,aggregation-rules.conf 使用“blob”模式而不是正则表达式模式。因此您需要为每个路径深度和聚合类型添加单独的 aggregation-rules.conf 文件条目。statsd 的优点是发送度量的客户端可以指定聚合类型,而不是在度量路径中对其进行编码。无论度量路径深度如何,您都可以灵活地动态添加新度量。如果您想配置 carbon-aggregator 在添加新指标时自动进行类似 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 上的相关补丁,这是关于聚合规则的标准文档
weightedAverage 函数是石墨 0.10 中的新功能,但通常只要您的负载均匀平衡,averageSeries 函数就会给出非常相似的数字。如果您有一些服务器速度较慢且服务的请求较少,或者您只是追求精确度,那么您仍然可以使用石墨 0.9 计算加权平均值。你只需要像这样构建一个更复杂的查询:
divideSeries(sumSeries(multiplySeries(a.time,a.count), multiplySeries(b.time,b.count)),sumSeries(a.count, b.count))
如果 statsd 在客户端机器上运行,这也可以减少网络负载。尽管理论上,您也可以在客户端运行 carbon-aggregator。但是,如果您使用 statsd 客户端库之一,您还可以使用采样来减少应用程序计算机 cpu 的负载(例如创建环回 udp 数据包)。此外,statsd 可以对单个输入指标(总和、平均值、最小值、最大值等)自动执行多个不同的聚合
如果您在每个应用服务器上使用 statsd 来聚合响应时间,然后使用 carbon 聚合器在石墨服务器上重新聚合这些值,您最终会得到应用服务器而不是请求加权的平均响应时间。显然,这只对使用 mean 或 top_90 聚合规则进行聚合很重要,而不是 min、max 或 sum。此外,仅当您的负载不平衡时才有意义。举个例子:假设你有一个由 100 台服务器组成的集群,突然 1 台服务器发送了 99% 的流量。因此,该 1 台服务器上的响应时间增加了四倍,但在其他 99 台服务器上保持稳定。如果您使用客户端聚合,您的整体指标只会上升约 3%。但是,如果您在单个服务器端碳聚合器中进行所有聚合,那么您的整体指标将上升约 300%。
carbon-c-relay本质上是用 c 编写的 carbon-aggregator 的替代品。它改进了性能和基于正则表达式的匹配规则。结果是您可以在同一个简单的基于正则表达式的配置文件中进行 statsd 样式的数据点聚合和 carbon-relay 样式的度量聚合以及多层聚合等其他简洁的东西。
如果您使用cyanite后端而不是 carbon-cache,那么 cyanite 将在内存中(从版本 0.5.1开始)或在读取时(在版本 <0.1.3 架构中)为您执行内部度量平均。
如果 Carbon 聚合器提供您需要的一切,那么没有理由不使用它。它有两个基本的聚合函数(求和和平均),而且这些确实没有包含在 StatsD 中。(我不确定历史,但也许 Carbon 聚合器已经存在并且 StatsD 作者不想复制功能?)Carbon 也支持通过 UDP 接收数据,所以你唯一会错过的就是采样,如果您通过平均来聚合,这并不重要。
StatsD 通过添加额外的聚合值来支持不同的度量类型(例如,对于计时器:平均值、下限、上限和上限 Xth 百分位,...)。我喜欢它们,但如果你不需要它们,Carbon 聚合器也是一个不错的选择。
我一直在查看 Carbon 聚合器和 StatsD 的源代码(以及Bucky,Python 中的 StatsD 实现),它们都非常简单,我不会担心任何一个选择的资源使用或性能。
看起来碳聚合器和 statsd 支持不相交的功能集:
因为石墨具有最小分辨率,所以您不能在定义的时间间隔内为同一度量保存两个不同的值。StatsD 通过预先聚合它们来解决这个问题,而不是说“1 个用户现在注册”和“1 个用户现在注册”它说“2 个用户注册”。
另一个原因是性能,因为: