使用自定义逻辑处理来自Redshift的数十亿条记录

时间:2019-09-22 13:03:59

标签: sql apache-spark bigdata amazon-redshift google-cloud-dataflow

我想对放置在Redshift中的数据集应用自定义逻辑。 输入数据示例:

userid, event,  fileid, timestamp, ....
100000, start,  120,    2018-09-17 19:11:40
100000, done,   120,    2018-09-17 19:12:40
100000, done,   120,    2018-09-17 19:13:40
100000, start,  500,    2018-09-17 19:13:50
100000, done,   120,    2018-09-17 19:14:40
100000, done,   500,    2018-09-17 19:14:50
100000, done,   120,    2018-09-17 19:15:40

这意味着:

file 120:  start-----done-----done-----done-----done 
file 150:                      start-----done   
time    :  11:40----12:40----13:40-----14:40-----15:40

但是应该看起来像

file 120:  start-----done-----done 
file 150:                      start-----done   
time    :  11:40----12:40----13:40-----14:40-----15:40

文件150一旦启动,文件120已被中断

请记住,如果此处有不同的用户和许多不同的文件,那么很多。

清洗后的数据应为:

userid, event,  fileid, timestamp, ....
100000, start,  120,    2018-09-17 19:11:40
100000, done,   120,    2018-09-17 19:12:40
100000, done,   120,    2018-09-17 19:13:40
100000, start,  500,    2018-09-17 19:13:50
100000, done,   500,    2018-09-17 19:14:50

同一用户不能一次拥有多个并发文件。因此,第二个事件开始后,第一个事件不会从当前数据集中删除。

代码很简单,但是在python上,例如,对于Google Dataflow来说,它很容易扩展,但是将100GB以上的数据从AWS迁移到GC并不是一个好主意。

问题1: 是否可以在SQL上做到这一点(使用postgres / redshift特定功能),或者更好地使用Spark? (但不确定如何在那里实现)

问题2: 关于使用AWS Batch或其他任何可能导致apache Beam的建议,这很容易,而且很明显,但是AWS Batch的工作方式以及如何将数据集按块划分(如每个用户分组)是一个很大的问题。 我的建议是以某种方式将数据从redshift卸载到S3存储桶中,然后以单独的file = user方式将其划分,然后,如果aws批处理支持此功能-只需输入存储桶,每个文件应在已创建的实例上同时处理。不知道这是否有意义。

1 个答案:

答案 0 :(得分:1)

如果您要删除fileid与用户最近的start不匹配的行,可以使用lag(ignore nulls)

select t.*
from (select t.*,
             lag(case when event = 'start' then file_id end ignore nulls) over (partition by userid order by timestamp) as start_fileid
      from t
     ) t
where event = 'start' or start_fileid = fileid;