spark 3.3+ 之BloomFilter Runtime Filter

问题:

小表left join超大表,耗时要超1.5h,而且发生了FetchException导致任务多次重试之后挂掉的情况:

解决方案:

ai了一番之后,给出了一个靠谱的解决方案:Runtime BloomFilter:

复制代码
修改前:
...
from table_small_xxx
LEFT JOIN (
            select user_id
            from table_xxx
            where dt='${etl_date}'
    ) t3 ON (t1.user_id=t3.user_id)
    
修改后:

SET spark.sql.runtimeFilter.bloomFilter.enabled=true;    --  总开关。是否启用 Runtime BloomFilter
SET spark.sql.runtimeFilter.bloomFilter.applicationSideScanSizeThreshold=10GB;    -- application side (大表) 必须 ≥ 这个阈值, 才考虑加 BF
SET spark.sql.runtimeFilter.bloomFilter.creationSideThreshold=1GB;    -- creation side (小表) 必须 ≤ 这个阈值, 才会去构建 BF,避免bf太大
SET spark.sql.runtimeFilter.semiJoinReduction.enabled=true;    -- 另一种运行时过滤策略,适合build side很小无须使用bloomfliter直接用类似in的查询方式(其实也可以不加)

...
from table_small_xxx
LEFT JOIN (
    SELECT t.user_id
    FROM table_xxx t
    LEFT SEMI JOIN (
        SELECT DISTINCT user_id
        FROM table_small_xxx
        WHERE dt='${etl_date}'
      ) s ON (t.user_id = s.user_id)
      WHERE t.dt='${etl_date}'
) t3 ON (t1.user_id=t3.user_id)

原理介绍:

a left join b 时,a是小表,b是超大表。 那么就先对a中的join条件构造bloomfilter,broadcast到各个executor上,把超大表中的数据先剔除掉,这样就不会shuffle大量数据了。

复制代码
                   ┌────────────────────────────┐
                   │  Build Side (小的一边)       │
                   │  (creation side)            │
                   │  e.g. song_base_info 750万  │
                   └────────────┬────────────────┘
                                │ 1. 扫一遍, 把 join key 全部塞进 BF
                                ▼
                   ┌────────────────────────────┐
                   │     BloomFilter 数据结构     │
                   │  几 MB ~ 几十 MB 的 bitmap  │
                   └────────────┬────────────────┘
                                │ 2. 通过 Broadcast 分发到 tag 表 scan task
                                ▼
                   ┌────────────────────────────┐
                   │  Application Side (大的一边)│
                   │  e.g. tag 表 8862 亿行      │
                   │                             │
                   │  for each row in tag:        │
                   │    if BF.mightContain(key):  │
                   │      emit row  ← 1% 通过     │
                   │    else:                     │
                   │      skip      ← 99% 丢弃    │
                   └────────────┬────────────────┘
                                │ 3. 输出筛选后的小数据集
                                ▼
                       进入正常的 Join 阶段
相关推荐
weixin_424183613 小时前
开放—封闭原则实战(下):基于策略的流程编排与编译期多态
c++·分布式·系统架构
动恰客流统计3 小时前
景区客流统计怎么做?兼顾管控与运营的实施方案解析
大数据·前端·人工智能
weixin_443883013 小时前
合规整改倒计时:高等级签名证书的应用场景
大数据·人工智能·法大大·法大大电子签·电子合同
dozenyaoyida4 小时前
AI与大模型新闻日报 | 2026-09-30
大数据·人工智能·大模型·新闻
辻弋2015 小时前
【无标题】
大数据·服务器·前端·搜索引擎·开源软件
衡石科技5 小时前
让问数更自然:衡石 Data Agent 实践
大数据·bi·数据权限·data agent·自然语言问数
实验室管理云平台5 小时前
应用盛元广通的SPF系统后,养殖场死亡率降低约20%
大数据·人工智能
FYKJ_20107 小时前
SSM校园失物招领系统41452-计算机课程设计、毕业设计
java·vue.js·spring boot·python·mysql·typescript·spark
frjc7 小时前
分布式事务:场景与选型决策表
分布式
火山引擎和TA的超级拍档们8 小时前
产品情报局 04|客服Agent:大模型时代的智能客服新范式
大数据·人工智能