我们正在探索如何使用Bigquery来存储和分析代表用户会话的100万个日志条目。源原始日志条目包含"connect“日志类型和”断开“日志类型。
我们可以选择在日志被摄取到bigquery之前处理它们,以便每个会话有一个条目,其中包含会话启动时间戳和一个“持续时间”值,或者单独插入每个日志条目并在分析阶段计算会话时间。让我们假设我们的表模式的形式是:
sessionStartTime: TIMESTAMP,
clientId: STRING,
duration: INTEGER
或者(在每个会话中存储两个日志条目:一个连接和一个断开连接):
time: TIMESTAMP,
type: INTEGER, //enum, 0 for connect, 1 for disconnect
clientId: STRING
我们的问题是,我们无法找到一种使用bigquery获得并发用户的方法:理想情况下,我们将能够编写一个查询,通过时间戳“桶”(假设每分钟)对会话表进行分区,并执行一个查询,该查询将在特定的时间范围内为我们提供每分钟的电流。
考虑日志条目的并发流的简单方法是,在任何时候使用函数f(t) = x0 + connects(t) -断开(T)计算它们,其中x0是初始并发用户计数(在时间t0),t是“时间戳”桶(在本例中以分钟为单位)。
有人能推荐一种方法吗?
谢谢!
发布于 2013-11-04 00:40:46
谢谢你提供的样本数据!(可在https://bigquery.cloud.google.com/table/imgdge:sopub.sessions查阅)
我将接受您的建议:“我们可以选择在日志被吞并到bigquery之前处理它们,以便每个会话都有一个条目,其中包含会话启动时间戳和一个‘工期’值”。这一次,我将使用BigQuery进行处理,并将结果放在我自己的表中:
SELECT u, start, MIN(end) end FROM (
SELECT a.f0_ u, a.time start, b.time end
FROM [imgdge:sopub.sessions] a
JOIN EACH [imgdge:sopub.sessions] b
ON a.f0_ = b.f0_
WHERE a.type = 'connect'
AND b.type='disconnect'
AND a.time < b.time
)
GROUP BY 1, 2
一共有819,321行。对于BigQuery来说不是一个很大的数字,但是由于我们要对它进行组合,它可能会爆炸。我们将限制计算并发会话的日期范围,以使其保持正常。我将把查询结果保存到fh-bigquery:public_dump.imgdge_sopub_sessions_startend.
一旦我有了所有有开始和结束时间的会话,我就可以找到每个有趣的时刻每个并发会话的数量。你说的那一刻?
所有有趣的时刻恰巧都是:
SELECT SEC_TO_TIMESTAMP(FLOOR(TIMESTAMP_TO_SEC(time)/60)*60) time
FROM [imgdge:sopub.sessions]
GROUP BY 1
现在,让我们将这个有趣的时间列表与我的新表中的所有会话结合起来。对于每一分钟,我们都要统计一下在此之前开始并在此之后结束的所有会话:
SELECT time, COUNT(*) concurrent
FROM (
SELECT u, start, end, 99 x
FROM [fh-bigquery:public_dump.imgdge_sopub_sessions_startend]
WHERE start < '2013-09-30 00:00:00'
) a
JOIN
(
SELECT SEC_TO_TIMESTAMP(FLOOR(TIMESTAMP_TO_SEC(time)/60)*60) time, 99 x FROM [imgdge:sopub.sessions] GROUP BY 1) b
ON a.x = b.x
WHERE b.time < a.end
AND b.time >= a.start
GROUP BY 1
注意99 x
。它可能是任何数字,我只是用它来生成组合,所有的会话*所有的时间。对于这种组合游戏,有太多的会话,所以我用WHERE start < '2013-09-30 00:00:00'
来限制它们。
这就是计算并发用户的方法。
发布于 2013-10-28 12:19:27
您能代替sessionStartTime获取sessionEndTime (或者只添加duration+sessionStartTime)吗?如果你能做到的话,这样的东西就可以制造出来。这并不完美,但它会给你一些相关的数据。
SELECT AVG(perMinute) as avgUsersMin FROM
(
SELECT COUNT(distinct clientId, 1000000) as perMinute, YEAR(sessionEndTime) as y,
MONTH(sessionEndTime) as m, DAY(sessionEndTime) as d, HOUR(sessionEndTime) as h, MINUTE(sessionEndTime) as mn FROM [MyProject:MyTable]
WHERE sessionEndTime BETWEEN someDate AND someOtherDate
GROUP BY y,m,d,h,mn
);
https://stackoverflow.com/questions/19618380
复制相似问题