statsd on steroid

Why Statsd

Statsd 模式最大的好处是两点

  1. 上报数据者直接是结果的受益者,并对其负责:因为上报数据的人直接是对最终的图表和监控负责的,他有最大的动机去选取合适的指标来帮助自己理解被监控的代码。这种模式可以避免“玩日志”的那帮人和那些平台出现。处理数据的人如果不负责被监控的业务,而上报数据的人不直接决定最终的图表,那么两方都做不好。

  2. 中心化的设计:所有的大数据平台都是基于分布式的。而最常见的问题是数据上报的时候的节点分布和业务指标统计时所需要的节点分布不同,导致多个stage之间shuffle数据产生大量的开销。而statsd简化的设计的一个偶然的结果就是因为数据从上报是直接出结果的,所以一个指标所需要的数据是之接上报给同一个物理节点的。很多复杂的聚合计算从而变成可能。

  3. 数据上报和计算公式二合一:每次上报的数据里都包含了计算所需要的所有元信息(比如计算公式)。省去了注册计算公式的操作,以一定运行时开销的方式简化了使用,而且让数据和数据计算方式的定义两者同时在一起简化了整体的维护成本。

监控最重要的是度量整个被监控的对象是否 “is getting work done”,就是要不断关注是否有产出。而关注一个系统是否有产出,就要对这个系统的模型要有理解。statsd做为很方便的工具,具有非常多的优点。如果statsd更进一步,内置的aggregator不仅仅是counter/gauge这样的对上报数据的肤浅理解,而是能够从模型的角度更深度地了解上报的数据的含义,那么statsd可以更加大放光芒~

业务指标监控:线性Funnel

最通用的关于业务的建模是所谓的Business Process,或者说是某种Funnel。比如

基于所有的业务场景都可以用上面这样的Funnel模型来建模。而从业务角度来说就是关注两点:

  1. 实现这个业务流程的IT系统有没有出问题,是不是有人发了单,但是没有订单并没有真正被收到,或者流程被“卡”在某一步了。

  2. 所有阶段的业务指标(绝对量或者转化率)是否显著低于历史同期(同比)或者前几分钟(环比)

对于一个监控系统来说就是要提供一个方便的接口让业务直接上报每个阶段的数据,然后自动把业务关心的指标统计出来并告警。从IT系统监控的角度来说无需多维,无需复杂如Mixpanel或者Kissmetrics那样,可以简单的提供这样一个上报接口

1000897
sales_funnel
stage=01/estimate
f
或者

1000897
sales_funnel
stage=03/new_order
f
这些数据包含了三个信息:

  1. 1000897 订单id,或者说是其他某种流量id

  2. 对应哪个funnel stage,这里是 new_order

  3. 当前时间,这个是隐含的就是收到这条消息的时间

这些数据还包含了三个元信息:

  1. 我需要用funnel模型对数据进行统计并告警

  2. 这个funnel名叫sales_funnel,所有对同一个funnel的数据上报统一计算

  3. 03/new_order 说明了当前stage在funnel里的位置,其实也就是用index注册了一个新的funnel,但是并不需要使用者去注册,只需要报数据就好了

利用上报的数据就可以统计出

  1. 每个阶段的流量

  2. 每个阶段到下一个阶段的转化率

  3. 每个阶段到下一个阶段的停留时间

  4. 还有多少流量停留在某个具体阶段

复杂一点还需要支持超时,就是时间过去一段时间之后自动转换为另外一个状态,比如新的订单如果迟迟没有到下一个阶段就自动认为作废了。这些指标去做同比环比的对比,就可以得出非常有意义的业务告警了。

业务指标监控:重复性Funnel

重复性Funnel和简单线性Funnel的区别是中间会有重复性的步骤。重复性的步骤在业务上可能是类似于实时计价这样的重复性动作,也可能是系统设计里类似心跳这样的设计。对于重复性Funnel,上报的时候需要添加一个标志位来说明这个stage是不是重复性的。这样可以统计出一个关键指标

  1. 基于前一个stage和后一个stage得出还有多少流量应该停留在当前的stage

  2. 基于重复性动作以心跳的形式计算出当前stage还有多少流量active

  3. active流量和理论流量的比例

这样可以得出当前这个stage后面对应的IT系统是不是有故障了,比如是不是客户端上报遇到了困难,或者服务器挂掉了。

系统指标监控:RPC

另外一个告警的层面是从系统架构的角度来建模。最常见的系统的模型就是一个RPC链条。A调用了B,B调用了C。可以把statsd扩展为这样的形式

0.53,error
my_srv/rpc
caller=/login
callee=http://passport.com/validate
rpc
这里包含了四个信息:

  1. 主调方:/login

  2. 被调方:协议是 http,服务 passport.com,具体的接口 validate

  3. 延迟:0.53 秒

  4. 状态码:error

利用这些信息可以统计出:

  1. rpc.counter:总调用量

  2. rpc.error.counter:分错误码调用量

  3. rpc.latency:延迟的分布

  4. rpc.error.ratio:所有错误码加和的总错误量相比总调用量的比率

利用error.ratio可以直接阈值告警,其他值相比同比和环比也可以告警。这些rpc指标是统计在某个namespace下的,比如上面是统计在my_srv/rpc下的。把A的被调和B的主调对应起来,就可以把A=>B=>C这样的串联起来。

另外所有的Access log也可以建模成RPC。比如

0.28,success
my_srv/rpc
caller=/login
callee=
rpc
把callee去掉换成自己,不就是access log了,说明当前接口处理是否成功,花了多久。对当前接口处理的某个函数的耗时,也是某种pc(procedure call),只是不是rpc,比如

0.28,success
my_srv/rpc
caller=/login
callee=
rpc

系统指标监控:队列

系统除了用RPC建模,另外一种就是队列了(似乎所有的架构模式最后就是这两种做选择)。队列其实比RPC要复杂,也更难监控。需要生产方在生产完之后上报数据

1000897
topic1/partition1
producer=passport
queue
这个上报包含了三个信息:

  1. 1000897 是offset,代表了队列里的一条消息(id),也可以度量队列的长度

  2. topci1/partition1 代表了排队的主体

  3. 生产方名叫passport

  4. 隐藏的信息是 1000897 的生产时间

需要消费方在消费完成之后上报数据

1000677,error
topic1/partition1
consumer=profile
queue
这个上报包含了三个信息:

  1. 1000677 消费到了哪个offset

  2. topci1/partition1 代表了排队的主体

  3. 消费方名叫profile

  4. 隐藏的信息是 1000677 被profile消费的时间

这样就可以统计出

  1. 每个消费者自己的队列长度,比如profile还有多少消息需要消费

  2. 每个消费者自己队列的消费时间分布,从入队列到消费完成。这个是利用了收到产生消息和收到消费消息的时间点。

  3. 每个消费者的错误率

  4. 每个生产者产生了多少消息

核心点

所有以上构想的功能如果有一点吸引力,那主要是因为上报数据的人懒。这也是statsd的核心思想,它做了复杂的事情(有状态),所以你可以变得简单。比如我们可以在订单被接了之后上报的数据包含订单是什么时候发出来的,这样是简化了statsd,但是对于statsd的使用方来说就必须记录和上报这个订单是什么发出来的。也许你会说业务本来就记录了这些,但是也许你上报的地方可能没有读数据库呢?也许就是懒呢?

我们需要一个statsd,不但是有状态,还可以理解业务和系统模型。从而使得使用方可以非常简单,在每个节点上无状态地上报当前阶段有的信息。让statsd自己去聚合这个时间片的指标,聚合关联流程上下游的指标,聚合关联同比和环比的指标。直接出图。直接告警。just works。

关键字:监控, statsd, 上报, rpc

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部