spark踩坑记录 (一) group by

mysql 与 spark sql 语法大致相通。但是会有一些坑存在。比如 group by
·
需求场景:
在视屏表中,取每个作者最新的一条数据。
即, 筛选出 所有  user_id对应的  最新的(通过create_time 倒序取)一条数据。
·
mysql中:
select user_id,site,create_time
from ( select user_id, site, create_time   
       from table_video
       where dt =20210909 and user_id is not null 
       order by create_time desc ) a
group by user_id
·
mysql --> Spark 产生异常:
但是, 同样的代码 进入 spark 就会报异常:
org.apache.spark.sql.AnalysisException:
expression 'a.`site`' is neither present in the group by, nor is it an aggregate function. 
Add to group by or wrap in first() (or first_value)
·
网上搜索后得知:
mySQL 语句中少了一个分组,   spark 中的sql用的是美式标准的sql。
说是需要将 查询的字段,都加在 group by 后面:
select user_id,site,create_time
from ( select user_id, site, create_time   
       from table_video
       where dt =20210909 and user_id is not null
       order by create_time desc ) a
group by user_id,site,  create_time
但最终查询的结果并不满足我们场景需要的内容:
`
         最终分组是根据 三列属性来分组,如果他们的数据个数分别是:k、m、n个,那查询的行数是 k*m*n个;
不符合我们期待的k个user_id对应的最新记录。
`
正确解决: 
在spark中,site等 几列在 group by user_id  时,会有多个查询结果:
  • 如果都需要,就获取其余几列对应的属性值集合: collect_set(site), collect_list(create_time)  -- 前者去重,后者不去重
  • 如果不需要全部,只是取随机一行里的属性值:first(site)   【不同于 MySQL 默认的第一行】
·
Spark中:
select user_id, first(site), first(create_time)
from ( select user_id, site, create_time   from table_video
              where dt =20210909 and user_id is not null 
              order by create_time desc ) a
group by user_id

·

Spark中复杂嵌套:
如果外部有嵌套,最好给几列属性,内部另起别名/或者 外部也得使用 dtpv.first(site) 。否则在外面 直接用 dtpv.site 会报错
select  dta.user_id, dta.user_name, dtpv.site,  dtpv.create_time as update_time
from tv_author AS dta
LEFT JOIN (
  select user_id, first(site) as site, first(create_time) as create_time
  from ( select user_id,site,create_time   from  table_video
              where dt =20210909 and user_id is not null 
              order by create_time desc ) a
  group by user_id
) AS dtpv
on dtpv.user_id = dta.user_id
where dta.dt = 20210909

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
spark streaming 是基于 spark 引擎的实时数据处理框架,可以通过集成 kafka 来进行数据流的处理。然而,在使用 spark streaming 进行 kafka 数据流处理时,可能会遇到一些。 首先,要注意 spark streaming 和 kafka 版本的兼容性。不同版本的 spark streaming 和 kafka 可能存在一些不兼容的问题,所以在选择版本时要特别留意。建议使用相同版本的 spark streaming 和 kafka,以避免兼容性问题。 其次,要注意 spark streaming 的并行度设置。默认情况下,spark streaming 的并行度是根据 kafka 分区数来决定的,可以通过设置 spark streaming 的参数来调整并行度。如果并行度设置得过高,可能会导致任务处理过慢,甚至出现 OOM 的情况;而设置得过低,则可能无法充分利用集群资源。因此,需要根据实际情况进行合理的并行度设置。 另外,要注意 spark streaming 和 kafka 的性能调优。可以通过调整 spark streaming 缓冲区的大小、批处理时间间隔、kafka 的参数等来提高性能。同时,还可以使用 spark streaming 的 checkpoint 机制来保证数据的一致性和容错性。但是,使用 checkpoint 机制可能会对性能产生一定的影响,所以需要权衡利弊。 最后,要注意处理 kafka 的消息丢失和重复消费的问题。由于网络或其他原因,可能会导致 kafka 的消息丢失;而 spark streaming 在处理数据时可能会出现重试导致消息重复消费的情况。可以通过配置合适的参数来解决这些问题,例如设置 KafkaUtils.createDirectStream 方法的参数 enable.auto.commit,并设置适当的自动提交间隔。 总之,在使用 spark streaming 进行 kafka 数据流处理时,需要留意版本兼容性、并行度设置、性能调优和消息丢失重复消费等问题,以免
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值