Fork me on GitHub
Suzf  Blog

How-to set up and use graphite on Ubuntu

Graphite 是一个Python写的web应用,采用django框架,Graphite用来进行收集服务器所有的即时状态,用户请求信息,Memcached命中率,RabbitMQ消息服务器的状态,Unix操作系统的负载状态,Graphite服务器大约每分钟需要有4800次更新操作,Graphite采用简单的文本协议和绘图功能可以方便地使用在任何操作系统上。 Graphite 仅是一个画图工具,不主动地收集数据,而是将接收到的数据以图形的方式展现出来。 因为Graphite不收集数据,所以需要将指定格式的数据发送给Graphite,其在将受到的数据,绘制成图像。 Graphite的功能

  • 存储时间序列数据
  • 根据需要呈现数据的图形

Graphite 三大组件:

  1. Graphite-Web, a Django-based web application that renders graphs and dashboards
  2. The Carbon metric processing daemons
  3. The Whisper time-series database library

graphite-overview 实验环境

Ubuntu Release: 16.04
Python: 2.7.12

# pip freeze | egrep -i 'django|whisper|carbon|graphite|uwsgi|cairocffi|pytz|fontconfig'
cairocffi==0.8.0
carbon==0.9.15
Django==1.8.14
django-common==0.1.51
django-tagging==0.4.5
graphite-web==0.9.15
pytz==2014.10
uWSGI==2.0.14
whisper==0.10.0rc1

# PS
# 关于 Django 与 graphite-web 的版本问题可能造成 graphite-web 无法正常打开
# 请自行 升降 Django  版本, 或是直接修改相关模块的源码

Basic Graphite requirements

Graphite 安装

sudo apt-get install nginx uwsgi uwsgi-plugin-python
sudo apt-get install graphite-web graphite-carbon python-whisper

基本上到这里 Graphite 相关的组件就已经安装完成了, 接着我们也可以用官方提供的检测脚本 check-dependencies.py 检测一下依赖关系,之后缺少什么安装包安装什么就好了。

PS 本文使用的是 Django 1.8 所以检测 Django 可能会有提示,不影响使用,自行跳过。

配置 Graphite

# grep -v "^#\|^$"  /etc/graphite/local_settings.py
SECRET_KEY = 'YOURS_SECRET_KEY'
TIME_ZONE = 'Asia/Shanghai'
LOG_RENDERING_PERFORMANCE = True
LOG_CACHE_PERFORMANCE = True
LOG_METRIC_ACCESS = True
DEBUG = True
GRAPHITE_ROOT = '/usr/share/graphite-web'
CONF_DIR = '/etc/graphite'
STORAGE_DIR = '/var/lib/graphite/whisper'
CONTENT_DIR = '/usr/share/graphite-web/static'
WHISPER_DIR = '/var/lib/graphite/whisper'
LOG_DIR = '/var/log/graphite'
INDEX_FILE = '/var/lib/graphite/search_index'  # Search index file
DATABASES = {
    'default': {
        'NAME': 'graphite',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'graphite',
        'PASSWORD': 'YOURS_PASSWORD',
        'HOST': 'localhost',
        'PORT': '3306'
    }
}

同步数据库信息

sudo graphite-manage makemigrations
sudo graphite-manage migrate

配置 uWSGI

# cat /etc/uwsgi/apps-enabled/graphite.ini 
[uwsgi]
processes = 2
uid = _graphite
gid = _graphite
master = True
chdir = /usr/lib/python2.7/dist-packages/graphite
wsgi-file = /usr/share/graphite-web/graphite.wsgi
chmod-socket = 666
enable-threads = true
socket = /run/uwsgi/app/graphite/graphite.socket

测试 uwsgi 是否配置正确

uwsgi --http :8000 --chdir  /usr/lib/python2.7/dist-packages/graphite --wsgi-file /usr/share/graphite-web/graphite.wsgi

然后通过浏览器访问 8000 端口看输出页面是否正常 关于 UWSGI APP 的日志位于 /var/log/uwsgi/app/graphite.log,该日志是调试 uwsgi 程序的关键。 配置 Nginx

# cat /etc/nginx/sites-enabled/graphite.conf 
server {
  listen 80;
  # server_name 172.16.9.110;
  server_name graphite.suzf.net;

  access_log /var/log/nginx/graphite-access.log;
  error_log /var/log/nginx/graphite-error.log;

  location / {
    include uwsgi_params;
    uwsgi_pass unix:///run/uwsgi/app/graphite/graphite.socket;
  }

  location /static {
    alias /usr/share/graphite-web/static;
  }

}

配置 Carbon

1. sudo vim /etc/default/graphite-carbon
CARBON_CACHE_ENABLED=true

2. sudo vim /etc/carbon/carbon.conf
#开启Carbon的log rotation
ENABLE_LOGROTATION = True

3. sudo vim /etc/carbon/storage-schemas.conf
#配置storage schemas
#意思是匹配任何以test.开头的metrics,采用三种方式收集存储数据:
#1.10s:10m---每10秒创建一个数据点,保存10分钟内该类型的数据点。
#2.1m:1h---每1分钟创建一个数据点,保存1小时内该类型的数据点。
#3.10m:1d---每10分钟创建一个数据点,保存一天内的该类型的数据点。
[test]
pattern = ^test\.
retentions = 10s:10m,1m:1h,10m:1d

4. sudo cp /usr/share/doc/graphite-carbon/examples/storage-aggregation.conf{.example,}
# /etc/carbon/storage-aggregation.conf中的aggregation method默认使用的是average,
# 其中的xFileFactor的值代表Carbon做聚合的最小百分比值,根据你的具体情况修改。

启动相关服务

sudo service carbon-cache start
sudo service nginx start
sudo service uwsgi start
metrics的配置,精度的具体配置得看自己的业务,并不是粒度越细越好。江南白衣有篇很好的文章:Graphite的百万Metrics实践之路,就直接引过来,希望对大家有帮助。Graphite的安装及配置并不是非常容易,如果碰见问题,查查资料便能够解决,特别注意各种版本的兼容问题。

Whisper存储模式和聚合

在开始的架构图中,你可能已经看见Graphite包含三个组件,CarbonGraphite-web你可以不了解。但是如果你对Whisper的内部运行原理不是很了解,你可能会碰见如下的困惑:

  • 为什么我的数据点被平均了?
  • 为什么我周期性的发布了数据点,却看不见任何数据?
  • 我发布了很多天的数据,却只能看见一天的数据?
  • 为什么看见的数据跟我发布的数据点好像对应不上?

要解决以上的问题,首先我们要明白Whisper是如何存储数据的,然后要了解它的聚合规则,最后还有数据点的移动。只要掌握了这些,我们才能配置合理的存储模式以及聚合规则,从而得到我们想要的结果。InfoQ上的 DevOps实战:Graphite监控上手指南已经讲的非常透彻,此处本着不造轮子的原则,就不复述了。

Graphite如何获取数据

如果你有一些随时间变化的数值,然后你想他们绘图,那么 Graphite 非常有用。基本上你编写一个程序来收集这些数值,然后将他们发送到graphite的后端即可。

1.命名方案

存储在Graphite的任何东西都有一个路径,这些路径由多个部分组成,每个部分以点号相隔。 比如在”foo.bar.baz”这个路径中,每个点周围的东西都称为一个路径组件,因此“foo”,“bar”,“baz”都是路径组件。 每个路径组件必须是明确的,有目的的。路径组件应该和系统层次尽量保持相对应的深度。

2.数据保存

Graphite建立在固定尺寸的数据库上 (参考whisper) ,因此我们必须预先配置我们想存储多少数据和数据的精度。 比如你想以一分钟的精度(即每分钟有一个数据节点)保存2小时的数据。另外你还可以以10分钟的精度保存2周的数据。其理念就是存储开销由你想存储的数据节点决定的,精度越低,那就可以以更少的节点覆盖更长的时间。 要确定最佳的保存配置,你必须回答以下所有问题:

  •     你的数据多久产生一次?
  •     你要求的最大精度是多少?
  •     在那个精度下,你需要查看多久的数据?
  •     你能使用的最小精度是多少?
  •     你要查看多久之前的数据?(它必须是个有限时,且提前确定好)

一旦你选择好了命令方案和回答了以上所有问题,那么你可以通过创建或修改/opt/graphite/conf/storage-schemas.conf文件来创建一个schema。 schema文件的格式通过示例最容易说明。假设我们已经写了一个脚本,这个脚本会从不同的服务器中收集系统性能数据,它的命名方案类似于:

servers.HOSTNAME.METRIC

其中HOSTNAME是服务器的主机名,METRIC是一个像 cpu_load, mem_usage, open_files的性能数据。同时假设我们想以一分钟的精度保存这些数据30天,以15分钟的精度保存10年。 下面是我们要写入到schema文件的内容:

[server_load]         # schema名称,可任意
priority = 100        # 优先级
pattern = ^servers\.
retentions = 60:43200,900:350400

简单来说,当carbon接收到一个指标数据时,Graphtie会确定这个指标数据应该保存到文件系统的哪个whisper数据文件中。如果数据文件不存在,carbon知道它必须创建一个,但是因为whisper是一个确定尺寸的数据库,在创建文件时必须确定某些参数(这就是为什么我们写入schema的原因)。 Carbon查看schema文件,然后根据优先规则选择第一个匹配指标数据名称的schema。如果没有schema匹配,那么默认的schema会被启用 (每分钟一分,保存2小时) 。一旦合适的schema确定之后,carbon会使用schema中的保存配置参数创建whisper数据文件。 现在回到我们的schema内容。 server_load              schema名称,你如何写都无所谓。 priority                      是一个整数,表示优先级,由高到低。作用:一个是让测试更常使用的schema更快;二是优先级提供了一种方式,通过这种方式可以为已经匹配另外一个schema的指标数据提供一个不同的保存。 pattern 参数是一个正则表达式,它用来匹配一个新的指标名称来查找它适用于哪个schema。在我们的例子中,这个模式就匹配所有以servers.开头的指标数据。 retentions 参数有点复杂,它是这样工作的: 保存配置之间以逗号相隔,每个保存配置的格式为:seconds_per_data_point:data_points_to_store。 因此在我们的例子中,第一个保存配置是每个数据节点为60秒,然后存储43,200个这样的节点。 第二个保存配置是每900秒一个数据节点, 然后保存350,400 这样的点。

3. Graphite数据格式

可以通过shell脚本,向graphite的2003端口发送数据。

#路径   值    时间戳
metric_path value timestamp
…
metric_path value timestamp

举个栗子 采集 系统 load

#/bin/bash

i=1

while [ $i -le 60 ]
do
      echo   "test.`hostname -f`.load.one      `cat /proc/loadavg | cut -d' ' -f 1` `date +%s`" | nc localhost 2003
      echo   "test.`hostname -f`.load.three    `cat /proc/loadavg | cut -d' ' -f 2` `date +%s`" | nc localhost 2003
      echo   "test.`hostname -f`.load.fifteen  `cat /proc/loadavg | cut -d' ' -f 3` `date +%s`" | nc localhost 2003
      
      sleep 60 ;
      let "i=i+1";
done

  graphite_test 参考文档

[0] http://graphite.readthedocs.io/en/latest

[1] https://github.com/graphite-project/graphite-web

[2] https://my.oschina.net/fufangchun/blog/232895

[3] http://www.yangguo.info/2015/08/17/%E5%9F%BA%E4%BA%8EGraphite%E7%9A%84%E7%9B%91%E6%8E%A7%E6%96%B9%E6%A1%88/

[4] http://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html