大数据日志查找访问量峰值问题

一,问题描述

如果给你一个集群一天的日志,日志里面记载了:

1. 每个用户的登录id

2. 用户的登录时间login_time

3. 用户的登出时间logout_time

那么你会用怎样的方法去判断日志中记录的一天的用户峰值和持续时间段呢?(假设日志打印的时间间隔为秒)

 

此处思考一段时间。。。

欢迎访问我的github~

我在GitHub制作了一些我的基础小项目以及计划可用于的好玩的东西,欢迎一起合作,提建议和创作

也欢迎大家来star经常更新的项目


 

二,问题分析

 

首先遇到这样的问题首先要想到,这种实际情况可能产生的海量数据是不适宜用排序算法做的,即时快排堆排能够保证排序的评价时间复杂度为O(nlogn),但数值一旦大起来这种排序肯定是不能用的。

就像一道经典的题目:如何在海量数据中查找中位数一样要和topK问题做好区别,

topK问题本身是使用堆之后,解决如何避免了对K个数进行排序,时间复杂度为O(N*logK),也可以使用随机选择算法让最好时间复杂度降到O(N),在此不再赘述,有兴趣可见topK问题与随机选择算法

海量数据查找中位数需要通过桶排序的归并能力,首先规划好每个桶的范围,遍历一遍把相应的数值放到相应的桶中,然后在中位数存在的桶中再进行划分排序,每个桶内可以进行快速排序,这样假设桶的个数为M, 平均每个桶内的元素个数为N/M,  桶排序的整体时间复杂度是:O(N + M*N/Mlog(N/M)),找到中位数只需要排序中间的桶的数据就好

桶排序属于很重要但又容易被人忽略的排序算法,其实桶排序的作用解决与hashmap,可以通过将一些大数据映射成小文件来实现问题规模的缩小化。

桶排序的基本思想:

假如我们有一列1~100(一定区间)的数字,待排序列K= {43、 36 、 35、 98 、 26、 73 、 7、 49 }。这些数据全部在1—100之间。因此我们定制10个桶,然后确定映射函数f(k)=k/10。则第一个关键字49将定位到第4个桶中(43/10=4)。依次将所有关键字全部堆入桶中,并在每个非空的桶中进行快速排序。然后依次枚举输出桶B[0]....B[M]中的全部内容即是一个有序序列。

 

桶排序代价分析

桶排序利用函数的映射关系,减少了几乎所有的比较工作。实际上,桶排序的f(k)值的计算,其作用就相当于快排中划分,已经把大量数据分割成了基本有序的数据块(桶)。然后只需要对桶中的少量数据做先进的比较排序即可。

 

桶排序的平均时间复杂度为线性的O(N+C),其中C=N*(logN-logM)。如果相对于同样的N,桶数量M越大,其效率越高,最好的时间复杂度达到O(N)。 当然桶排序的空间复杂度 为O(N+M),如果输入数据非常庞大,而桶的数量也非常多,则空间代价无疑是昂贵的。此外,桶排序是稳定的。

 

这道题和海量数据寻找中位数很像,我们首先要选择适当的桶元素,每天有24*60*60=86400秒,每一秒完全可以作为一个桶,用一个hashmap维护,key值为每一秒,存放的元素为用户在线数量,然后便利整个日志的用户,将在线状态(即登录时间之后,登出时间之前)的秒数key对应的value加1,把所有用户数据装入hashmap之后,遍历hashmap找到value即在线人数最大的时间,并返回最大人数。

// 伪代码
Map<Long, Integer> map = new HashMap<>();
// 装入数据
for (User user: users) {
  for (Long time = user.login_time; time < user.logout_time; time++) {
    map.put(time, map.get(time)+1);
  }
}
// 计算峰值
List<Long> list = new ArrayList<>();
int max = 0;
Iterator it = map.entrySet().iterator();
while (it.hasNext()) {
  Map.Entry entry = (Map.Entry) it.next();
  if ((Integer)entry.getValue() >= max) {
    list.add(entry.getKey());
    max = (Integer)entry.getValue();
  }   
}

// 时间段 list
// 最大峰值 max

 

在这道题中,一个难点是要发现天然给你的“桶”,就是每一秒当作一个桶去做操作,时间复杂度为O(N+86400)=O(N),这样也不需要考虑桶的划分问题

三,再思考

我们发现海量数据问题经常会用到桶,其实用桶排序解决海量数据问题,其本质是分治,桶天然具有分治的能力。在笔试和面试中,桶排序常常会有妙用。 桶排序引入了桶,耗费了空间,节省了时间,这种以空间换时间的技巧,在计算机科学中无处不在。这一点需要重视起来。

另外在题外话,也需要我们结合工程中的实践经验,比如怎么去处理日志格式,怎么去做好审计来便于日后的统计

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值