写点什么

一文搞懂指标采集利器 Telegraf

用户头像
尔达Erda
关注
发布于: 刚刚
一文搞懂指标采集利器 Telegraf

作者| 姜闻名

来源|尔达 Erda 公众号


导读:为了让大家更好的了解 MSP 中 APM 系统的设计实现,我们决定编写一个《详聊微服务观测》系列文章,深入 APM 系统的产品、架构设计和基础技术。本文为该系列文章的第三篇,将主要对 Telegraf 数据处理链路的实现原理以及插件实现方式进行介绍。


《详聊微服务观测》系列文章:



Telegraf 是 InfluxData 公司开源的一款十分流行的指标采集软件,在 GiHub 已有上万 Star。其借助社区的力量,拥有了多达 200 余种采集插件以及 40 余种导出插件,几乎覆盖了所有的监控项,例如机器监控、服务监控甚至是硬件监控。​

架构设计

Pipeline 并发编程

​在 Go 中,Pipeline 并发编程模式是一种常用的并发编程模式。简单来说,其整体上是由一系列阶段(stage),每个 stage 由一组运行着相同函数的 goroutine 组成,且各个 stage 之间由 channel 相互连接。


在每个阶段中,goroutine 负责以下事宜:​


  1. 通过入口 channel,接收上游 stage 产生的数据。

  2. 处理数据,例如格式转换、数据过滤聚合等。

  3. 通过出口 channel,发送处理后的数据到下游 stage。


其中,每个 stage 都同时拥有一个或多个出口、入口 channel,除了第一个和最后一个 stage,其分别只有出口 channel 和入口 channel。​

Telegraf 中的实现

​Telegraf 采用了这种编程模式,其主要有 4 个 stage,分别为 Inputs、Processors、Aggregators 和 Outputs。​


  • Inputs:负责采集原始监控指标,包括主动采集和被动采集。

  • Processors:负责处理 Inputs 收集的数据,包括去重、重命名、格式转换等。

  • Aggregators:负责聚合 Processors 处理后的数据,并对聚合后的数据计算。

  • Outputs:负责接收处理 Processors 或 Aggregators 输出的数据,并导出到其他媒介,例如文件、数据库等。


且它们彼此之间也是由 channel 相互链接的,其架构图如下所示:



可以看到,其整体上采用的就是 pipeline 并发编程模式,我们简单介绍下它的运作机制:​


  • 第一个 stage 为 Inputs,每个 input 生成一个 goroutine,各自采集数据并扇入(fan-in)到 channel 中。

  • 第二个 stage 为 Processors,每个 processor 生成一个 goroutine,并按顺序彼此用 channel 连接。

  • 第三个 stage 为 Aggregators,每个 aggregator 生成一个 goroutine,并消费 Processors 产生的数据,并扇出(fan-out)到各个 aggregator。

  • 最后一个 stage 为 Outputs,每个 output 生成一个 goroutine,并消费由 Processors 或 Aggregators 产生的数据,并扇出到各个 output。


扇入(fan-in):多个函数输出数据到一个 channel,并由某个函数读取该 channel 直到其被关闭。​扇出(fan-out):多个函数读取同一个 channel 直到其被关闭。

插件设计

​Telegraf 拥有如此众多的 input、output 以及 processor 插件,那么它是如何高效地管理这些插件呢?并且又是如何设计插件体系以应对不断激增的扩展需求呢?别急,请容我细说。​其实,这里的插件并非通常意义上的插件(即在运行时动态加载与绑定动态链接库),而是一种基于工厂模式的变体,首先我们来看下 Telegraf 的插件目录结构:


plugins├── aggregators│   ├── all│   ├── basicstats│   ├── registry.go...├── inputs│   ├── all│   ├── cpu│   ├── registry.go...├── outputs│   ├── all│   ├── amqp│   ├── registry.go...├── processors│   ├── all│   ├── clone│   ├── registry.go...
复制代码


​由上可以看到,目录结构是有规律的(以下我们均以 Inputs 的插件为例,其他模块实现类似)。​


  • plugins/inputs:为各个 input 插件的包目录。

  • plugins/inputs/all:通过 import 的方式引入插件模块包(主要是为了避免循环引用)。

  • plugins/inputs/registry.go:存放注册表以及相关函数。

接口声明

​Telegraf 通过 interface 来声明如下 Input 接口,表示 Input:


接口实现

​在 plugins/inputs/ 目录中创建插件,例如 cpu,实现 Input 接口:


注册插件

​最后,我们只需要往全局注册表中注册插件的工厂函数即可:



如此,众多插件就被有条不紊的管理起来了。同时,扩展插件也很方便,只需实现 Input 接口并注册工厂函数即可。​

Erda 中的应用

​在 Erda 中,我们使用 Telegraf 作为 Erda 平台的指标采集服务,以守护进程的方式部署在每台物理机上。现如今,已广泛应用生产,在上千台机器上稳定运行,采集并上报大量指标,以供 SRE 及相关运维人员方便地分析与排查。​由于一些特殊的需求,我们不得不基于 Telegraf 进行了二次开发,以便更好的适配业务需求。虽然如此,得益于 Telegraf 强大的插件系统,我们往往只需要针对需求新增插件即可。例如,增加 output 插件以上报到我们自己的收集端,增加 intput 插件检查 Erda 自身组件健康度等。​后续,我们将逐渐抛弃二开部分,拥抱开源,最大化地与 Telegraf 官方开源版本保持一致,以回馈社区。

参考


如果你有任何疑问,欢迎添加小助手微信(Erda202106)加入交流群,参与交流和讨论!


发布于: 刚刚阅读数: 4
用户头像

尔达Erda

关注

还未添加个人签名 2021.06.16 加入

还未添加个人简介

评论

发布
暂无评论
一文搞懂指标采集利器 Telegraf