日志服务中提供了消费组能够以流的方式获取日志,使用消费组获取日志的优点在于,用户无需关心日志服务的实现细节和消费者之间的负载均衡、failover等,只需要专注于业务逻辑即可。
一个消费组由多个消费者构成,这多个消费者共同消费一个Logstore中的数据,消费者之间不会重复消费数据。因为每个Shard只会分配到一个消费者,一个消费者可以同时消费多个Shard(当消费者数量超过Shard数量时,多余消费者就会被搁置)。消费者是消费组的基本构成单元,实际承担消费任务,同一个消费组下面的消费者名称必须不同。
常见的日志消费延迟有以下三个原因:
- 消费速度跟不上日志写入的速度
- 从历史数据开始消费,短暂的消费延迟
- 保存 checkpoint 频率较低,在控制台查看时误认为是消费延迟
在下图所示的消费组状态中查看到某个Shard或整体消费进度与当前时间相差较多时可以根据该文档进行排查。
图中最近消费数据时间是指消费组获取到的 logGroup 中日志写入日志服务的时间,消费组也是根据日志中的时间调用 UpdateConsumerGroupCheckpoint 接口进行修改的,所以调用的频率低,也会造成消费延迟的错觉。
消费速度跟不上日志写入的速度
消费、写入速度需要开通服务日志之后查看自动生成的 logstore: internal-operation_log
消费流量查询:
Method: pulldata | SELECT sum(NetOutFlow)/1024.0/1024.0 AS NetOutFlowMB, time_series(__time__, '1m', '%H:%i:%s', '0') as time GROUP BY time ORDER BY time
写入流量查询:
Method: PostLogstoreLogs | SELECT sum(NetInflow)/1024.0/1024.0 AS NetInFlowMB, time_series(__time__, '1m', '%H:%i:%s', '0') as time GROUP BY time ORDER BY time
比较上面两个SQL流量大小。
1) 首先需要排查process调用里面是否存在阻塞(比如写入到数据库的操作是否较慢等),有可能阻塞了消费进程。
检查消费流量是否达到上限:
Method: pulldata | SELECT Shard, count(1) as count, sum(NetOutFlow)/1024.0/1024.0 AS NetOutFlowMB, time_series(__time__, '1m', '%H:%i:%s', '0') as time GROUP BY time, Shard ORDER BY time
2) 当消费组比较多、且数据量较大时也会出现消费速度跟不上写入速度的情况,单个Shard每秒消费流量超过或接近10兆时,需要手动分裂Shard,shard读写能力参考文档。
3) 数据量过大,机器少时,处理负载过重(网络、cpu或内存上都会有瓶颈导致消费速度慢)
4) java 进程 GC 重启导致重复消费且延迟。
消费历史数据,短暂的延迟
创建消费组开始消费数据时,可以传递消费开始位置。
如果设置的beginCursor,会从最早的数据开始消费,保存的checkpoint 就是历史数据写入的时间点;这时可以参考上面SQL查询消费、写入的速度,如果消费速度远高于写入速度,之后是会追上最新数据的。
保存checkpoint的频率较低
通过下面SQL在 internal-operation_log 中查询保存消费位点的频率。
Method: ConsumerGroupUpdateCheckPoint | SELECT time_series(__time__, '1m', '%H:%i:%s', '0') as time, COUNT(*) as count, Shard GROUP BY time, Shard ORDER BY time
消费组代码中默认的保存频率是30秒一次,不过可以根据需求进行修改。保存 checkpoint 使用的时间是消费到数据FastLogGroup中的 tags 系统字段中 receive_time 字段,消费过程中可以打印该字段查看消费位置;该字段是消费到的最新位置。
消费延迟监控
首先,需要开启服务日志。消费延迟相关的信息在重要日志中,如果需要查看消费或写入速度,还需要开启详细日志。服务日志开启之后自动会创建消费组监控仪表盘,如下图:
可以使用上面的图表设置告警,由于默认的图表中字段别名使用了中文,告警条件中不能直接使用,需要将中文字段改为英文,然后在告警条件中使用。该日志内容是两分钟更新一次的,所以查询范围、告警条件等都需要大于120秒。
取消中文别名,然后修改Y轴字段、点击预览,最后点确定就可以了。告警条件设置为 MaxBehindLatest > 1800 ,即延迟超过半小时触发告警,查询区间和间隔都设置为 1小时。
相关
最新 checkpoint 保存位置查看:
https://sls.console.aliyun.com/lognext/project/${替换projectName}/logstore/${替换LogstoreName}/consumergroup/${替换消费组名称}/consumergroupList