Menu

  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay
  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay

Graphite学习笔记

11
Jul
2016

Graphite学习笔记

By Alex
/ in Database,Python
/ tags Django, Monitoring, TSDB, 学习笔记
0 Comments
简介

Graphite是一个开源项目,可以作为时间序列数据库(TSDB)使用,当你需要存储随着时间变化的数值时,应当考虑使用时间序列数据库。

除了数据的存储、查询外,Graphite还提供数据可视化(UI层)功能,它可以很好的在廉价的硬件上运行。你可以使用Graphite来监控网站、应用程序、网络服务器等的性能数据(Metrics),轻松实现基于时间维的分析。

Graphite本身不负责性能数据的采集,但是它提供了简单易用的接口,公共这些接口你可以把基于数字的性能数据存储到Graphite中。

术语
术语 说明
datapoint 数据点,存放在timestamp bucket中的数值。timestamp bucket中的默认值是None
function 时间序列( time-series)函数,用来转换、合并、计算多个series
resolution 分辨率,也称precision。序列中,一个数据点所跨越(代表)的秒数。分辨率确定了存储数据点频率
如果一个series每N秒存储一个数据点,则其分辨率为N
retention 驻留,series中包含的数据点的个数
series 一已命名的数据点的集合,每个series由其名称唯一确定,名称由点号分隔的字符串组成
也称为Metrics、Metric series
series list 包含通配符的series名称,匹配多个series
target 图形展示时的数据源,可以是metrics名称、metrics通配符、或者基于前两者的函数调用表达式
timestamp 数据点所关联的时间,1970-01-01到产生数据点那一刻的秒数
timestamp bucket 经过舍入后,能够整除分辨率的timestamp
架构

Graphite由三个组件构成:

  1. Carbon:一个基于Twisted(Python事件驱动网络框架)的守护程序,负责监听外部的时间序列数据
  2. Whisper:一个简单的存储时间序列数据的数据库,设计上和RRDtool类似 
  3. Graphite-Web:一个基于Django(Python Web框架)的Web应用,使用Cairo(一个2D图形库)来渲染性能数据的图表,使用ExtJS作为基础UI框架

下面是Graphite的架构图:graphite-arch

一旦你把数据送给Carbon,它就立刻可以在Webapp的图表中显示,因为数据在被写入文件系统之前,会驻留在缓存中。

除了使用Graphite Webapp,你也可以通过URL API,将图表嵌入到自己的应用程序中去。如何使用Graphite

如何使用Graphite

使用Graphite来监控你的性能数据,你需要完成以下工作:

  1. 理解Graphite组件的职责和相互关系
  2. 安装Graphite及其依赖
  3. 基础的配置,让Graphite能运行起来
  4. 设计Metrics路径
  5. 配置Metrics的驻留规则、聚合规则等
  6. 向Graphite发送Metrics
  7. 从Graphite获取Metrics并展示
Metrics路径设计

Metrics路径由点号分隔的字符串构成,类似于Python的包名称。路径是Metrics的标识。

你应当仔细的设计此路径的命名空间,以反映出所有Metrics之间的层次关系。例如servers.zircon.cpu,这个三级路径设计中,第一级表示设备类别,第二级表示设备名称,第三级表示监测点类型。

理解Graphite组件
Carbon

Carbon由一系列的守护进程组成,这些守护进程共同组成Graphite的存储后端。在最小化的安装下,只有一个守护进程carbon-cache.py。根据需要你可以启用carbon-relay.py、carbon-aggregator.py以便实现Metrics分发、定制聚合规则。各Carbon守护进程简介如下:

守护进程 说明
缓存进程
carbon-cache

缓存进程的程序文件是carbon-cache.py。它通过多种协议接收Metrics,然后尽可能高效的将其写入磁盘。从实现角度来说,缓存进程先把Metrics存放在RAM中,然后定期的通过whisper库进行入库

缓存进程提供一个查询服务供Graphite Webapp使用,用来快速获取位于内存中的Metrics数据点

要定制此进程的行为,可以修改carbon.conf的[cache]段、storage-schemas.conf、storage-aggregation.conf

中继进程
carbon-relay

该进程可以担任这两个职责之一:复制(replication)和分片(sharding)

要定制此进程的行为,可以修改carbon.conf的[relay]段、relay-rules.conf

前置聚合进程
carbon-aggregator

前置于缓存进程运行,能够在存入whisper之前,缓冲、聚合Metrics。当不需要细粒度的数据时启用该进程,可以减少I/O和.wsp文件的大小

要定制此进程的行为,可以修改carbon.conf的[aggregator]段、aggregation-rules.conf

Whisper

Whisper是一个固定大小(fixed-size)的数据库,其设计和用途与RRD(round-robin-database)类似。它能提供快速、可靠的数值数据的存储。

Whisper能够对最近的数据进行高分辨率的存储,而对久远的历史数据,自动降低其存储精度(减少样本数量)。

在大多数场景下,Whisper有足够好的性能。它比RRDtool慢,主要原因是Whisper基于Python编写,这个性能差异很小,通常不需要考虑。

Whisper数据库以文件方式存放在磁盘上,扩展名.wsp。Carbon会为每个Metrics创建一个.wsp文件,路径的最后一节作为文件的basename,路径的其它部分形成目录层次。

数据点

在Whisper中存储的每一个数值,称为数据点(Data Points)。

在磁盘上,数据点以大端、双精度浮点数存储。每个数据还附带一个时间戳信息,时间戳为1970-01-01到数据采集时间的秒数。

归档

一个Whisper数据库文件可以包含一个或者多个“归档”,归档是数据文件中的逻辑段。

每个归档具有不同的数据分辨率(一定时间段内,数据点数量越多,则分辨率越高)。归档以最高分辨率(最小驻留时间) —— 最低分辨率(最长驻留时间)的顺序,在数据库文件中顺序排列。

为了精确的从高分辨率向低分辨率的归档聚合,高分辨率归档和它之后的低分辨率归档,其分辨率应当具有整除关系。例如,第一个归档分辨率为60秒/数据点,那么第二个归档可以是300秒/数据点,第三个归档可以是3600秒/数据点。

一个数据库的总计驻留时间(存放的数据点跨越的时间),由最长驻留时间的(最后一个)归档确定。因为之前的那些归档,时间区间都是它的子区间。

聚合

把数据点转移到低分辨率归档时,面临着如何把多个数据点转变为单个数据点的问题。Whisper支持average、sum、last、max、min等聚合函数。

注意,这里的聚合和Carbon提供的前置聚合不是一回事。

多归档的读写策略

当Whisper向一个多归档数据写入Metrics时,数据点将被同时写入到所有的归档中。这意味着聚合动作随时可能发生。

当从Whisper中获取数据时,第一个能完整覆盖所需区间的归档被使用。

磁盘空间利用率问题

Whisper的磁盘利用效率不高,因为:

  1. 每个数据点要附加一个时间戳信息
  2. 由于归档的时间区间有重叠,因此数据存在冗余
  3. 归档中的时间槽位(time-slots)总是占据着磁盘空间,不管有没有值存储在其中

这些特征是故意的,主要出于性能方面的考虑。

Whisper与RRD的区别
  1. RRD不能去填充以前的时间槽位。这意味着每一条数据都必须是更新的,不会“补录”
  2. RRD不能很好的支持不规则的数据更新。如果RRD接收到一条数据,但是后续数据没有到来,则前一条数据可能丢失
安装与配置
检查并安装依赖
检查依赖
Shell
1
2
3
git clone https://github.com/graphite-project/graphite-web.git
graphite-web/check-dependencies.py
# 根据输出的提示来判断缺少哪些依赖,然后安装
安装依赖
Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
yum -y install python-devel     # Carbon 依赖于 Python Development Headers
 
yum install pycairo             # Cairo库的Python绑定
 
pip install django              # Web框架
pip install django-tagging
 
pip install pytz
 
yum install fontconfig
 
yum install -y memcached        # 可选,缓存支持
pip install python-memcached    
                                # 可选,RDDTool
yum install cairo-devel libxml2-devel pango-devel pango libpng-devel freetype freetype-devel libart_lgpl-devel rrdtool-devel
 
pip install python-rrdtool      # 可选,RRD支持
 
pip install whitenoise          # 用于Web静态文件处理
 
yum install pyOpenSSL           # OpenSSL的Python绑定
pip install service_identity    # SSL相关
通过pip安装Craphite组件
Shell
1
2
3
4
pip install https://github.com/graphite-project/ceres/tarball/master
pip install whisper
pip install carbon
pip install graphite-web
设置目录权限
Shell
1
2
3
4
5
sudo groupadd graphite
sudo usermod -a -G graphite root
sudo usermod -a -G graphite apache
sudo chgrp -R graphite /opt/graphite/storage
sudo chmod -R 770 /opt/graphite/storage
默认安装布局

Whisper被安装到Python全局site-packages目录,另外两个Graphite组件安装到 /opt/graphite,该目录(记为 $GRAPHITE_ROOT  )的布局如下:

子目录 说明
bin 一些脚本
conf 配置文件
lib 一些Python依赖库,Carbon的PYTHONPATH
storage 存储SQLite数据文件。该目录记为 $STORAGE_DIR 
storage/log Carbon和Graphite-web的日志
storage/rrd 待读取的RRD文件
storages/whisper Whisper数据文件
webapp

Graphite-web的Web资源、PYTHONPATH

webapp/graphite

标准的Django工程结构
local_settings.py所在位置

webapp/content 静态Web资源
配置Graphite-web数据库

你需要让Graphite-web的底层框架Django执行数据库的初始化。此数据库被用来存放用户设置、仪表盘,以及支持事件功能。

默认情况下,Graphite-web使用位于$STORAGE_DIR/graphite.db的SQLite数据库。如果要运行多个Graphite-web实例,则必须使用MySQL等数据库以便多个实例可以共享数据。 

配置SQLite

执行下面的命令初始化SQLite数据库:

Shell
1
2
PYTHONPATH=/opt/graphite/webapp django-admin.py migrate --settings=graphite.settings --run-syncdb
# 完毕后 $STORAGE_DIR/graphite.db自动创建

Django应用需要在Web服务器中运行,Web服务器需要对SQLite数据文件有读写权限。假设你使用Apache2,运行Apache2的用户为apache,则需要执行:

Shell
1
sudo chgrp graphite /opt/graphite/storage/graphite.db
配置WebApp
httplocal_settings.py

Graphite不建议修改settings.py,所有定制化的配置,都应该在此文件中进行。常用的设置项如下表:

设置项 说明
TIME_ZONE 时区,规范化的时区名称。默认America/Chicago
DEBUG 是否启用Django错误页面。默认False
FLUSHRRDCACHED 如果设置,在从RRD文件获取数据前,执行 rrdtool flushcached 
设置为rrdcached的地址或者Socket(例如unix:/var/run/rrdcached.sock)
MEMCACHE_HOSTS 如果设置,启用对计算出的目标、渲染过的图片的缓存。如果运行Graphite Web应用集群,则每个实例应当设置为一样的值
设置为memcached主机的数组,例如:['10.10.10.10:11211', '10.10.10.12:11211']
DEFAULT_CACHE_DURATION 数据、图片默认缓存时间。默认值60
DEFAULT_CACHE_POLICY 默认缓存策略。为元组的数组,每个元组指定最小查询时间、数据缓存时间
通过该设置,你可以让大的查询缓存更长时间。例如:
Python
1
2
3
4
DEFAULT_CACHE_POLICY = [
    (0, 60), # 默认缓存60秒
    (7200, 120) # >= 2小时以上时间范围的查询,缓存2分钟
] 
GRAPHITE_ROOT Graphite的安装目录。默认/opt/graphite 
CONF_DIR 额外Graphite-web配置文件目录。默认/opt/graphite/conf
STORAGE_DIR 存储目录。WHISPER_DIR、RRD_DIR、LOG_DIR、INDEX_FILE参照的基准目录
STATIC_ROOT Graphite-web的静态文件目录。默认/opt/graphite/static
该目录一开始会不存在,你需要在设置STATIC_ROOT、STATIC_URL后执行:
Python
1
2
3
4
# 如果报Unknown command: 'collectstatic' 说明INSTALLED_APPS中缺少
# django.contrib.staticfiles    
PYTHONPATH=/opt/graphite/webapp django-admin.py collectstatic
    --noinput --settings=graphite.settings

你还需要在Web服务器中把/static这个前缀映射到此目录,里Apache2为例:

1
Alias /static/ "/opt/graphite/static"

如果你安装了whitenoise包,静态文件可以直接由Graphite webapp来处理,不通过Web服务器

DASHBOARD_CONF 仪表盘的配置文件。默认$CONF_DIR/dashboard.conf
GRAPHTEMPLATES_CONF 图形模板的配置文件。默认$CONF_DIR/graphTemplates.conf 
WHISPER_DIR  Whisper数据文件目录。默认/opt/graphite/storage/whisper
RRD_DIR  RRD数据文件目录。默认/opt/graphite/storage/rrd
LOG_DIR  Graphite webapp的日志目录。默认$TORAGE_DIR/log/webapp
INDEX_FILE 搜索索引位置。默认/opt/graphite/storage/index
由build-index.sh脚本生成,运行Web应用的用户必须有写权限
URL_PREFIX URL前缀

我们的配置如下:

Python
1
2
# 如果不设置,会导致报错:AttributeError: 'Settings' object has no attribute 'URL_PREFIX
URL_PREFIX = '/'    
安装Apache和mod_wsgi

多种Web服务器可以用于运行基于Django的Web应用,这里我们选择Apache2。在CentOS下安装Apache2:

Shell
1
yum install httpd

要让Apache2能够运行Python Web应用,需要安装模块mod_wsgi。参考Django学习笔记完成mod_wsgi的构建与安装。

配置Graphite虚拟主机

在/opt/graphite/examples/目录下,example-graphite-vhost.conf可以作为Apache虚拟主机的模板,复制该文件到/etc/httpd/conf.d/目录下,然后修改:

graphite-vhost.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<IfModule !wsgi_module.c>
    LoadModule wsgi_module modules/mod_wsgi.so
</IfModule>
WSGISocketPrefix run/wsgi
<VirtualHost *:7767>
        ServerName xcentos7.local
        DocumentRoot "/opt/graphite/webapp"
        ErrorLog /opt/graphite/storage/log/webapp/error.log
        CustomLog /opt/graphite/storage/log/webapp/access.log common
        WSGIDaemonProcess graphite processes=5 threads=5 display-name='%{GROUP}' inactivity-timeout=120
        WSGIProcessGroup graphite
        WSGIApplicationGroup %{GLOBAL}
        WSGIImportScript /opt/graphite/conf/graphite.wsgi process-group=graphite application-group=%{GLOBAL}
        WSGIScriptAlias / /opt/graphite/conf/graphite.wsgi
        Alias /content/ /opt/graphite/webapp/content/
        <Directory /opt/graphite/webapp/content/>
            Require all granted
        </Directory>
        <Directory /opt/graphite/conf/>
            Require all granted
        </Directory>
</VirtualHost>
验证配置

如果配置没有问题,启动Web服务器后访问: http://GRAPHITE_HOST:GRAPHITE_PORT/render ,会显示一张330x250大小的图片,上面写着No Data。

配置Carbon

所有Carbon守护进程可以基于多种通信协议,监听时间序列数据,并且对数据进行不同的处理。

Carbon的配置文件位于/opt/graphite/conf/目录,默认情况下没有预置的配置文件,但是Graphite提供了若干配置文件样例。你可以复制这些配置文件并定制:

Shell
1
2
3
pushd /opt/graphite/conf
cp carbon.conf.example carbon.conf
cp storage-schemas.conf.example storage-schemas.conf
carbon.conf

这是主配置文件,为每个Carbon守护进程定义配置项。该配置文件按段区分不同守护进程的配置:

配置项段 配置项 说明
[cache]   

ENABLE_LOGROTATION

 是否启用每日的日志轮转,启用后每天创建一个日志

USER  运行该进程的用户 
MAX_CACHE_SIZE 内存中Metrics缓存的最大尺寸
MAX_UPDATES_PER_SECOND 每秒执行whisper的update_many()调用的最大次数,对应磁盘IO的次数,该配置项避免过度的磁盘使用
MAX_CREATES_PER_MINUTE 对每分钟最多创建的.wsp文件的个数进行软限制。超过限制的新Metrics对应的.wsp文件不会被创建,Metrics也被丢弃
LINE_RECEIVER_INTERFACE 接收文本格式数据的监听端口,默认0.0.0.0:2003
LINE_RECEIVER_PORT
PICKLE_RECEIVER_INTERFACE
接收Pickle格式数据的监听端口,默认0.0.0.0:2004
PICKLE_RECEIVER_PORT
ENABLE_UDP_LISTENER 是否启用UDP监听
UDP_RECEIVER_INTERFACE 通过UDP接收数据的监听端口,默认0.0.0.0:2003
UDP_RECEIVER_PORT
LOG_LISTENER_CONNECTIONS 对成功的连接请求记录日志
CACHE_QUERY_INTERFACE 缓存查询服务的监听端口,默认0.0.0.0:7002
CACHE_QUERY_PORT
USE_FLOW_CONTROL 是否进行流量控制。如果设置为True,那么达到MAX_CACHE_SIZE后,会暂停接收数据,直到缓存占用小于MAX_CACHE_SIZE的95%
CACHE_WRITE_STRATEGY 按何种顺序将缓存从内存中移除,并写入到磁盘的策略:sorted、max、naive
[relay] LINE_RECEIVER_INTERFACE

接收文本格式数据的监听端口,默认0.0.0.0:2003

LINE_RECEIVER_PORT
PICKLE_RECEIVER_INTERFACE 接收Pickle格式数据的监听端口,默认0.0.0.0:2004
PICKLE_RECEIVER_PORT
LOG_LISTENER_CONNECTIONS 对成功的连接请求记录日志
USER 运行该进程的用户
RELAY_METHOD

设置为rules:则该进程可以代替carbon-cache.py,然后中继所有Metrics给多个作为后端的carbon-cache.py

设置为consistent-hashing:则依据DESTINATIONS定义的分片策略,分发Metrics给多个作为后端的carbon-cache.py

REPLICATION_FACTOR RELAY_METHOD=consistent-hashing时,可以指定N,从而把每个数据点分发到N台机器
DESTINATIONS 转发的目标,每个目标的格式是IP:PORT
RELAY_METHOD=rules时relay-rules.conf每个servers都要在此字段定义
MAX_DATAPOINTS_PER_MESSAGE 单个转发报文中包含的数据点的最大个数
MAX_QUEUE_SIZE 待转发的队列最大包含多少数据点
QUEUE_LOW_WATERMARK_PCT 队列低水位的百分比,0-1之间
USE_FLOW_CONTROL 是否进行流量控制。如果设置为True,那么达到MAX_QUEUE_SIZE后,会暂停接收数据,直到转发队列低于QUEUE_LOW_WATERMARK_PCT
[aggregator]  LINE_RECEIVER_INTERFACE 接收文本格式数据的监听端口,默认0.0.0.0:2023
LINE_RECEIVER_PORT
PICKLE_RECEIVER_INTERFACE 接收Pickle格式数据的监听端口,默认0.0.0.0:2004
PICKLE_RECEIVER_PORT
LOG_LISTENER_CONNECTIONS 对成功的连接请求记录日志
USER 运行该进程的用户
FORWARD_ALL 如果设置为True,除了根据aggregation-rules.conf进行聚合外,还把原始数据转发给DESTINATIONS
DESTINATIONS 聚合后的数据发送到的地方
REPLICATION_FACTOR 如果设置为N,则把数据转发给N个DESTINATION
MAX_QUEUE_SIZE 待转发的队列最大包含多少数据点
USE_FLOW_CONTROL 是否进行流量控制。如果设置为True,那么达到MAX_QUEUE_SIZE后,会暂停接收数据,直到转发队列低于80%
MAX_DATAPOINTS_PER_MESSAGE 单个转发报文中包含的数据点的最大个数
MAX_AGGREGATION_INTERVALS 控制最多记住多少数据点,只有这些数据点才参与聚合
仅最近MAX_AGGREGATION_INTERVALS  * intervalSize秒内的数据点会被记住
storage-schemas.conf

这个配置文件用于定义Metrics的驻留率( retention rates)——即Metrics的数据点(datapoints)以什么频率保存,保存多长时间。关于该配置文件,需要注意:

  1. 该配置文件可以由多个段(Section)组成。每个段定义一个存储规则
  2. 这些规则按照从上到下的顺序对Metrics进行匹配,第一个匹配的规则对Metrics生效
  3. 匹配Metrics时,采用的是正则表达式
  4. 对于一个Metrics,其存储规则在接收到第一个数据时固化。因而修改此配置文件不会影响到既有的.wsp文件。要应用到既有的.wsp可以调用whisper-resize.py

每个规则由三个部分组成:

1
2
3
4
5
6
7
8
# 段名称(规则名称),主要是文档用途。在匹配段的Metrics被创建时,日志creates.log中会显示此名称
[rulename]
# 匹配Metrics路径(Metrics的全限定名称,点号分隔)的正则式
# 举例:^servers\.www.*\.workers\.busyWorkers$
pattern=regex
# 驻留率表达式,数据点间隔:存留天数,时间后缀s,m,h,d,y分别表示秒、分、小时、天、年
# 举例:10s:14d 表示每个数据点表示10秒(相当于每10秒采集数据一次),并且存储14天的数据
retentions=retention rate

注意,你可以指定多重驻留率表达式(retention rate),逗号分隔每个表达式。一般从最高精度:最短存留时间开始指定,直到最低精度:最长存留时间。例如: 15s:7d,1m:21d,15m:5y 表示7天内每15秒存留一个采样,而大于21天小于5年的则每15分钟一个采样。

设置多重驻留率表达式,可以在保存足够长时间的历史数据的前提下,尽量减少磁盘I/O和消耗的存储空间。当跨越驻留表达式的时间区间(上例中7天,21天)后,whisper会自动降低采样率(downsamples),默认算法是取平均值,可以通过storage-aggregation.conf定制聚合方式

storage-aggregation.conf

这个配置文件定义如何在降低采样率(转换为低精度存储时) 如何对数据进行聚合。该文件的格式与storage-schemas.conf类似:

1
2
3
4
5
6
[rulename]
pattern = rexexp
# 0-1之间的浮点数,默认0.5。聚合区间内的值,至少多少比例为非空,聚合后的值才是非空
xFilesFactor = 0.5
# 数据聚合方式,默认average
aggregationMethod = average | sum | min | max | last

同样的,修改此文件不会影响已经生成的.wsp文件, 要应用到既有的.wsp文件,可以调用whisper-set-aggregation-method.py。

relay-rules.conf

这个配置文件指定中继规则——即需要把何种Metrics转发给何种后端。中继由Carbon的中继进程负责执行。该文件格式如下:

1
2
3
[rulename]
pattern = regex
servers = ip:port,ip:port,...
aggregation-rules.conf

该配置文件定义聚合出来的Metrics——由几个Metrics聚合而成的新的Metrics。聚合由Carbon的聚合进程负责执行。

注意:这里的聚合storage-aggregation.conf提及的聚合不同。后者用于单一Metrics的降低采样,而前者用于生成新的Metrics。

与其它配置文件不同,该文件一旦更改,立即生效。

该文件的格式如下:

1
2
3
4
# 捕获任何匹配input_pattern的Metrics,使用method聚合成新的Metrics:output_template
# frequency:每隔多久执行一次聚合
# method:可选sum/avg
output_template (frequency) = method input_pattern

举例,假设你的Metrics的命名规则是:

1
<env>.applications.<app>.<server>.<metric>

这是你可以配置如下聚合规则,来计算所有应用程序的请求的总数:

1
<env>.applications.<app>.all.requests (60) = sum <env>.applications.<app>.*.requests

在此规则下,下面的Metrics:

1
2
3
4
test.applications.pems.221.request
test.applications.pems.6.request
test.applications.pems.5.request
test.applications.pems.201.request

会每个60秒求和并生成  test.applications.pems.all.request 的一个数据点。

rewrite-rules.conf 

该配置文件定义Metrics名称的改写规则。 与其它配置文件不同,该文件一旦更改,立即生效。该文件的格式如下:

1
2
3
4
5
[pre]
# pre段的规则,在接收到数据后立即执行改写
[post]
# post段的规则,在聚合完毕后执行改写
regex-pattern = replacement-text

 举例:

1
2
3
# \1表示第一个捕获,即[a-z0-9]+
^collectd\.([a-z0-9]+)\. = \1.system.
# collectd.prod.cpu-0.idle-time 会被改写为 prod.system.cpu-0.idle-item
whitelist.conf和blacklist.conf 

Carbon提供黑白名单功能。白名单:仅仅接受其中列出的Metrics;黑名单:拒绝其中列出Metrics。

要启用黑白名单功能,需要修改carbon.conf,设置 USE_WHITELIST = True 

启动Graphite

如何启动Graphite Webapp依赖于其运行的Web服务软件,以Apache为例:

Shell
1
2
# CentOS 7
systemctl restart httpd

Carbon组件需要执行下面的命令来启动:

Shell
1
/opt/graphite/bin/carbon-cache.py start

SQLite是一个“文件数据库”,不需要启动。如果Graphite Webapp使用其它数据库,例如MySQL,则需要启动之。 

向Graphite发送数据点
数据格式

你可以通过多种方式向Graphite(的Carbon组件)发送Metrics数据点。主要的三种数据格式是:Plaintext、Pickle、AMQP 

Plaintext协议

这种方式非常简单,你可以用如下格式来发送一条Metrics数据点:

1
2
3
<metric path> <metric value> <metric timestamp>
# 举例:
servers.zircon.cpu 85 1470303923

出于测试目的,你可以直接通过命令向Carbon发送Metrics数据:

Shell
1
2
3
PORT=2003
SERVER=127.0.0.1
echo "servers.zircon.cpu 85 `date +%s`" | nc ${SERVER} ${PORT}
Pickle协议

Pickle是Python下的对象串行化框架,Pickle协议即它的串行化格式协议。使用该协议,你可以一次发送多个Metrics,并且串行化后的数据比较紧凑,因此Pickle协议性能更好。

下面是构建Pickle报文的示例代码:

Python
1
2
3
4
5
6
7
8
listOfMetricTuples = [
    (path, (timestamp, value)),
    ...
]
payload = pickle.dumps(listOfMetricTuples, protocol=2)
header = struct.pack("!L", len(payload))
message = header + payload
# 然后通过Socket把message发送出去即可
客户端示例
简单Pickle客户端
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import pickle
import socket
import struct
import sys
import time
from time import sleep
 
import psutil
 
 
def get_cpu_load():
    load = psutil.cpu_percent()
    print load
    return load
 
 
if __name__ == '__main__':
    CARBON_HOST = '172.16.87.132'
    CARBON_PORT = 2004
    s = socket.socket()
    try:
        s.connect((CARBON_HOST, CARBON_PORT))
        while True:
            data = [
                ('servers.zircon.cpu', (time.time(), get_cpu_load()))
            ]
            pkg = pickle.dumps(data, 1)
            s.sendall(struct.pack('!L', len(pkg)))
            s.sendall(pkg)
            sleep(5)
    except socket.error:
        raise SystemExit("Failed to connect to %(host)s:%(port)" % {'host': CARBON_HOST, 'port': CARBON_PORT})
    except KeyboardInterrupt:
        sys.stderr.write("\nExiting on CTRL-C\n")
        sys.exit(0) 
从Graphite获取数据

要从Graphite获取数据用于展示,可以使用Graphite Webapp暴露的Render URL API(RUA)。你可以通过

1
http://GRAPHITE_HOST:GRAPHITE_PORT/render

访问此API。要向RUA传递参数,可以使用URL请求参数方式: &name=value 。注意大部分的参数名、函数名是大小写敏感的。

下面列出几个RUA的URL示例:

Shell
1
2
3
4
5
6
# Zircon的CPU负载图,获取800x600的图片
http://graphite/render?target=servers.zircon.cpu&height=800&width=600
# 最近12小时,所有服务器的CPU负载平均值
http://graphite/render?target=averageSeries(servers.*.load)&from=-12hours
# 获取原始数据而不是图片,JSON格式
http://graphite/render?target=servers.zircon.cpu&format=json
target参数

该参数用来指定从何处获取数据,你可以指定:

  1. 单个Metrics路径
  2. 带有通配符的的Metrics路径,匹配多个Metrics
  3. 函数调用,针对作为入参的Metrics进行各种转换、合并操作
通配符

你可以在路径中使用三种风格的通配符:

  1. * 可以匹配0-N个字符,例如 servers.dev-*.cpu ,可以匹配所有开发服务器的CPU负载Metrics。
  2. [...] 可以匹配列表中枚举的单个字符,例如 servers.dev-[a-z0-9].cpu ,可以匹配dev-0、dev-1等服务器的CPU负载Metrics。
  3. {...} 可以匹配列表中枚举的单个字符串,例如 servers.{dev-0,dev-1}.cpu ,匹配dev-0、dev-2的CPU负载Metrics。

注意:所有通配符都不能跨越点号。 

template函数

你可以指定target为template函数调用,从而在Metrics路径中使用变量,例如:

1
2
3
4
5
6
7
8
9
# $varname 用来声明变量占位符
# template[varname]参数用来传递变量值
&target=template(servers.$servername.cpu)&template[servername]=zircon
 
# 可以使用数字代替变量名
&target=template(servers.$1.cpu)&template[1]=zircon
 
# template可以内嵌其它函数
&target=template(constantLine($number))&template[number]=123
所有函数

可用的函数较多,这里不一一列举说明,参见官方文档。

from/until参数

这两个可选参数用来指定相对或者绝对的时间区间(time period)。from表示区间起点,如果忽略,默认值是24小时之前;until表示区间终点,如果或略,默认值是当前时间点。

相对时间

如果要使用相对时间,需要加上 - 前缀(负号),后面跟着数值和时间单位。时间单位包括:

时间单位 说明
s 秒
min 分钟
h 小时
d 天
w 周
mon 月(30天)
y 年(365天)
绝对时间

你可以指定 HH:MM_YYYYMMDD 、 YYYYMMDD 、  MM/DD/YY 等格式的时间绝对值。

format参数

该参数用来指定要获取的数据的格式。 支持以下取值:

格式 说明
png 根据指定的width、height,直接把数据渲染为PNG图片
raw 原始数据,分为多行,每行格式为:
1
<target name>,<start timestamp>,<end timestamp>,<series step>|[data]*

 示例:

1
entries,1311836008,1311836013,1|1.0,2.0,3.0,5.0,6.0
csv 基于逗号分隔符的格式,每行表示一个数据点。示例:
1
2
3
4
5
entries,2011-07-28 01:53:28,1.0
entries,2011-07-28 01:53:29,2.0
entries,2011-07-28 01:53:30,3.0
entries,2011-07-28 01:53:31,5.0
entries,2011-07-28 01:53:32,6.0
json

JSON数组格式,示例:

JavaScript
1
2
3
4
5
6
7
8
9
10
[{
  "target": "entries",
  "datapoints": [
    [1.0, 1311836008],
    [2.0, 1311836009],
    [3.0, 1311836010],
    [5.0, 1311836011],
    [6.0, 1311836012]
  ]
}]

可以和jsonp参数联用,以便把数据包装成函数调用,进行跨域请求

可以和maxDataPoints参数联用,限定最大的数据点个数。超过数量的数据点将被压缩掉

可以和noNullPoints参数联用,移除所有Null值的数据点

svg 渲染为SVG图片格式
pdf 渲染为PDF文档
dygraph dygraphs是一个快速、灵活的JavaScript图表(Chart)库。该格式返回dygraphs支持的数据格式。示例:
JavaScript
1
2
3
4
5
6
7
8
9
10
{
  "labels" : [
    "Time",
    "entries"
  ],
  "data" : [
    [1468791890000, 0.0],
    [1468791900000, 0.0]
  ]
}
rickshaw rickshaw是一个简单的JavaScript图表库。该格式返回rickshaw支持的数据格式。示例:
JavaScript
1
2
3
4
5
6
7
8
9
10
[{
  "target": "entries",
  "datapoints": [{
    "y": 0.0,
    "x": 1468791890
  }, {
    "y": 0.0,
    "x": 1468791900
  }]
}]
pickle 返回Pickle串行化格式,设置MIME类型为application/pickle。反串行化后的对象示例:
Python
1
2
3
4
5
6
7
8
9
[
  {
    'name' : 'summarize(test.data, "30min", "sum")',
    'start': 1335398400,
    'end'  : 1335425400,
    'step' : 1800,
    'values' : [None, None, 1.0, None],
  }
]
图形参数

你可以指定多个参数,来控制生成的图形的样式:

参数 说明
areaAlpha 启用areaMode时,填充区域的透明度。0-1之间的浮点数
areaMode 填充曲线与X轴之间的区域,形成Area图,可以取值:
none 不进行填充
first 填充第一个目标
all  填充所有目标
stacked 堆叠模式,填充所有目标,一个目标的取值为前面所有其它目标的取值+该目标的取值
bgcolor 背景颜色。示例:
1
2
3
4
5
6
# 颜色名称
&bgcolor=blue
# HEX代码
&bgcolor=2222FF
# HEX代码,包含透明度
&bgcolor=5522FF60
cacheTimeout 被渲染出的图形,其有效缓存时间
colorList 多个Target时,每个Target的颜色,逗号分隔颜色代码
drawNullAsZero 是否把空值渲染为0
fontBold 是否使用粗体
fontItalic 是否使用斜体
fontName 字体名称,该字体必须安装在Graphite服务器上
fontSize 字体大小,大于1的浮点数
graphOnly 是否不显示网格线、X/Y轴和图例
graphType 图表类型,line或者pie
hideLegend 是否隐藏图例
hideAxes 是否隐藏X/Y轴
hideXAxis
hideYAxis
hideGrid 是否隐藏网格线
height 图形的高度、宽度,单位像素
width
leftColor 在双Y轴模式下,设置与左轴关联的Metrics的颜色
rightColor 在双Y轴模式下,设置与右轴关联的Metrics的颜色
leftDashed 在双Y轴模式下,是否以虚线绘制与左轴关联的Metrics
rightDashed 在双Y轴模式下,是否以虚线绘制与右轴关联的Metrics
leftWidth 在双Y轴模式下,设置与左轴关联的Metrics的线条宽度
rightWidth 在双Y轴模式下,设置与右轴关联的Metrics的线条宽度
lineMode 设置线条绘制的行为:
slope:从一个数据点向下一个数据点绘制斜线,Null值的区间不被绘制
connected:与slope类似,但是数据点总是被连接起来,无论它们之间是否存在Null值
staircase:绘制直方图
lineWidth 线条的宽度
majorGridLineColor 网格线主色
minorGridLineColor 网格线从色
minorY 每两个网格主线之间,有几个从线,Y方向
margin 图形四周的边距
maxDataPoints 使用
minXStep

两个连续的数据点之间,间隔的最小像素

如果数据点过多,则压缩,以满足此配置

noCache 禁止图片缓存
pieLabels 饼图标签如何显示,horizontal或者rotated
pieMode 饼图聚合方式:
average,取series中非空数据点的平均值
maximum,取series中非空数据点的最大值
minimum,取series中非空数据点的最小值
valueLabels 如何显示饼图分块的标签:
none,不显示
numbers,显示原始值
percent,显示百分比
valueLabelsColor 如何显示饼图分块的标签的颜色
valueLabelsMin 饼图中,分块占比小于此数值的分块,不显示其标签
title 在图形顶端显示的标题
vtitle Y轴标题,垂直显示
vtitleRight 双Y轴模式下,右Y轴的标题
tz 用于显示时间值的时区
展示Graphite数据

上一章内容我们讨论了如何获取Graphite数据。通过Render URL API,我们不但可以获得文本数据,还可以直接获得渲染好的图片。这意味着通过Render URL API本身就可以实现Metrics的渲染,你只需要把生成的图片嵌入到自己的应用程序中即可。

Graphite Webapp本身提供了基于ExtJS的一个管理界面,你可以通过 http://GRAPHITE_HOST:GRAPHITE_PORT/admin 浏览Metrics。

Graphite生成的Metrics曲线的图片,不是非常美观,而静态图片也缺乏交互性。因此,实际项目中常常结合使用第三方基于JavaScript的Charts库来做展示,例如:

  1. Grafana:UI比较绚丽,支持设计仪表盘、时间区间联动。参见:使用Grafana展示时间序列数据
  2. Graphene:一个较为简单的,基于D3.js和Backbone.js的Graphite仪表盘工具
Graphite事件

除了简单的,基于Key/Value的Metrics数据,Graphite还可以存储、展示随机出现的数据——事件。

事件不适合存储在Whisper中,因此它被存储在Graphite的Webapp的数据库中(默认使用SQLite)。

发布事件

通过向 http://GRAPHITE_HOST:GRAPHITE_PORT/events/ 发送POST请求,即可发布Graphite事件。事件使用JSON格式编码在请求体中:

JavaScript
1
2
3
4
5
{
    "what": "事件类型",
    "tags": "标签",
    "data": "事件相关的数据"
}
查询事件

指定target为 event(*tags) 函数调用,即可通过 /render 查询事件,例如

http://graphite/render/?target=events('mytag')&format=json
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[
   {
      "target" : "events(mytag)",
      "datapoints" : [
         [
            1,
            1388966651
         ],
         [
            3,
            1388966652
         ]
      ]
   }
]

你也可以通过 /render/events/get_data 获得原始的事件数据,例如:

http://graphite/render/events/get_data?tags=mytag&from=-3hours&until=now
1
2
3
4
5
6
7
8
9
[
   {
      "when" : 1392046352,
      "tags" : "mytag",
      "data" : "...",
      "id" : 2,
      "what" : "Event - deploy"
   }
] 
常见问题
AttributeError: 'WSGIRequest' object has no attribute 'REQUEST'

Django的request对象曾经有一个属性REQUEST,用来获得通过GET或者POST请求传递的请求参数,在1.9版本中此属性已经移除。

Graphite代码没有即时更新,存在不兼容的问题,修改一下即可:

/opt/graphite/webapp/graphite/render/views.py
Python
1
2
def parseOptions(request):
   queryParams = request.GET # request.REQUEST已经被移除

还有很多其它views.py存在同样的问题,最好搜索一下一并修改。如果觉得麻烦可以安装兼容版本的Django:

Python
1
pip install django==1.8.14

 

 

← Jenkins知识集锦
2016年7月大连 →

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Related Posts

  • 使用Grafana展示时间序列数据
  • Shinken学习笔记
  • Prometheus学习笔记
  • OpenTSDB学习笔记
  • InfluxDB学习笔记

Recent Posts

  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
  • A Comprehensive Study of Kotlin for Java Developers
  • 背诵营笔记
  • 利用LangChain和语言模型交互
  • 享学营笔记
ABOUT ME

汪震 | Alex Wong

江苏淮安人,现居北京。目前供职于腾讯云,专注容器方向。

GitHub:gmemcc

Git:git.gmem.cc

Email:gmemjunk@gmem.cc@me.com

ABOUT GMEM

绿色记忆是我的个人网站,域名gmem.cc中G是Green的简写,MEM是Memory的简写,CC则是我的小天使彩彩名字的简写。

我在这里记录自己的工作与生活,同时和大家分享一些编程方面的知识。

GMEM HISTORY
v2.00:微风
v1.03:单车旅行
v1.02:夏日版
v1.01:未完成
v0.10:彩虹天堂
v0.01:阳光海岸
MIRROR INFO
Meta
  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
Recent Posts
  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
    In this blog post, I will walk ...
  • A Comprehensive Study of Kotlin for Java Developers
    Introduction Purpose of the Study Understanding the Mo ...
  • 背诵营笔记
    Day 1 Find Your Greatness 原文 Greatness. It’s just ...
  • 利用LangChain和语言模型交互
    LangChain是什么 从名字上可以看出来,LangChain可以用来构建自然语言处理能力的链条。它是一个库 ...
  • 享学营笔记
    Unit 1 At home Lesson 1 In the ...
  • K8S集群跨云迁移
    要将K8S集群从一个云服务商迁移到另外一个,需要解决以下问题: 各种K8S资源的迁移 工作负载所挂载的数 ...
  • Terraform快速参考
    简介 Terraform用于实现基础设施即代码(infrastructure as code)—— 通过代码( ...
  • 草缸2021
    经过四个多月的努力,我的小小荷兰景到达极致了状态。

  • 编写Kubernetes风格的APIServer
    背景 前段时间接到一个需求做一个工具,工具将在K8S中运行。需求很适合用控制器模式实现,很自然的就基于kube ...
  • 记录一次KeyDB缓慢的定位过程
    环境说明 运行环境 这个问题出现在一套搭建在虚拟机上的Kubernetes 1.18集群上。集群有三个节点: ...
  • eBPF学习笔记
    简介 BPF,即Berkeley Packet Filter,是一个古老的网络封包过滤机制。它允许从用户空间注 ...
  • IPVS模式下ClusterIP泄露宿主机端口的问题
    问题 在一个启用了IPVS模式kube-proxy的K8S集群中,运行着一个Docker Registry服务 ...
  • 念爷爷
      今天是爷爷的头七,十二月七日、阴历十月廿三中午,老人家与世长辞。   九月初,回家看望刚动完手术的爸爸,发

  • 6 杨梅坑

  • liuhuashan
    深圳人才公园的网红景点 —— 流花山

  • 1 2020年10月拈花湾

  • 内核缺陷触发的NodePort服务63秒延迟问题
    现象 我们有一个新创建的TKE 1.3.0集群,使用基于Galaxy + Flannel(VXLAN模式)的容 ...
  • Galaxy学习笔记
    简介 Galaxy是TKEStack的一个网络组件,支持为TKE集群提供Overlay/Underlay容器网 ...
TOPLINKS
  • Zitahli's blue 91 people like this
  • 梦中的婚礼 64 people like this
  • 汪静好 61 people like this
  • 那年我一岁 36 people like this
  • 为了爱 28 people like this
  • 小绿彩 26 people like this
  • 彩虹姐姐的笑脸 24 people like this
  • 杨梅坑 6 people like this
  • 亚龙湾之旅 1 people like this
  • 汪昌博 people like this
  • 2013年11月香山 10 people like this
  • 2013年7月秦皇岛 6 people like this
  • 2013年6月蓟县盘山 5 people like this
  • 2013年2月梅花山 2 people like this
  • 2013年淮阴自贡迎春灯会 3 people like this
  • 2012年镇江金山游 1 people like this
  • 2012年徽杭古道 9 people like this
  • 2011年清明节后扬州行 1 people like this
  • 2008年十一云龙公园 5 people like this
  • 2008年之秋忆 7 people like this
  • 老照片 13 people like this
  • 火一样的六月 16 people like this
  • 发黄的相片 3 people like this
  • Cesium学习笔记 90 people like this
  • IntelliJ IDEA知识集锦 59 people like this
  • 基于Kurento搭建WebRTC服务器 38 people like this
  • Bazel学习笔记 37 people like this
  • PhoneGap学习笔记 32 people like this
  • NaCl学习笔记 32 people like this
  • 使用Oracle Java Mission Control监控JVM运行状态 29 people like this
  • Ceph学习笔记 27 people like this
  • 基于Calico的CNI 27 people like this
Tag Cloud
ActiveMQ AspectJ CDT Ceph Chrome CNI Command Cordova Coroutine CXF Cygwin DNS Docker eBPF Eclipse ExtJS F7 FAQ Groovy Hibernate HTTP IntelliJ IO编程 IPVS JacksonJSON JMS JSON JVM K8S kernel LB libvirt Linux知识 Linux编程 LOG Maven MinGW Mock Monitoring Multimedia MVC MySQL netfs Netty Nginx NIO Node.js NoSQL Oracle PDT PHP Redis RPC Scheduler ServiceMesh SNMP Spring SSL svn Tomcat TSDB Ubuntu WebGL WebRTC WebService WebSocket wxWidgets XDebug XML XPath XRM ZooKeeper 亚龙湾 单元测试 学习笔记 实时处理 并发编程 彩姐 性能剖析 性能调优 文本处理 新特性 架构模式 系统编程 网络编程 视频监控 设计模式 远程调试 配置文件 齐塔莉
Recent Comments
  • qg on Istio中的透明代理问题
  • heao on 基于本地gRPC的Go插件系统
  • 黄豆豆 on Ginkgo学习笔记
  • cloud on OpenStack学习笔记
  • 5dragoncon on Cilium学习笔记
  • Archeb on 重温iptables
  • C/C++编程:WebSocketpp(Linux + Clion + boostAsio) – 源码巴士 on 基于C/C++的WebSocket库
  • jerbin on eBPF学习笔记
  • point on Istio中的透明代理问题
  • G on Istio中的透明代理问题
  • 绿色记忆:Go语言单元测试和仿冒 on Ginkgo学习笔记
  • point on Istio中的透明代理问题
  • 【Maven】maven插件开发实战 – IT汇 on Maven插件开发
  • chenlx on eBPF学习笔记
  • Alex on eBPF学习笔记
  • CFC4N on eBPF学习笔记
  • 李运田 on 念爷爷
  • yongman on 记录一次KeyDB缓慢的定位过程
  • Alex on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • haolipeng on 基于本地gRPC的Go插件系统
  • 吴杰 on 基于C/C++的WebSocket库
©2005-2025 Gmem.cc | Powered by WordPress | 京ICP备18007345号-2