大量数据分析

时间:2013-04-14 06:31:50

标签: c++ algorithm bigdata

假设我们每天都有1e10行日志文件,每行包含:ID号(长度小于15位的整数),登录时间和注销时间。有些ID可能会多次登录和注销。

问题1

如何计算已登录的ID总数?(我们不应将每个ID计算两次或更多)

我试图在这里使用哈希表,但我发现我们应该获得的内存可能非常大。


问题2

计算在线用户人数最多的时间。

我认为我们可能会将一天的时间分成86400秒,然后对于每行日志文件,在在线时间间隔内每秒加1。或者我可以按登录时间对日志文件进行排序?

5 个答案:

答案 0 :(得分:6)

你可以在* nix shell中做到这一点。

  1. cut -f1 logname.log | sort | uniq | wc -l
  2. cut -f2 logname.log | sort | uniq -c | sort -r

答案 1 :(得分:1)

对于问题1,忘记C ++并使用* nix工具。假设日志文件是以空格分隔的,那么给定日志中的唯一登录数由下式计算:

$ awk '{print $1}' foo.log | sort | uniq | wc -l

Gnu排序,将愉快地排序大于内存的文件。以下是每件作品的作用:

  • awk 正在提取第一个以空格分隔的列(ID号)。
  • sort 正在对这些ID号进行排序,因为 uniq 需要排序输入。
  • uniq 仅返回uniq数字。
  • wc 打印行数,这将是uniq数的数量。

答案 2 :(得分:1)

问题2有意义:您可能需要记录两件事:用户登录和用户注销。两个不同的活动以及用户ID。如果此列表按活动的时间排序(登录或注销完成)。您只需使用名为currentusers的计数器进行扫描:每次登录添加1,每次注销添加-1。该数字(当前用户)达到的最大值是您感兴趣的值,您可能还会对跟踪它发生的时间感兴趣。

答案 3 :(得分:0)

对于1,您可以尝试使用足够小的文件片段以适应内存。 即代替

countUnique([1, 2, ... 1000000])

尝试

countUnique([1, 2, ... 1000]) + 
countUnique([1001, 1002, ... 2000]) + 
countUnique([2001, 2002, ...]) + ... + countUnique([999000, 999001, ... 1000000])

2有点棘手。将工作划分为可管理的时间间隔(如您所建议的那样)是一个好主意。对于每一秒,使用以下检查(伪代码)查找在泰铢秒期间登录的人数:

def loggedIn(loginTime, logoutTime, currentTimeInterval):
    return user is logged in during currentTimeInterval

将loggedIn应用于所有86400秒,然后最大化86400个用户计数列表,以查找在线用户数量最大的时间。

答案 4 :(得分:0)

  1. 使用segment tree来存储连续ID的间隔。 扫描日志以查找所有登录事件。 要插入id,首先搜索包含id的段:如果存在,则id是重复的。如果它不搜索id之后或之前的段。如果它们存在,请删除它们并根据需要合并新ID,然后插入新段。如果它们不存在,请将id作为1个元素的一部分插入。

    插入所有ID后,通过汇总树中所有段的红衣主教来计算其数量。

  2. 假设:

    • 给定的ID在任何给定时间只能登录一次,
    • 事件按时间顺序存储(通常是日志)

    扫描日志并保留当前登录用户数量的计数器c,以及找到的最大数量m和相关时间t。对于每次登录,请增加c,并为每次注销减少它。如果m低于t,则在每个步骤更新mc