其实不太想用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里面,用那个看更漂亮一点。