sparksql 因为 where 条件类型而导致的数据倾斜的问题?

问答 niaoyu118 ⋅ 于 2023-03-03 18:23:37 ⋅ 最后回复由 niaoyu118 2023-03-06 15:33:18 ⋅ 1182 阅读

问题:

spark
.read
.option("fetchsize" , fetchsize)
.option( "partitionColumnoption" , partitionColumnoption)
.option( "lowerBound" , where条件的最小值 )
.option( “upperBound” , where条件的最大值 ).
.option( “numPartitions” , numPartitions)
.jdbc(mysql_url, mysql_tablename, prop)
.where( “条件”)
toDF()

假如 读取的表 user 表,有 1 亿数据。
where operatetime > '2023-01-01' and operatetime) < '2023-01-31' 这么一个条件,符合这个条件的有100W数据
问题:
如果 operatetime 字段是 date类型的,spark.read 还是会扫描全表。
如果 operatetime 字段是 String类型的,spark.read 只会扫描符合条件的100W数据。
这样问题就出来了,operatetime 这个字段是date类型的话,扫描全表会导致 数据倾斜,因为我的分区字段配置的上下限已经做过where条件的判断了。
求教各位大佬,这个问题怎么处理?

成为第一个点赞的人吧 :bowtie:
回复数量: 2
  • 青牛 海汼部落创始人,80后程序员一枚,曾就职于金山,喜欢倒腾技术做产品
    2023-03-03 18:50:32

    对于日期类型的列,Spark JDBC 连接器并不会在过滤条件中使用分区列来进行优化。这意味着当您使用 Spark JDBC 连接器读取包含日期类型列的表时,Spark 会在整个表中扫描数据,而不仅仅是扫描符合过滤条件的数据,从而可能导致数据倾斜。

    为了解决这个问题,您可以使用以下两种方法之一:

    1.将日期类型的列转换为字符串类型,以便 Spark 能够在读取数据时使用分区列进行优化。您可以在读取数据之前使用 SQL 中的 CAST 函数或 DataFrame API 中的 withColumn 函数将日期类型的列转换为字符串类型。例如:

    SELECT *, CAST(operatetime AS STRING) AS operatetime_str FROM user WHERE operatetime > '2023-01-01' AND operatetime < '2023-01-31'

    val df = spark.read.jdbc(mysql_url, "user", prop)
      .where("operatetime > '2023-01-01' AND operatetime < '2023-01-31'")
      .withColumn("operatetime_str", col("operatetime").cast(StringType))

    2.增加数据分区,使每个分区的大小不超过合理的范围。这样,即使 Spark 无法使用分区列进行优化,也可以在多个分区上并行读取数据,从而减少数据倾斜的可能性。例如:

    val df = spark.read.jdbc(mysql_url, "user", 
        new Properties() {
            put("fetchsize", fetchsize)
            put("partitionColumnoption", "operatetime")
            put("lowerBound", "2023-01-01")
            put("upperBound", "2023-01-31")
            put("numPartitions", numPartitions)
        })
      .where("operatetime > '2023-01-01' AND operatetime < '2023-01-31'")

    请注意,增加数据分区可能会增加查询的总运行时间和内存开销。因此,您需要权衡分区大小和查询性能之间的权衡

  • niaoyu118
    2023-03-06 15:33:18

    好的,我试试,谢谢大佬

暂无评论~~
  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,可用Emoji的自动补全, 在输入的时候只需要 ":" 就可以自动提示了 :metal: :point_right: 表情列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif,教程
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
Ctrl+Enter