`

Graphite的百万Metrics实践之路

阅读更多

Graphite作为Metrics界的大哥

  • 它是RRDTool的Network Service版,和RRD一样支持Metrics的精度递减,比如一天之内10秒一条,7天之内聚合到1分钟一条,一年之内聚合到1小时一条。
  • 它支持丰富的查询函数,从简单的min/max/avg/sum 到 rate、top N等等,以Restful API提供。
  • 它有整个生态圈的插件支持,而且简单的TCP Plain Text协议,自己来插入数据也很简单。
  • 它有漂亮的DashBoard -- Grafana
  • 它有完整的HA和Scalable 方案 -- Carbon-Relay
  • 它有数据预聚合方案 -- Carbon-Aggregator

上面的一切,都只靠配置文件就能搞定, 不需要编一行代码。

但是,等你在服务器、应用的监控之外,真的将海量的业务Metrics也交给它,想不写一行代码就赚回一个看起来不错的报表系统时,问题来了。

 

百万Metrics......

每个Metrics在硬盘里都是一个文件。metrics的个数,最大估算值是所有维度大小的乘积,维度的增加让文件的个呈量级的增加。

写入的时候,依赖于Graphite自己很自豪的架构:Cluster Sharding分摊每台服务器上的Metric个数以及Carbon-Cache里的延时聚合批量写入同一个文件的机制持,对百万Metrics的支持并不困难。(唯一问题就是如果Carbon-Cache崩了,内存中未写入的数据会丢失)

但查询的时候......如果Dashboard里看的并不是某一个Metrics,而是某些维度下的一个合计,每次查询可能动不动都要打开上万个文件,就是件痛苦的事情。

解决方法之一是使用Carbon-Aggregator,像我们在报表系统里常做的那样,先做一些维度下的聚合。

比如,计数器只在每台Web服务器的内存里累加,metrics nam就是 traffic.server1.userlogin.count,因为我们只关心总用户登录数,就将20台server的数据聚合在一起,形成traffic.all.userlogin.count再发给carbon-cache,而原来属于每台server的记录则丢弃掉不再往后传,这样我们就少了20倍的metrics数量。

又比如 我们有时候会专门看某个app的使用情况,有时候又想看全部app的情况,则可以既新增一条allApp的聚合数据,也保留每一条app的数据。

好,铺垫完了。

 

读取百万Metrics时的真正问题

真正的问题1:carbon-aggregator是python写的基于Twisted的应用,见鬼的GIL问题,居然只能用到单核CPU。有时候单CPU核根本不够用。在Java里完全没想过会遇到的问题,别人说多核编程的时候总是很茫然,本来就多核的呀。。。。

真正的问题2:有些无法预先聚合的场景,比如要从2000个app中找出使用量最大的5个,则必须打开2000个app对应的全部文件。

真正的读取问题3: Sharding之后,查询时需要聚合多台服务器的结果,比如数据分布在三台机器上,第一台机命中了100个metrics,平均值是3;第二台命中了20个,平均值是2;第三台命中了10个,平均值是1。
首先决不能把三个平均值做平均。像MysqlCluster那种会做执行计划分析的,会只要求每台机上传sum 和 count 一共6条数据。但Graphite做不到这一点,只能让每台机把命中的metrics即130条数据都传上来。在0.9.12版中,如何批量上传数据还是个问题,在始终不肯发布的0.9.13 Snapshot版里此问题总算解决了。
但计算聚合时,再次遇到Python的单CPU核问题......

Graphite作者在宣布支持百万Metrics的时候,好像很少考虑这些问题。
 

要抛弃Graphite么?

现在,坚定一下继续留在Graphite的决心。能掀桌子把Graphite干掉吗? 一个选型的借鉴是Grafana作者合伙创业开的公司Raintank,它提供一个关于Metrics的SAAS平台,看the promising KairosDB 与influxdb: first impressions这两篇博客,也没太好的能下定决心的选择。

1. OpenTSDB
基于HBase,不支持RRD风格的数据精度递减,函数有限比如根本就没有Top N这种功能,运维复杂。

2. Kairosdb
基于Cassandra,8个月没更新了,似乎很不活跃。因为是从OpenTSDB fork出来的,所以不支持RRD与函数有限的问题依然在。

3. InfluxDB
用Go语言编写,是我最看好的一个alternative。但看好它快一年半了,还是没有成熟。最过份是,0.8版与还没发布的0.9版之间,居然几乎是重写。关于Cluster的文档也没写好让人不清楚底细。而且依然不支持RRD,只支持数据超过某个时间段就直接删除。

所以,近期还是留在Graphite吧,继续讨论优化吧。

 

可选的优化方法列表

两份有用的参考资料:

还有一个增强信心的案例,Booking.com(携程网的山寨对象),经过改造的Graphite,支持90台Server,50TB数据的方案。

1. 使用SSD

因为要写入和读取大量不同的文件,用SSD无疑会快很多。
但SSD的价格贵,而且Booking.com的视频里也说。在频繁读写下,一块SSD盘的寿命也就一年半。

2. 使用pypy代替python
看官方数据speed.pypy.org,twisted_tcp中比CPython快3倍,一快解千愁,可缓解很多问题了。

Python把py文件编译成字节码(pyc文件),再交给PVM执行,就像Java的JVM一样。但PVM没有JIT,每次都要把字节码翻译成机器码再执行,而JVM可以把解释后机器码保存下来。pypy提供了JIT,让Ruby社区一片羡慕。

3. 接受现实,减少数据精度

比如最初的一天之内就不要10秒一条记录了,降到30秒或一分钟,大大减少relay,aggregate, 写入的压力和文件的大小。

4. 使用Carbon-Agggrator方案做预聚合

Aggregator能减少不必要的存储,预聚合某些维度,见前。

5. 处理Carbon-Aggrator/Carbon-Relay的单CPU瓶颈

方法1: 前面提到的pypy应该有帮助。

方法2: 如果瓶颈是在carbon-replay,Booking.com用C重写的carbon-c-relay (但暂时用链表存储所有要聚合的Metrics,Metrics数量多时也会搞爆CPU的问题,作者在改),或者这个用Go重写的carbon-relay-ng,都是很活跃很值得尝试的项目。

方法3: 如果不想有任何改变,那多开几个carbon-aggregator,每个aggreator只负责少量的规则,甚至sharding出几个aggreator来完成同一条规则(如果该规则允许分区的话),aggregator会为每个要在聚合后吐出来的Metrics建立一个任务,用LoopingCall不断调用,所以要吐出的Metrics数量进行拆分。部署结构越来越复杂了。。。

6. Sharding

Sharding能减少每个节点上要读写文件的数量,Graphite作者预订的方案。

7. 处理Graphite-Web聚合Sharding时的单CPU瓶颈

暂时无法解决。只能期待前面pypy的提升。

Booking.com提供全套用go重写的方案,carbonserver, carbonzipper,carbonapi一起连用,它们都是重新实现了Graphite各部件的功能,但改动好像太大了,暂不推荐。

8. 最后一招,后台预查询预cache数据
可能有些慢查询要30秒才出结果,那就预先在后台查询一次,cache在Graphite-Web说连接的Memcached里。不过这时就只支持一些固定的时间段,不能支持last 15 minutes这种相对时间了。

其他优化

1. 将Whisper存储换成其他backend方案

用Cassandra的graphite-cyanite,Vimeo的同学写的用Influxdb的graphite-influxdb, 但看起来都不成熟也没多少用户,不敢试。

2. 将Graphite-Web换成Graphite-Api

Graphite-Api与Graphite-Web相比,少了用户管理,数据库与PNG渲染,只保留最核心的Query功能,而且有自己的一套plugin架构,比如raintank就写了个Kairosdb的backend

小结

InfluxDB真正超车之前,我们仍将尝试各种优化,继续实现我们不写一行代码,光靠配置获得一个不错的报表系统的愿望。

 

转自:http://calvin1978.blogcn.com/articles/graphite.html

ps:写得很棒

 

分享到:
评论

相关推荐

    yammer metrics-2.2.0 源码

    12. **Integration with Monitoring Systems**:yammer metrics可以与各种监控系统(如Graphite、Cassandra、Elasticsearch等)集成,将指标数据持久化并进行可视化分析。 通过深入研究yammer metrics-2.2.0的源码...

    metrics-poc:一个测试指标和监控工具(如logstash statsd Graphite Grafana)的游乐场

    标题中的“metrics-poc”指的是一个用于测试和评估指标及监控工具的项目,它是一个...通过实践,你可以深入了解这些工具的优缺点,以及它们在不同场景下的适用性,这对于提升系统的监控能力和故障排查能力非常有帮助。

    Metrics-In-Action:汪文君的Metrics系列课程的源码,课程请在淘宝检索“心蓝说Java”购买

    3. **报告与可视化**:探讨如何将Metrics数据定期报告给如Graphite、InfluxDB这样的存储系统,以便通过Grafana等工具进行可视化展示。 4. **集成Spring Boot**:如果涉及Spring Boot,会教授如何在Spring Boot应用...

    mw-metrics

    4. **文档**(docs目录):包含项目文档,如README.md,介绍了如何安装、配置和使用mw-metrics,可能还包括API参考和最佳实践指南。 5. **构建脚本**(build scripts,如pom.xml或build.gradle):项目构建配置,...

    mp-metrics-examples:使用MicroProfile Metrics API的示例

    `mp-metrics-examples`项目就是用来演示如何在实践中使用MicroProfile Metrics API。 MicroProfile Metrics API主要包含以下组件和概念: 1. **Metrics Registry**:这是存储所有度量指标的核心组件。每个度量实例...

    mbench-benchmarks_2.9.3-0.1.zip

    此外,Metrics-Scala还支持与其他监控系统(如Graphite、InfluxDB等)的集成,实现更高级别的监控和报警功能。 结合mBench和Metrics-Scala,开发者可以在Scala项目中建立一个完整的性能测试和监控体系。首先,...

    时序数据库 InfluxDB

    插件支持其他数据摄取协议,例如 Graphite、collectd 和 OpenTSDB。 专为轻松查询聚合数据而定制的类似 SQL 的表达查询语言。 标签允许为系列建立索引以实现快速高效的查询。 保留策略有效地自动使陈旧数据过期。 ...

    blog-metrics:用于使用 dropwizard 指标和 statsd 配置 Spring Boot 应用程序的源存储库

    3. 收集数据:Dropwizard会周期性地将指标数据发送到StatsD,StatsD则会聚合这些数据,并可以将它们转发到如Graphite、InfluxDB等可视化工具,以便生成图表和报警。 在这个"blog-metrics"项目中,你将找到如何在...

    ng-grid-2.0.11-2.zip

    它可以与各种监控系统(如 Graphite、New Relic 等)集成。 4. **开源软件开发**: 开源项目意味着代码公开,鼓励社区协作和共享。这样的模式促进了技术的快速发展,同时也提供了学习和贡献的机会。开发者可以在 ...

    基于Java的监控框架.zip

    - **Dropwizard Metrics**:一个强大的度量库,支持多种度量类型,包括计数器、定时器、直方图等,可以与其他监控系统(如Graphite、Elasticsearch)集成。 - **Zipkin**:专注于收集和可视化微服务架构中的调用链...

    HBase参数修改 PDF 下载

    2. Hadoop的Metrics2系统,可以集成Ganglia、Graphite等工具进行性能监控。 3. JMX接口,可以利用JConsole、VisualVM等工具查看和调整HBase的运行参数。 总结,HBase参数修改是确保系统高效稳定运行的关键步骤,...

    riemann:Clojure中的网络事件流处理系统

    **正文** Riemann是一款基于Clojure语言的网络事件流处理系统,专为实时监控、度量和日志分析设计。在IT运维领域,Riemann因其强大的...通过深入学习和实践,你可以更好地利用Riemann来优化你的系统监控和运维流程。

    admin-monitoring

    这些指标可以被导出到不同的监控系统,如Prometheus或Graphite。 4. **日志管理**:日志是诊断问题的重要资源,项目可能采用Logback或Log4j作为日志框架,同时结合ELK(Elasticsearch、Logstash、Kibana)堆栈或者...

Global site tag (gtag.js) - Google Analytics