<< ..

阿里云日志服务SLS下数据对比的实践

发布时间:

问题

背景是我们有一个API服务改造,可以用SLS SDK直接发送到阿里云日志服务。 所以实验需要,就做了API和SDK双写。收集了一阵子数据后,就涉及到了数据对比问题。

将这个问题抽象一下就是,向A/B两个SLS发送了相同的100条数据。依据相同时间范围查询,预期A/B均获得100条数据。

但是实际情况查询发现:

  1. A返回100条
  2. B返回98条

找出差异的2条数据,用其唯一标识去反查,发现B其实也有这两条数据。

疑问:

  1. SLS下对比数据如何实现?
  2. SLS如何做到精确的时间范围查询?
  3. 查询差异的原因是什么?

解答

在同Project下支持logstore之间执行join查询。 就可以尝试使用left join方式找出两个数据集直接的异同。

我们的数据结构大概是:

event: {
  "uuid": "一串唯一id GHJGHJGJGJGKGJJGJG",
}

所以需要做一个JSON元素提取用到json_extract_scalar()。 然后就是用old_dataset left join new_dataset,这里需要注意的是时间范围用__time__字段传入unixtimestamp控制。 最终用下面的sql查询,不断切换时间范围就可以对比出每个时间段两个数据集的差异多少了:

select count(old.uuid) as cnt from (
  select json_extract_scalar(event, '$.uuid') as uuid from old_dataset
  where __time__ >= {start_time} AND __time__ < {end_time}
) as old
left join (
  select json_extract_scalar(event, '$.uuid') as uuid from new_dataset
  where __time__ >= 1594656000
) as new
on old.uuid = new.uuid
where new.uuid is null

但是时间对比结果如下,会发现17点开始差异值明显不一样:

time_range old-new
2020-07-14 00:00:00 ~ 2020-07-14 01:00:00 21
2020-07-14 01:00:00 ~ 2020-07-14 02:00:00 21
2020-07-14 02:00:00 ~ 2020-07-14 03:00:00 7
2020-07-14 03:00:00 ~ 2020-07-14 04:00:00 1
2020-07-14 04:00:00 ~ 2020-07-14 05:00:00 4
2020-07-14 05:00:00 ~ 2020-07-14 06:00:00 4
2020-07-14 06:00:00 ~ 2020-07-14 07:00:00 60
2020-07-14 07:00:00 ~ 2020-07-14 08:00:00 62
2020-07-14 08:00:00 ~ 2020-07-14 09:00:00 178
2020-07-14 09:00:00 ~ 2020-07-14 10:00:00 104
2020-07-14 10:00:00 ~ 2020-07-14 11:00:00 185
2020-07-14 11:00:00 ~ 2020-07-14 12:00:00 134
2020-07-14 12:00:00 ~ 2020-07-14 13:00:00 170
2020-07-14 13:00:00 ~ 2020-07-14 14:00:00 92
2020-07-14 14:00:00 ~ 2020-07-14 15:00:00 163
2020-07-14 15:00:00 ~ 2020-07-14 16:00:00 158
2020-07-14 16:00:00 ~ 2020-07-14 17:00:00 71
2020-07-14 17:00:00 ~ 2020-07-14 18:00:00 36759
2020-07-14 18:00:00 ~ 2020-07-14 19:00:00 39254
2020-07-14 19:00:00 ~ 2020-07-14 20:00:00 34640
2020-07-14 20:00:00 ~ 2020-07-14 21:00:00 42345
2020-07-14 21:00:00 ~ 2020-07-14 22:00:00 43063
2020-07-14 22:00:00 ~ 2020-07-14 23:00:00 38705
2020-07-14 23:00:00 ~ 2020-07-15 00:00:00 23040

这里其实是SLS的另一个坑,我摸索到的解决办法是重建这个对比时间段的索引。 在SLS的控制台页面右上侧查询分析属性按钮下有一个重建功能,可以指定时间范围重建索引。 在重建索引后查询,数据符合了分析预期。 可见如果有精确分析需求,还是需要手动重建一下索引。

基于上面认知,可以回答的有:

  1. SLS下对比数据如何实现? 直接使用left join
  2. SLS如何做到精确的时间范围查询? __time__字段控制时间维度
  3. 查询差异的原因是什么? 可能和索引有关系,重建索引会获得不一样的值

还有坑就是:

  1. 在日志服务Web页面查询的时候语句前需要加一个* |,但是使用SDK代码提交查询的时候就不需要了。
  2. 使用SDK查询返回是0的时候,再去Web页面缩减时间范围查一下,或许就不是0了。