我正在布置一个架构,我们将在其中使用 statsd 和石墨。我了解石墨的工作原理以及单个 statsd 服务器如何与之通信。我想知道架构和设置如何用于扩展 statsd 服务器。你会有多个节点 statsd 服务器,然后有一个中央 statsd 服务器推送到石墨吗?我似乎找不到任何关于扩展 statsd 的信息,任何关于如何拥有多个 statsd 服务器的想法都将不胜感激。
3 回答
我现在正在处理同样的问题。在多个 statsds 之间进行简单的负载平衡显然是行不通的,因为具有相同名称的键最终会出现在不同的 statsds 中,因此会被错误地聚合。
但是有几个选项可以在需要扩展的环境中使用 statsd:
对计数器指标使用客户端采样,如 statsd 文档中所述(即,不是将每个事件发送到 statsd,而是仅发送每 10 个事件并将 statsd 乘以 10)。缺点是您需要为每个指标手动设置适当的采样率。如果您采样的值太少,您的结果将不准确。如果您采样太多,您将杀死您的(单个)statsd 实例。
构建一个自定义负载均衡器,按指标名称分片到不同的 statsds,从而避免聚合中断的问题。其中每一个都可以直接写入 Graphite。
构建一个统计本地事件的 statsd 客户端,并且只将它们汇总发送到 statsd。这大大减少了流向 statsd 的流量并使其保持不变(只要您不添加更多服务器)。只要您将数据发送到 statsd 的周期远小于 statsd 自己的刷新周期,您也应该获得同样准确的结果。
我在生产中取得了巨大成功的最后一点的变体:使用多个(在我的情况下是本地的)statsds 的第一层,这些statsds 又聚合成一个中央statsd,然后与Graphite 对话。第一层 statsds 需要比第二层更短的刷新时间。为此,您需要一个 statsd-to-statsd 后端。因为我正好遇到了这个问题,所以我写了一个尽可能提高网络效率的文章:https ://github.com/juliusv/ne-statsd-backend
事实上,不幸的是,statsd 的设计目的不是以可管理的方式进行扩展(不,我不认为手动调整采样率是“可管理的”)。但是,如果您坚持下去,上述解决方法应该会有所帮助。
我看到的大多数实现都使用每个服务器指标,例如:<env>.applications.<app>.<server>.<metric>
使用这种方法,您可以在每个盒子上拥有本地 statsd 实例,在本地进行 UDP 工作,并让 statsd 将其聚合发布到石墨。
如果您真的不需要每个服务器的指标,您有两种选择:
- 在可视化层结合相关指标(例如:通过配置graphiti来这样做)
- 使用碳聚集来解决这个问题
如果您可以访问像 F5 BigIP 这样的硬件负载均衡器(我想有 OSS 软件实现可以做到这一点)并且碰巧在您的指标中包含每个主机的主机名(即您正在计算诸如“appname.servername. foo.bar.baz”并在 Graphite 级别聚合它们)您可以使用源地址关联负载平衡 - 它会将所有流量从一个源地址发送到同一目标节点(在合理的超时内)。因此,只要每个指标名称仅来自一个源主机,就可以达到预期的效果。