Skip to content

Metrics library

Calvin Xiao edited this page Jun 12, 2015 · 15 revisions

1.Yammer Codehale评测

1.1 简介

堂堂Java界,只有一个Yammer Codehale作为metrics库,其余就是不成熟的Netfilx Servo,以及JavaSimon, JaMon, Perf4j这些单调的更接近于Profiler。所以,Cassandra是用Yammer, Spring Boot里也是用Yammer。

Codehale有几种Metrics类型:

  • Counter,最单纯的Couter。
  • Meter,Counter的基础上还带有Rate,包括从系统启动到现在的平均rate,1分钟,5分钟,15分钟的平均rate,15分钟这种移动rate并不是真的保存15分钟然后求平均值,而是在每隔很一小段时间,按照某个公式(使用Linux里Top的算法)对counter变化进行计算推导出1/5/15分钟的值。
  • Histogram,适合于计算请求的执行时间,每次塞进去一个当前的执行时间,算出一堆数值的最小,最大,平均,方差,以及50%,75%, 90%, 95%, 98%, 99%, and 99.9% 都会小于某个值。有几种算法决定存储多少的基本数据 ,比如 SlidingWindowReservoir(固定大小),SlidingTimeWindowReservoir(固定时间长度),UniformReservoir(随机采样)
  • Timer,等于Meter+Hitogram,既算TPS,也算执行时间。

向后报告的方式包括定期报告的如graphite, console, slf4j log,也有即时报告的如JMX(不建议用于生产环境)。各个reporter间独立Scheduler。

Metrics Spring支持Spring applicationContext.xml里定义Reporter,以及用@Countered 这样的annotation定义方法,用AOP生成Counter

Cassandra还用到了一个辅助项目Metrics Reporter Config,支持用Yaml定义Reporter。

1.2 缺点

  1. 很多数据并不是我们想要的,白白计算白白浪费性能,Meter经常性计算推导的1/5/15分钟平均TPS值有点浪费,影响traffic, 又比如Hisogram,方差对一般人来说不敏感,”50%,75%, 90%, 95%, 98%, 99%, and 99.9% 都会小于某个值“ 也是太多了,最好可以自行配置需要的数值。

  2. Meter里只有一个从服务启动到现在的Counter和Mean Rate,以及推导出来的1/5/15分钟平均值。总Counter其实不能很好的解决服务重启以及Long值达到最大值等情况,其实更多情况需要的是StatsD那种每个报告期内的Counter的变化值和TPS。(当然,启动到现在的Counter和平均Rate可以作为一个辅助数据同时提供)

  3. 多种Reporter同时使用的话,ConsoleReporter计算一次值,GraphiteReporter再计算一次值。

看Cassandra的Java Driver的Stress Application,就是很郁闷的自己在程序里解决上面2、3的问题,自己记录上一次的Counter和TPS,计算报告期内的Counter变化;也没有使用Reporter,而是自己先用一个对象缓存数据,然后自行输出到CSV和Console。

2. SpringSide改造

结合Statsd的做法,在Yammer Codahale Metircs的基础上重写,其实两者一个最核心的差别,就是Statsd有一个报告期的概念,每次报告生成后数据清零:

  • Reporter机制,所有Reporter可共用一个Scheduler,触发时计算一次metrics值的Snapshot,然后在各个reporter以及JMX Exporter, REST exporter间共享。
  • Counter和Meter合一,并且提供上一次report到现在的counter变化值和rate。
  • Histogram,去除了方差,而50%,75%, 90%, 95%, 98%, 99%, and 99.9%变成可配置多个任意值。基本数据只存储上一次report到现在的数据。目前算法是存储当前报告期内的所有数据进行计算,以后还可能支持设置采样算法,以及最大存储量限制,防止数量大过大时占用内存过多。
  • Graphite,改变原来每条记录flush()一次,学习Collectd的Graphite Reporter,尽量buffer到足够大再flush()以加强性能。