其实不太想用 opentsdb, 一直以来用 influxdb+grafana 挺方便的, 而且 tsdb 依赖 hbase, 虽说容量和速度有保证, 但是分布式系统对于一个监控平台来说, 终归还是有些重了, 出问题定位更繁琐, 但领导说用那就用吧.
在这里必须吐一下 OpenTSDB 和 Tcollector 的文档更新, 太落后, 看官方文档根本找不到配置文件的位置. 最后还得看源码, 尤其是 TCollector, 这个 tsdb 官方推出的数据采集器. 不光文档落后, 除了核心, 周边辅助的代码也落后. 而且插件方式设计的各种数据收集器太奇葩了, 运行不了就狂报错.
安装 tsdb 还是比较方便的, 找一台 hbase 的 regionserver 直接 rpm 就可以. 主要是搞了 tcollector 以后排错, 不过问题主要是在 tcollector 上, 不赖 tsdb.
不过 tsdb 装完以后, 需要自己运行一个脚本叫 create_table.sh 来在 hbase 里创建 tsdb 需要的表. 这块坑了我几分钟, 安装官方文档的说法, 创建表格时采用何种压缩方式并不重要, 然后运行脚本, 半个小时表都没创建起来, 脚本默认会采用 LZO 方式选择压缩, 就是建不起来, 必须在命令行写 env COMPRESSION='NONE' ... 才可以. 不过我这集群是支持 lzo 的啊. 不过跟 tcollector 相比, 这就不算事.
tsdb 的配置也算简单, 就不细说了.
tcollector 是 opentsdb 官方推出的数据采集器, 符合个人开源风格, 文档长期不更新. 参看官方文档硬是找不到在哪配置能访问 opentsdb, 文档写的文件根本在代码里不存在, 只能翻源码.
tcollector 安装也不复杂, 自带一个 rpm 的打包 Makefile, 直接 make rpm 就可以打包成 rpm, 然后放到 repo 里面 yum 安装即可, 主要问题是安装以后跑起来没数据.
那就开始排错吧, 首先确定 opentsdb 能不能接收到数据. 停掉 tsdb, 用 nc -l 4242 启动一个 TCP Server, 监听在原 tsdb 的端口上, 然后启动 tcollector,nc 接收到一个 version, 然后就没了. 好吧, 去看 tcollector 的源码.
- # we use the version command as it is very low effort for the TSD
- # to respond
- LOG.debug('verifying our TSD connection is alive')
- try:
- self.tsd.sendall('version\n')
- except socket.error, msg:
- self.tsd = None
- self.blacklist_connection()
- return False
嗯, version 其实是相当于发送一个 ping 命令, 如果没有响应, 就把服务器放到黑名单里. 我不明白, 往单一服务器发送的程序, 要黑名单干什么.
继续 nc -l, 收到 version 给个响应.
收到 version 以后, 直接在 nc 控制台里打 2, 随便给个响应就行, 立刻数据就上来了. 好吧, tcollector 发送数据其实没问题, 那问题一定是在 tsdb 这边了.
打开 tsdb 的日志, 没有任何报错.
打开 /etc/opentsdb/logback.xml 将日志等级从 INFO 提升为 DEBUG,opentsdb 采用 slf4j 作为日志记录.
- <root level="DEBUG">
- <!-- <appender-ref ref="STDOUT"/> -->
- <appender-ref ref="CYCLIC"/>
- <appender-ref ref="FILE"/>
- </root>
重启 tsdb, 再去看日志, 来了.
16:58:27.470 DEBUG [PutDataPointRpc.execute] - put: unknown metric: No such name for 'metrics': 'tcollector.reader.lines_collected'
说 hbase 的 tsdb 表里没有 metrics 这个列名, 翻看官方文档, 有个配置叫
tsd.core.auto_create_metrics = true
默认是 false, 设置成 true 以后重启 tsdb, 数据进入 hbase, 没有问题了.
不过数据进到 hbase 里面又出现一个问题, 没有 cpu 的度量信息, 看源码得知 cpu 信息在 collector 里面的 sysload.py 里面, 不过翻看 Makefile 打包出来的 rpm, 里面不包含这个文件. 没办法, 接着回去看 tcollector 的 Makefile 和 rpm 的 spec 文件, 顺手修复了一下 centos6 下的 bug.
Makefile 倒是没看出什么问题, 几个选项, all, rpm, clean, distclean, swix, 分别对应 make all, make rpm, make clean 等, 那应该就是在 spec 文件里面了.
果然, spec 文件的第一个问题是 rpm 调用的 python 被硬指向了 python 2.7, 而 centos6 里面是没有 2.7 的, 顺手改之.
%global py2_sitelib /usr/lib/python2.6/site-packages
第二个问题, 安装的插件指向的是具体文件.
- %files collectors
- %{tcollectordir}/collectors/0/dfstat.py
- %{tcollectordir}/collectors/0/ifstat.py
- %{tcollectordir}/collectors/0/iostat.py
- %{tcollectordir}/collectors/0/netstat.py
- %{tcollectordir}/collectors/0/procnettcp.py
- %{tcollectordir}/collectors/0/procstats.py
- %{tcollectordir}/collectors/0/smart_stats.py
所以结果是这几个文件才会被打包到 rpm, 这明显是主要代码更新了, 而周边辅助的代码没更新导致的.
不过改成 * 是不优雅的, 因为有些新增的插件因为调用依赖问题, 启动后会一直报错, 所以, 需要根据具体需求来执行都安装哪些插件, 所以, 从这一点上说, 这部分代码的产品化程度还远远不够, 最起码要做出插件判断啊, 缺少依赖就别运行了.
更新了 spec, 重新打包, 需要的数据就都进入 hbase 了.
而 tcollector 的配置是最大的槽点, 放到最后压轴来说, 根据官方文档, 理应有一个 startstop 脚本, 将上报服务器配置为 opentsdb 的服务器, 结果源码里死都找不到这个 startstop 脚本. 然后通过阅读源码得知, 他娘的核心配置文件是放在插件文件夹里的, 这思路, 简直是灾难啊. 在 tcollector/collectors/etc/config.py 里面, 其实并不复杂, 但是比较烦人.
- defaults = {
- 'verbose': False,
- 'no_tcollector_stats': False,
- 'evictinterval': 6000,
- 'dedupinterval': 300,
- 'deduponlyzero': False,
- 'allowed_inactivity_time': 600,
- 'dryrun': False,
- 'maxtags': 8,
- 'max_bytes': 64 * 1024 * 1024,
- 'http_password': False,
- 'reconnectinterval': 0,
- 'http_username': False,
- 'port': 4242,
- 'pidfile': '/var/run/tcollector.pid',
- 'http': False,
- 'http_api_path': "api/put",
- 'tags': [],
- 'remove_inactive_collectors': False,
- 'host': 'to.your.opentsdb.server',
- 'backup_count': 1,
- 'logfile': '/var/log/tcollector.log',
- 'cdir': default_cdir,
- 'ssl': False,
- 'stdin': False,
- 'daemonize': False,
- 'hosts': False
- }
嗯, 这是我目前逛街发现的最坑的有公司维护的开源代码了, 设计出这个代码结构的工程师应该拉出去枪毙半小时. 浪费我 2 小时宝贵的撸码时间装这破玩意.
然后, 我发现我司有一台服务器上面是有 tcollector 的代码的, 文件创建时间是 15 年, 那会我还没来, 说明其实我司早就调研过这个, 但是一直没搞起来可能, 这东西没多难, 但是文档确实坑人.
感觉产品设计, 从来就不是互联网码农的强项, 快速开发实现功能就行了, 从不考虑产品化工程化代码结构优化的问题.
最后, 领导愿意看用 gnuplot 画的图我也就不说什么了. 我还是把 opentsdb 作为数据源接入到 grafana 里面, 用那个看更漂亮一点.
来源: http://blog.51cto.com/slaytanic/2119612