直播观看时长波动问题排查记录
问题
最近有主播反馈了个问题「线上直播的总观看时长在直播结束之后值变小了」,随后领导便安排我去排查问题了。
排查
接到任务之后,我便打开代码看了下目前统计直播观看时长的代码,大概看了几遍代码之后,也没发现什么问题。
先大概说下之前的统计流程:
- 有个定时任务会去查出最近的直播id
- 根据直播id及时间段在用户建/断连的表查出观看直播的用户
- 通过用户和时间段查出用户在直播间的所有不同渠道的建/断连数据
- 直接累加在不同渠道的建连和断连的时间段(我看到这块的时候觉得会重复统计时间段,导致统计数据变大,但是,主播却反馈数据变小了,疑惑中…)
- 将用户在直播间下的观看时长写入到最终的统计表
思考了一会儿之后,没有发现符合这次现象的bug;然后,我便看了下线上统计表的数据,发现这场直播有些用户的观看时长竟然为 null,并且,更新时间还是直播结束之后,我想这个应该就是导致统计的时长变小的原因吧!但是,为什么用户观看的时长会被更新为 null 呢?带着疑惑,我便查了下那个直播观看时长为 null 的用户的建/断连数据,发现这个用户在开播之前20多分钟就进入直播间了,中途有几次退出和进入,最后一次是在直播结束之后30多分钟才退出直播间。数据看起来没什么问题,但是,为什么最后统计的观看时长会被更新为 null 呢?
郁闷中,我又仔细看了一遍代码,发现之前忽略掉了查询用户建/断连的表时,还带上了 id 偏移量(我想是为了加快查询速度),1个小时只查询 xxx 条数据,我一看注释中写的数值挺大的了,但是,本着谨慎的态度,我看了下线上实际配置的值,不错,好家伙,果然和注释的不一致… 至此,我心中便有了初步的猜想了,应该是最后一次统计用户观看时长的时候,查询的数据正好没有完整的建连和断连的时间段,导致统计不到观看时长,便将时长更新为 null 了;为了验证我心中的猜想,我便查了最后一次统计该直播间观看时长时候的数据量,发下查询到的数据量恰好是比配置的大了一些,导致一些用户数据没有被查到,统计的时长变少了。
修复
简单和领导沟通了下问题出现的原因之后,领导便同意先临时将 id 偏移量调大一些;然后,让我修复一下这个问题。
我看了下之前的表结构,在创建时间字段上已经有索引了,按理说直接按照创建时间进行范围查询速度上也是很快的,为啥要用 id 偏移量呢?而且在这里预估了数据量的大小,这样数据量一上来就得调整这个 id 偏移量了,要是忘记改了又得出问题,不合理呀。首先就是把这玩意去掉了。然后真正统计用户观看时长那块也有问题,没有考虑到用户提前进入直播间和推迟离开直播间这两种情况,比如,用户提前20分钟进入直播间,然后观看了30分钟直播之后,便离开直播间了,此时只能查到用户有一个断连的数据,这样的数据直接被忽略掉了,同理,用户推迟离开直播间,也会导致用户最后一段连续观看时长没有被统计到。
我此时便想到先把用户的观看时间段数据补齐,但是,如何去重不同渠道下的观看时间段呢?想了会儿,没有啥好思路,便在网上查了下相关搜索词,顺利找到 LeetCode 上的一道算法题 56. 合并区间,看了下解题思路,感觉很 nice。调整了下代码来适应新算法,然后,写了下单元测试,将几种边界情况挨个测了一遍。至此,问题修复完成了。又是美好的一天 :)