在本文中,我将提供一个帮助读者了解用 Graphite 套件创建监控系统所涉及的全部工作的指南。
主要讨论内容
在本文中我们将会谈及如下用于创建 Graphite 监控系统的主题:
- Carbon 和 Whisper 简介
- Whisper 存储模式和聚合
- Graphite Web 应用
前提条件
首先,我们需要能够运行 Graphite 套件的硬件资源。为了简单起见,我将使用 _Amazon Web Services EC2_ 主机。不过,你也可以使用办公室或家中已有的任何型号的计算机。
技术规格:
- 操作系统:Red Hat Enterprise Linux (RHEL) 6.5
- 实例类型:m3.xlarge
- 弹性存储区块(EBS)容量:250 GB
- Python 版本:2.6.6
Carbon 和 Whisper 简介
Graphite 由多个后端和前端组件组成。后端组件用于存储数值型的时间序列数据。前端组件则用于获取指标项数据并根据情况渲染图表。在本文中,我首先会介绍后端组件:Carbon__ 和 Whisper。
指标项可以被发布到一个负载均衡器或直接发布到一个 Carbon__ 线程中。Carbon__ 线程与 Whisper__ 数据库交互,将时间序列数据存储到文件系统中。
安装 Carbon
Carbon实际上是一系列守护进程,组成一个 Graphite 安装的存储后端。这些守护进程用一个名为 Twisted 的事件驱动网络引擎监听时间序列数据。Twisted 框架让 _Carbon_ 守护进程能够以很低的开销处理大量的客户端和流量。
要安装 Carbon,运行如下命令即可(假设目标系统是 RHEL 操作系统):
# sudo yum groupinstall "Development Tools" # sudo yum install python-devel # sudo yum install git # sudo easy_install pip # sudo pip install twisted # cd /tmp # git clone https://github.com/graphite-project/carbon.git # cd /tmp/carbon # sudo python setup.py install
/opt/graphite 文件夹下将包含如下 Carbon 库和配置文件:
# ls -l /opt/graphite drwxr-xr-x. 2 root root 4096 May 18 23:56 bin drwxr-xr-x. 2 root root 4096 May 18 23:56 conf drwxr-xr-x. 4 root root 4096 May 18 23:56 lib drwxr-xr-x. 6 root root 4096 May 18 23:56 storage
在 _bin_ 文件夹下,能够找到如下三种不同类型的 _Carbon_ 守护进程:
- Cache:接受通过各种协议传输来的指标项数据并以尽可能高的效率将它们写入磁盘;在接收到指标项时,将指标项值缓存在 RAM 中,并用底层的 Whisper 库按照指定的时间间隔将这些值写入磁盘。
- Relay:有两个不同的用途:将输入的指标项复制并分区。
- **Aggregator**:运行于 cache 前方,在 Whisper 中记录指标项之前,缓存这些指标项一段时间。
安装 Whisper
Whisper是一个用于存储时间序列数据的数据库,之后应用程序可以用 _create__,update__ 和 fetch_ 操作获取并操作这些数据。
安装 Whisper,需要运行如下命令:
# cd /tmp # git clone https://github.com/graphite-project/whisper.git # cd /tmp/whisper # sudo python setup.py install
Whisper 脚本现在应该已经相应的位置:
# ls -l /usr/bin/whisper* -rwxr-xr-x. 1 root root 1711 May 19 00:00 /usr/bin/whisper-create.py -rwxr-xr-x. 1 root root 2902 May 19 00:00 /usr/bin/whisper-dump.py -rwxr-xr-x. 1 root root 1779 May 19 00:00 /usr/bin/whisper-fetch.py -rwxr-xr-x. 1 root root 1121 May 19 00:00 /usr/bin/whisper-info.py -rwxr-xr-x. 1 root root 674 May 19 00:00 /usr/bin/whisper-merge.py -rwxr-xr-x. 1 root root 5982 May 19 00:00 /usr/bin/whisper-resize.py -rwxr-xr-x. 1 root root 1060 May 19 00:00 /usr/bin/whisper-set-aggregation-method.py -rwxr-xr-x. 1 root root 969 May 19 00:00 /usr/bin/whisper-update.py
启动 Carbon 缓存进程
Carbon 安装包中包含了关于端口号和其他多个配置参数的明确缺省值。拷贝这些已有的示例配置文件:
# cd /opt/graphite/conf # cp aggregation-rules.conf.example aggregation-rules.conf # cp blacklist.conf.example blacklist.conf # cp carbon.conf.example carbon.conf # cp carbon.amqp.conf.example carbon.amqp.conf # cp relay-rules.conf.example relay-rules.conf # cp rewrite-rules.conf.example rewrite-rules.conf # cp storage-schemas.conf.example storage-schemas.conf # cp storage-aggregation.conf.example storage-aggregation.conf # cp whitelist.conf.example whitelist.conf # vi carbon.conf
在 _cache_ 区段下,接收端口这一行包含一个默认值,用于通过 _ 平文本协议(_plaintext protocol _)_ 接受输入指标项(如下所示):
[cache] LINE_RECEIVER_INTERFACE = 0.0.0.0 LINE_RECEIVER_PORT = 2003
执行如下命令,可以启动一个 carbon-cache 进程:
# cd /opt/graphite/bin # ./carbon-cache.py start Starting carbon-cache (instance a)
这个进程现在应该正在监听 2003 端口:
# ps -efla | grep carbon-cache 1 S root 2674 1 0 80 0 - 75916 ep_pol 00:18 ? 00:00:03 /usr/bin/python ./carbon-cache.py start # netstat -nap | grep 2003 tcp 0 0 0.0.0.0:2003 0.0.0.0:* LISTEN 2674/python
发布指标项
指标项(metric _)_ 是一种随着时间不断变化的可度量的数量,例如:
- 每秒请求数
- 请求处理时间
- CPU 使用情况
A datapoint is a tuple containing:
数据点(datapoint_)_ 是包含如下信息的三元组:
- 指标项名称
- 度量值
- 时间序列上某个特定的点(通常是一个时间戳)
客户端应用程序通过将数据点发送至 Carbon 进程发布指标项。应用程序在 Carbon 进程所监听的端口上建立 TCP 连接,然后以简单平文本格式发送数据点信息。在本文的示例中,这个端口号是 2003。这个 TCP 连接可能会一直处于打开状态并根据需要尽可能多次重复使用。Carbon 进程监听输入的数据但是并不会给客户端返回任何响应。
数据点的格式定义如下:
- 每个数据点是一行文本
- 位置 0 是带点的指标项名称
- 位置 1 是一个值
- 位置 2 是一个 Unix 时间戳
- 空格作为各个位置之间的分隔符
例如,下面是一些有效的数据点:
- carbon-cache 进程每分钟接收到的指标项数量
- � carbon.agents.graphite-tutorial.metricsReceived 28198 1400509108
- carbon-cache 每分钟创建的指标项数量
- � carbon.agents.graphite-tutorial.creates 8 1400509110
- 示例服务器端点每分钟的 p95 响应次数
- � PRODUCTION.host.graphite-tutorial.responseTime.p95 0.10 1400509112
客户端应用程序发布指标项的方式可以有多种:
- 通过像 _netcat_(nc)命令这样的工具,使用平文本协议发布
- 使用 pickle 协议
- 使用高级消息队列协议(AMQP)
- 用函数库,如 Dropwizard Metrics 库
为了简单起见,在本文示例中我将通过 netcat 命令用平文本协议发布指标项。发布如上所列的示例数据点,运行如下命令即可:
sudo yum install nc echo "carbon.agents.graphite-tutorial.metricsReceived 28198 `date +%s`" | nc localhost 2003 echo "carbon.agents.graphite-tutorial.creates 8 `date +%s`" | nc localhost 2003 echo "PRODUCTION.host.graphite-tutorial.responseTime.p95 0.10 `date +%s`" | nc localhost 2003
carbon-cache 的日志文件中将包含接收到的新指标项的有关信息以及存储这些信息的位置:
# tail -f /opt/graphite/storage/log/carbon-cache/carbon-cache-a/creates.log 19/05/2014 10:42:44 :: creating database file /opt/graphite/storage/whisper/carbon/agents/graphite-tutorial/metricsReceived.wsp (archive=[(60, 129600)] xff=0.5 agg=average) 19/05/2014 10:42:53 :: creating database file /opt/graphite/storage/whisper/carbon/agents/graphite-tutorial/creates.wsp (archive=[(60, 129600)] xff=0.5 agg=average) 19/05/2014 10:42:57 :: creating database file /opt/graphite/storage/whisper/PRODUCTION/host/graphite-tutorial/responseTime/p95.wsp (archive=[(60, 1440)] xff=0.5 agg=average)
Carbon 与 Whisper 交互,将这些时间序列数据存储到文件系统中。切换到文件系统相应的位置,确保数据文件已经创建成功:
# ls -l /opt/graphite/storage/whisper/carbon/agents/graphite-tutorial/ total 3040 -rw-r--r--. 1 root root 1555228 May 19 10:42 creates.wsp -rw-r--r--. 1 root root 1555228 May 19 10:42 metricsReceived.wsp # ls -l /opt/graphite/storage/whisper/PRODUCTION/host/graphite-tutorial/responseTime/ total 20 -rw-r--r--. 1 root root 17308 May 19 10:42 p95.wsp
最后,你可以用 _whisper-info_ 脚本获取为这些指标项创建的 Whisper 文件的元数据信息。
# whisper-info.py /opt/graphite/storage/whisper/PRODUCTION/host/graphite-tutorial/responseTime/p95.wsp maxRetention: 86400 xFilesFactor: 0.5 aggregationMethod: average fileSize: 17308 Archive 0 retention: 86400 secondsPerPoint: 60 points: 1440 size: 17280 offset: 28
_whisper-dump_ 是一个更完整的脚本,可以输出所有存储保留周期内的原始数据以及 Whisper 文件的元数据信息。
# whisper-dump.py /opt/graphite/storage/whisper/PRODUCTION/host/graphite-tutorial/responseTime/p95.wsp Meta data: aggregation method: average max retention: 86400 xFilesFactor: 0.5 Archive 0 info: offset: 28 seconds per point: 60 points: 1440 retention: 86400 size: 17280 Archive 0 data: 0: 1400609220, 0.1000000000000000055511151231257827 1: 0, 0 2: 0, 0 3: 0, 0 4: 0, 0 5: 0, 0 ... 1437: 0, 0 1438: 0, 0 1439: 0, 0
理解聚合方法,最大保留期,xFilesFactor 和 Whisper 文件中的其他属性是相当重要的。如果现在你有一点迷茫,也不要过于担心,我将在接下来的章节中详细讨论这些属性。
Whisper 存储模式和聚合
当你或你的开发者同事和系统管理员们开始发布数据点却得到了一些意想不到的结果时,可能会有一些困惑:
- 为什么我的数据点被平均了?
- 我已经在周期性地发布数据点了,为什么还是没有任何数据点?
- 我已经发布很多天数据点了,为什么我只得到一天的数据?
Whisper 是如何存储数据的?
首先我们需要理解数据是如何在 Whisper 文件中存储的。当 Whisper 文件被创建时,将拥有一个固定的文件尺寸,这个尺寸永远不会再改变。在 Whisper 文件中可能会包含多个用于不同分辨率的数据点的“存储区(bucket)”,这些存储区是在配置文件中定义的。
例如:
- 存储器 A:拥有 10 秒分辨率的数据点
- 存储区 B:拥有 60 秒分辨率的数据点
- 存储区 C:拥有 10 分钟分辨率的数据点
每个存储区还拥有一个保留期(retention)属性用于标识该存储区中的数据点应该保留的时间长度。例如:
- 存储区 A:分辨率为 10 秒,保留时间 6 小时的数据点
- 存储区 B:分辨率为 60 秒,保留时间 1 天的数据点
- 存储区 C:分辨率为 10 分钟,保留时间 7 天的数据点
根据上述两种信息,Whisper 可以进行一些简单的数学计算,计算出在每个存储区中实际需要保存多少数据点。
- 存储区 A:6 小时 x 60 分钟 / 小时 x 6 数据点 / 分钟 = 2160 点
- 存储区 B:1 天 x 24 小时 / 天 x 60 分钟 / 小时 x 1 数据点 / 分钟 = 1440 点
- 存储区 C:7 天 x 24 小时 / 天 x 6 数据点 / 小时 = 1008 点
如果根据这个存储模式配置创建 Whisper 文件,该文件大小是 56KB。如果在这个文件上执行 _whisper-dump.py_ 脚本,会有如下输出。需要注意的是,一个 _archive_ 对应一个 _ 存储区 _,_ 每点秒数(_seconds per point _)_ 和 _ 点数(_points _)_ 属性则与我们之前的计算相匹配。
元数据:
aggregation method: average max retention: 604800 xFilesFactor: 0.5 Archive 0 info: offset: 52 seconds per point: 10 points: 2160 retention: 21600 size: 25920 Archive 1 info: offset: 25972 seconds per point: 60 points: 1440 retention: 86400 size: 17280 Archive 2 info: offset: 43252 seconds per point: 600 points: 1008 retention: 604800 size: 12096
关于聚合
当数据从一个较高精度的存储区移动到一个较低精度的存储区时,聚合开始发挥作用。让我们以前一个示例中的存储区 A 和存储区 B 为例:
- 存储区 A:分辨率为 10 秒,保留时间 6 小时的数据点(较高精度)
- 存储区 B:分辨率为 60 秒,保留时间 1 天的数据点(较低精度)
我们可能有一个每 10 秒钟发布一个数据点的应用程序。在存储区 A 中可以找到 6 小时之内发布的任何数据点。不过,如果我开始查询 6 小时之前发布的数据点,就可以在存储区 B 中找到它们。
数据点如何移动到存储区 B?
用高精度值除以低精度值,以确定需要聚合的数据点的数量。
l 60 秒(存储区 B)/10 秒(存储区 A)= 6 个数据点需要聚合
_ 注:_Whisper 需要较高精度的值能够整除较低精度的值(也就是说,相除的结果必须是整数)。否则聚合的结果可能会不准确。
聚合数据时,Whisper 从存储区 A 中读取 6 个 10 秒数据点,然后将函数应用于这些数据点上,得出一个将被存储在存储区 B 中的 60 秒数据点。有 5 个聚合函数选项:average_,sum__,max__,min__ 和 last__。_ 聚合函数的选择取决于需要处理的数据点。例如,第 95 百分位的值可能应该用 _max_ 函数聚合。另一方面,对于计数器来说,_sum_ 函数可能更合适。
在聚合数据点时,Whisper 还处理了 xFilesFactor 的概念。xFilesFactor 表示为了保证聚合准确,一个存储区必须包含的数据点比率。在我们之前的示例中,Whisper 确定了它需要聚合 6 个 10 秒数据点。由于网络问题,应用重启等原因,可能只有 4 个数据点有数据而其他 2 个数据点是空值。
如果我们的 Whisper 文件的 xFilesFactor 是 0.5,这意味着只有存在至少 50% 的数据点时,Whisper 才会聚合数据。如果超过 50% 的数据点为空时,Whisper 会创建一个空值聚合。在我们的例子中,即 6 个数据点中的 4 个——也就是 66%。聚合函数会被应用在非空数据点上,创建聚合值。
你可以将 xFilesFactor 设置为 0 到 1 之间的任意值。值 0 表示即使只有一个有效数据点,就会执行聚合。值 1 则表示只有全部的数据点都有效,才会执行聚合。
在前一章节中,我们将所有的样例配置文件拷贝到了 _/opt/graphite/conf_ 文件夹中。控制 Whisper 文件如何创建的配置文件如下:
- /opt/graphite/conf/storage-schemas.conf
- /opt/graphite/conf/storage-aggregation.conf
默认存储模式
存储模式(storage-schemas_)配置文件由多个条目组成,每个条目中包含一个模式,用于匹配指标项名称和保留期定义。默认情况下,包含两个条目:Carbon 和 _ 全部其他。
_carbon_ 条目匹配以“carbon”字符串开头的指标项名称。默认情况下,Carbon 守护进程每 60 秒发布一次它们自己内部的指标项(这一间隔是可以更改的)。例如,carbon-cache 进程会发布指标项,用于标识该进程每分钟创建的指标项文件的数量。保留期的定义则表示数据点每 60 秒记录一次,并保存 90 天。
[carbon] pattern = ^carbon\. retentions = 60s:90d
_ 全部其他 _ 条目通过指定带星号的模式捕捉全部其他与 _Carbon_ 无关的指标项。这个保留期的定义表示数据点每 60 秒记录一次,并保存 1 天。
[default_1min_for_1day] pattern = .* retentions = 60s:1d
默认存储聚合
_storage-aggregation_ 配置文件也是由多个条目组成,其中包括:
- 匹配指标项名称的模式
- 一个 xFilesFactor 值
- 一个聚合函数
默认情况下,包含 4 个条目:
- 以.min 结尾的指标项
- 使用 min 聚合函数
- 至少有 10% 数据点才可以聚合
- 以.max 结尾的指标项
- 使用 max 聚合函数
- 至少有 10% 数据点才可以聚合
- 以.max 结尾的指标项
- 使用 sum 聚合函数
- 聚合的前提是至少要有一个数据点
- 其他指标项
- �使用 average 聚合函数
- 至少有 10% 数据点才可以聚合
[min] pattern = \.min$ xFilesFactor = 0.1 aggregationMethod = min [max] pattern = \.max$ xFilesFactor = 0.1 aggregationMethod = max [sum] pattern = \.count$ xFilesFactor = 0 aggregationMethod = sum [default_average] pattern = .* xFilesFactor = 0.5 aggregationMethod = average
在测试环境下,默认的存储模式和存储聚合函数可以很好的完成任务,不过真正应用到生产指标项时,可能还要修改配置文件。
存储模式修改
首先,我会修改 Carbon 条目。我希望 Carbon 每 60 秒记录一次指标项,并将这些指标项保存 180 天(6 个月)。180 天之后,我希望能够以 10 分钟的精度将这些指标项归档,再保存 180 天。
[carbon] pattern = ^carbon\. retentions = 1min:180d,10min:180d
在 Squarespace,我们用 Dropwizard 框架构建 RESTful 的 Web Service。在准生产环境和生产环境中,我们运行了许多这样的服务,所有这些服务都使用 Dropwizard Metrics 库以每 10 秒一次的速度发布应用和业务指标项。这种 10 秒一次的数据我会保存 3 天。3 天后,这些数据将被聚合为 1 分钟数据并保存 180 天(6 个月)。最后,6 个月之后,这些数据将被聚合为 10 分钟数据并再保存 180 天。
_ 注:_ 如果我的指标项库以不同的速度发布数据点,我就需要修改保留的定义以匹配新的速度。
[production_staging] pattern = ^(PRODUCTION|STAGING).* retentions = 10s:3d,1min:180d,10min:180d
而 Carbon,生产环境或准生产环境之外的指标项,可能只是用于测试。我会将这些数据保存 1 天并且假设他们会每 1 分钟发布一次。
[default_1min_for_1day] pattern = .* retentions = 60s:1d
修改存储聚合
我会保留默认的存储聚合条目,不过会增加几条新的条目用于以 ratio,m1_rate 和 p95 结尾的指标项。
_ 注:_ 新增的条目需要添加到 _default_ 条目之前。
[ratio] pattern = \.ratio$ xFilesFactor = 0.1 aggregationMethod = average [m1_rate] pattern = \.m1_rate$ xFilesFactor = 0.1 aggregationMethod = sum [p95] pattern = \.p95$ xFilesFactor = 0.1 aggregationMethod = max
目前为止,你已经完成了 Graphite 后端的配置以匹配应用程序发布数据点的速率并且已经完全理解数据点是如何在文件系统中存储的。接下来的一章,我们将尝试用 graphite-webapp 将这些数据可视化。
Graphite Web 应用
现在,后端组件已经成功启动并运行,并且能够用我们指定的格式存储数值型的时间序列数据,接下来我们将了解 Graphite 的前端组件。具体说来,我们需要查询并可视化已存储的信息的途径。
据其 Github 描述文件所介绍,Graphite Web 应用程序是一个运行在 Apache/mod_wsgi 下的 Django 应用程序。一般来说,能够提供如下功能:
安装迷阵
graphite-web 的安装真的可以称得上是一个迷阵。我已经多次尝试安装 graphite-web——在 RHEL,CentOS,Ubuntu 和 Mac OS X 上——而每一次的安装步骤都是有不同的。你可以把它当成一场游戏,享受这个过程,当所有必需的依赖都成功安装完成后,你就知道你已经完成了这个迷阵。
RHEL 6.5 安装指南:
# cd /tmp # git clone https://github.com/graphite-project/graphite-web.git # cd /tmp/graphite-web # python check-dependencies.py [REQUIRED] Unable to import the 'django' module, do you have Django installed for python 2.6.6? [REQUIRED] Unable to import the 'pyparsing' module, do you have pyparsing module installed for python 2.6.6? [REQUIRED] Unable to import the 'tagging' module, do you have django-tagging installed for python 2.6.6? [OPTIONAL] Unable to import the 'memcache' module, do you have python-memcached installed for python 2.6.6? This feature is not required but greatly improves performance. [OPTIONAL] Unable to import the 'txamqp' module, this is required if you want to use AMQP as an input to Carbon. Note that txamqp requires python 2.5 or greater. [OPTIONAL] Unable to import the 'python-rrdtool' module, this is required for reading RRD. 3 optional dependencies not met. Please consider the optional items before proceeding. 3 necessary dependencies not met. Graphite will not function until these dependencies are fulfilled.
目标是保证至少所有必需的依赖都安装成功。如果计划使用 AMQ 功能或 Memcache 的缓存功能,就还需要安装可选依赖。
# sudo yum install cairo-devel # sudo yum install pycairo-devel # sudo pip install django # sudo pip install pyparsing # sudo pip install django-tagging # sudo pip install python-memcached # sudo pip install txamqp # sudo pip install pytz # cd /tmp/graphite-web # python check-dependencies.py [OPTIONAL] Unable to import the 'python-rrdtool' module, this is required for reading RRD. 1 optional dependencies not met. Please consider the optional items before proceeding. All necessary dependencies are met.
我已经安装了很多包,满足 _ 必需 _ 依赖的要求后,就可以开始安装 graphite-web:
# cd /tmp/graphite-web # sudo python setup.py install # ls -l /opt/graphite/webapp/ total 12 drwxr-xr-x. 6 root root 4096 May 23 14:33 content drwxr-xr-x. 15 root root 4096 May 23 14:33 graphite -rw-r--r--. 1 root root 280 May 23 14:33 graphite_web-0.10.0_alpha-py2.6.egg-info
安装脚本会将 web 应用文件移动到 _/opt/graphite/webapp_ 文件夹下适当的位置。
数据库初始化
web 应用程序维护了一个内部数据库用于保存用户信息和仪表盘。运行如下命令初始化该数据库:
# cd /opt/graphite # export PYTHONPATH=$PYTHONPATH:`pwd`/webapp # django-admin.py syncdb --settings=graphite.settings You just installed Django's auth system, which means you don't have any superusers defined. Would you like to create one now? (yes/no): yes Username (leave blank to use 'root'): feangulo Email address: feangulo@yaipan.com Password: Password (again): Error: Blank passwords aren't allowed. Password: Password (again): Superuser created successfully. Installing custom SQL ... Installing indexes ... Installed 0 object(s) from 0 fixture(s)
上述命令将创建一个新的数据库并将其保存在 _/opt/graphite/storage_ 文件夹下:
# ls -l /opt/graphite/storage/graphite.db -rw-r--r--. 1 root root 74752 May 23 14:46 /opt/graphite/storage/graphite.db
Graphite Web 应用设置
包含 graphite-webapp 设置的配置文件位于 _/opt/graphite/webapp/graphit_ 文件夹下。将样例配置文件拷贝到该文件夹下:
# vi /opt/graphite/webapp/graphite/local_settings.py ######################### # General Configuration # ######################### TIME_ZONE = 'UTC' ########################## # Database Configuration # ########################## DATABASES = { 'default': { 'NAME': '/opt/graphite/storage/graphite.db', 'ENGINE': 'django.db.backends.sqlite3', 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '' } }
到现在为止,如果你遵循前述章节的指令,现在只会有一个运行在 2003 端口上的 carbon-cache 进程和一个 7002 查询端口。这些是默认情况下 graphite-webapp 所需的端口。因此,配置文件无需任何修改。
# ps -efla | grep carbon-cache 1 S root 14101 1 0 80 0 - 75955 ep_pol May20 ? 00:00:26 /usr/bin/python ./carbon-cache.py start # netstat -nap | grep 2003 tcp 0 0 0.0.0.0:2003 0.0.0.0:* LISTEN 14101/python # netstat -nap | grep 7002 tcp 0 0 0.0.0.0:7002 0.0.0.0:* LISTEN 14101/python
不过,你也可以在设置文件中显式指定从哪个 carbon-cache 进程读取数据:
# vi /opt/graphite/webapp/graphite/local_settings.py ######################### # Cluster Configuration # ######################### CARBONLINK_HOSTS = ["127.0.0.1:7002:a"]
上述代码的含义是我有一个本地运行的名为‘a’的 carbon-cache 进程,其查询端口设置为 7002。查看 Carbon 配置文件,将会看到如下配置:
# vi /opt/graphite/conf/carbon.conf [cache] LINE_RECEIVER_INTERFACE = 0.0.0.0 LINE_RECEIVER_PORT = 2003 CACHE_QUERY_INTERFACE = 0.0.0.0 CACHE_QUERY_PORT = 7002
注:‘a’ 是从何而来的呢?是默认分配的名字。如果要定义更多缓存,需要在配置文件中创建新的命名区块。
[cache:b] LINE_RECEIVER_INTERFACE = 0.0.0.0 LINE_RECEIVER_PORT = 2004 CACHE_QUERY_INTERFACE = 0.0.0.0 CACHE_QUERY_PORT = 7003
仪表盘和图表模版配置
Graphite Web 应用中包含默认的仪表盘和图表模版。拷贝样例配置文件:
# cd /opt/graphite/conf # cp dashboard.conf.example dashboard.conf # cp graphTemplates.conf.example graphTemplates.conf
我对仪表盘配置文件作了一些修改,让图表展示区块更大。
# vi /opt/graphite/conf/dashboard.conf [ui] default_graph_width = 500 default_graph_height = 400 automatic_variants = true refresh_interval = 60 autocomplete_delay = 375 merge_hover_delay = 750
我对默认的图表模版也做了一些修改,让它有一个黑色背景和白色前景。另外我还把字体调小了一些。
# vi /opt/graphite/conf/graphTemplates.conf [default] background = black foreground = white minorLine = grey majorLine = rose lineColors = blue,green,red,purple,brown,yellow,aqua,grey,magenta,pink,gold,rose fontName = Sans fontSize = 9 fontBold = False fontItalic = False
运行 Web 应用程序
终于,一切准备就绪,可以运行 Web 应用程序了。我会在 8085 端口运行这个 Web 应用,你可以随意设置这个端口号。运行如下命令:
# cd /opt/graphite # PYTHONPATH=`pwd`/storage/whisper ./bin/run-graphite-devel-server.py --port=8085 --libs=`pwd`/webapp /opt/graphite 1>/opt/graphite/storage/log/webapp/process.log 2>&1 & # tail -f /opt/graphite/storage/log/webapp/process.log
打开一个 Web 浏览器并输入如下地址 http://your-ip:8085。确保 Graphite Web 应用能够正常加载。用 tail 命令查看 _process.log_ 文件的输出,应该可以看到资源的加载和来自于 web 应用的查询。
(点击图片查看大图)
指标项导航
在上一章中,我们用 netcat 命令将几个指标项发布到 carbon-cache 进程中。具体如下:
<a href="/mag4media/repositories/fs/articles/graphite-intro/zh/resources/0303041.png"> carbon.agents.graphite-tutorial.metricsReceived carbon.agents.graphite-tutorial.creates PRODUCTION.host.graphite-tutorial.responseTime.p95</a>
Web 应用程序以树状结构展示这些指标项。如果在左侧面板中操作指标树,就可以看到全部的指标项。
点击任意一个指标项,右边的面板上将绘制出这个指标项的图表(默认情况下是过去 24 小时的数据)。可以通过面板中图表上方的按钮修改查询的日期范围。
创建仪表盘
在 _Edit Dashboard_ 窗口中输入如下代码,即可构建用于监控 carbon-cache 进程的仪表盘。
注:该仪表盘会监控所有正在运行的 carbon-cache 进程。注意在指标项名称中星号(*)的使用会匹配所有以 _carbon.agents_ 为前缀的值。
<a href="/mag4media/repositories/fs/articles/graphite-intro/zh/resources/0303048.png"> [ { "target": [ "aliasByNode(carbon.agents.*.metricsReceived,2)" ], "title": "Carbon Caches - Metrics Received" }, { "target": [ "aliasByNode(carbon.agents.*.creates,2)" ], "title": "Carbon Caches - Create Operations" }, { "target": [ "aliasByNode(carbon.agents.*.cpuUsage,2)" ], "title": "Carbon Caches - CPU Usage" }, { "target": [ "aliasByNode(carbon.agents.*.memUsage,2)" ], "title": "Carbon Caches - Memory Usage" } ]</a>
修改_Edit Dashboard_ 对话框中的内容会更新浏览器中的仪表盘。不过这些修改并没有保存到Graphite 的内部仪表盘数据库中。继续并保存该仪表盘,以便可以分享并再次打开它。
在Graphite 的生产安装环境中,_Graphite Caches_ 仪表盘的外观界面更类似下图:
API 才是重点
(点击图片查看大图)
Graphite API 支持多种显示选项以及遵循简单的函数式语法的数据操作函数。考虑到复杂的表达式和计算过程,函数可以嵌套。查看在线文档以详细了解全部可用的函数:
假设我有一个运行在上百台服务器上的应用,每个服务器每 10 秒钟发布一次各自的 p95 响应时间。利用 API 中所提供的函数,我可以对指标项进行加工并构建一个信息化图表:
- averageSeries: 计算集合内所有值的平均值
我们想要看一下全部 p95 时延的平均值
- scale: 将一个值乘以一个常量
� 时延是以毫秒为单位记录的,我们想要以秒为单位展示。
- alias: 更改指标项展示的名称
我们想要在图表的图例中只展示 _avg p95_,而不是指标项全名
作为指标项查询的一部分传递给 API 的函数参数如下:
alias(scale(averageSeries(PRODUCTION.host.*.requests.p95),0.001),'avg p95')
API 将返回如下图表:
恭喜!我们已经完成了 Carbon,Whisper 和 graphite-webapp 的安装和配置,指标项的发布和导航以及仪表盘的构建。现在你可以为你的业务和应用指标项构建漂亮的仪表盘。
本文是关于 Graphite 的一篇入门级文章。关于更高级的主题请参考:
关于作者
Franklin Angulo在 Squarespace 的负责管理构建和维护大型核心后端引擎的团队,Squarespace 是一家位于纽约市的网站构建平台。Franklin 是一名在带领复杂的跨领域的大型工程项目方面有丰富经验的专业人士。在加入 Squarespace 之前他曾经是亚马逊的一名资深软件开发工程师,主要负责全球进货物流和亚马逊储物柜计划的路由规划调优,运率购买和容量规划算法。
评论