Hive分桶机制应用
Hive分桶机制应用业务背景数据提供方的数据频率不固定很多时候N天才会推一次多天的业务数据会集中到某一个分区中由于分布不均匀查询的时候也就需要不固定时间范围的查询。按照业务需求需要关联维表回填一些信息。解决办法使用动态分区的方式按业务时间重新将数据写入新的表。新表设计时候引入分桶策略方便后期查询。新表设计-- 数据表createtableifnotexistsnew_box(capture_timebigintcomment采集时间戳,uid stringcomment‘用户ID’,tags string,......)partitionedby(dt stringcomment日期分区)CLUSTEREDBY(uuid)INTO32BUCKETS;-- 用户标签表createtableifnotexistsuser_tags(uid string,tags string)CLUSTEREDBY(uuid)INTO32BUCKETS;动态分区SEThive.exec.dynamic.partitiontrue;SEThive.exec.dynamic.partition.modenonstrict;SEThive.execution.enginetez;SEThive.merge.tezfilestrue;SEThive.merge.size.per.task268435456;-- 256MBSEThive.merge.smallfiles.avgsize16777216;-- 16MBINSERTINTOTABLEnew_boxPARTITION(dt)SELECTt1.capture_time,t1.uid,t2.tags...date_format(capture_time,yyyy-MM-dd)ASdtFROMsrc_data t1leftjoinuser_tags t2ont1.uidt2.uid DISTRIBUTEBYhash(uid)%64,dt;如何设计分桶分桶设计的4条核心原则分桶是为了join、去重、抽样不是为了分区一个表只允许一个分桶键clustered by 只能是一个字段分桶键必须是 JOIN/Group By/Distinct 的高频字段分桶数数据规模 / 单文件理想大小。分桶设计的标准流程5步法1: 确定分桶键✅ 优先候选场景分桶键事实表 JOIN 维表外键uuid / user_id明细表去重主键用户行为分析user_id订单表order_id❌ 绝对不要时间戳经纬度高基数 无意义字段2判断是否需要分桶问自己 3 个问题1️⃣ 是否会频繁 JOIN / 去重 / 抽样2️⃣ 数据量是否 ≥ 100GB3️⃣ 是否已经有分区✅ 满足 2 个以上 →必须分桶3计算bucket数经验公式 bucket数 ≈ 表数据量 / 单 bucket 理想大小✅ 推荐单 bucket 大小场景推荐离线批处理200–400MB交互查询100–200MB日志表256MB4.表结构模板CREATETABLExxx(...)PARTITIONEDBY(dt STRING)CLUSTEREDBY(bucket_key)INTO32BUCKETS STOREDASPARQUET;分区不等于分桶不要把时间放进分桶5.写入时预防小文件INSERTINTOTABLExxxPARTITION(dt)SELECT...FROMsource DISTRIBUTEBYhash(bucket_key)%32,dt;备注控制文件数不影响 bucket 映射与 CLUSTERED BY 逻辑一致验证是否合理bucket分布检查SELECThash(uuid)%32ASb,count(*)FROMtableGROUPBYb;结果0-31连续行数差距 20%JOIN是否命中SMBexplainselect...# SMB Join Operator#(利用两张表的分桶信息直接按 bucket 对齐 JOIN避免 Shuffle)