spark-streming 中调用spark-sql时过程遇到的问题

在spark-streming 中调用spark-sql时过程遇到的问题

使用版本:spark-2.1.0
JDK1.8

1. spark-sql中对limit 的查询结果使用sum() 聚合操作不生效

如下sql会报出 top10_sts 存在异常。

SELECT 
  SUM(mtime_show_times) AS top10_sts 
FROM
  tb_movie_bo_pt_params 
ORDER BY mtime_persion_times DESC 
LIMIT 10 

改成如下sql逻辑正常执行

SELECT 
  SUM(mtime_show_times) AS top10_sts 
FROM
  (SELECT 
    * 
  FROM
    tb_moive_bo_pt_params 
  ORDER BY mtime_persion_times DESC 
  LIMIT 10) a 

2. spark-sql中使用union 连接两个表;再将union结果进行过滤 != 操作不生效问题。

SELECT 
  'ALL_MOVIE' AS movie_id,
  SUM(no_sale) AS persion_times,
  COUNT(1) AS show_times 
FROM
  tb_bo_real_time 
WHERE biz_date = '#{var_date}' 
UNION
SELECT 
  'ALL_MOVIE2' AS movie_id,
  '2017-12-31' AS persion_times,
  '1123' AS show_times 

基于union 的结果生成的临时表 temp_tb;
执行如下操作得不到预期的结果:

SELECT 
 *
FROM
  temp_tb 
WHERE movie_id != 'ALL_MOVIE' 

这 可能是spark的bug,经过调试后发现,使用 union关键字之后就会出现该问题。
测试发现有2种解决办法:

  • 将uinon的两部分分别使用sql计算,之后在使用RDD的union操作,将两个数据集合合并起来。
    val movie_summary_realtime_Df = sparkSession.sql(config.getProperty("test_union_sql").replace("#{var_date}", biz_date))
    movie_summary_realtime_Df.collect().foreach(println)
    println("-----------movie_summary_realtime_all_Df------------------")
    val movie_summary_realtime_all_Df = sparkSession.sql(config.getProperty("test_union_sql_all").replace("#{var_date}", biz_date))
    movie_summary_realtime_all_Df.collect().foreach(println)
    println("-----------union_Df------------------")

    val unioDf = movie_summary_realtime_Df.union(movie_summary_realtime_all_Df)
    unioDf.collect().foreach(println)
    unioDf.createOrReplaceTempView("tb_bo_movie_summary_realtime")

    println("-----------test filter------------------")
    val test_DF = sparkSession.sql("SELECT movie_id FROM tb_bo_movie_summary_realtime WHERE movie_id != 'ALL_MOVIE'")
    test_DF.collect().foreach(println)
  • 将相关依赖表cache后,再进行sql操作。
    val movie_summary_realtime_Df = sparkSession.sql(config.getProperty("tb_bo_movie_summary_realtime").replace("#{var_date}", biz_date))
    movie_summary_realtime_Df.cache()

3. spark 内存快照的更新

  def updateSeatMapState(moviesKey: String, seatMap: Option[JSONObject], state: State[JSONObject]) = {
    var newValue:JSONObject = seatMap match {
      case None => { val temp =state.get();temp;}
      case _ => { state.update(seatMap.get);seatMap.get; }
    }
    val output = (moviesKey, newValue)
    output
  }
  • 当前值Option[JSONObject] 有可能为none,state.update(none) 会有空指针异常,造成程序退出。
  • 当前值Option[JSONObject] 为none时,有两种情况。一种是业务确实为空;另一种是当前key已经过期了。
    不管那种情况,都不需要更新state的值。
  • 如果一个state的可以过期了,再调用state.update()就会报出一个更新过期Key的异常,后程序退出。
  • 状态值如果不设置过期,就会一直存在,系统长时间运行性能会越来越差,并出现内存溢出,而异常退出。
  • 更新方法需要返回值。
java.lang.IllegalArgumentException: requirement failed: Cannot update the state that is timing out
        at scala.Predef$.require(Predef.scala:224)
        at org.apache.spark.streaming.StateImpl.update(State.scala:156)
        at com.mtime.bigdata.bo.RealTimeBoxOfficeCluster$.updateSeatMapState(RealTimeBoxOfficeCluster.scala:110)
        at com.mtime.bigdata.bo.RealTimeBoxOfficeCluster$$anonfun$6.apply(RealTimeBoxOfficeCluster.scala:72)
        at com.mtime.bigdata.bo.RealTimeBoxOfficeCluster$$anonfun$6.apply(RealTimeBoxOfficeCluster.scala:72)
        at org.apache.spark.streaming.StateSpec$$anonfun$1.apply(StateSpec.scala:181)
        at org.apache.spark.streaming.StateSpec$$anonfun$1.apply(StateSpec.scala:180)
        at 
posted @ 2017-09-19 18:43  丹江湖畔养蜂子赵大爹  阅读(1209)  评论(0编辑  收藏  举报