Hive 优化是一个系统工程,涉及数据模型、存储、计算、配置等多个层面。以下是一些关键优化方向及对应的案例:
优化核心目标: 减少数据扫描量、减少数据移动量、减少 Shuffle 数据量、提高并行度、减少 I/O、减少资源消耗、避免数据倾斜。
一、 数据模型与存储优化
-
分区 (Partitioning)
- 原理: 将表按某一列(通常是日期、地区等维度)的值划分成不同的目录存储。查询时只扫描相关分区的数据。
- 案例:
user_behavior_log表按dt(日期) 分区。- 查询
SELECT COUNT(*) FROM user_behavior_log WHERE dt = '2023-10-25' AND action = 'click'; - 优化前: 扫描整个表目录下的所有文件。
- 优化后: 只扫描路径如
/user/hive/warehouse/user_behavior_log/dt=2023-10-25/下的文件。数据扫描量减少几十甚至几百倍。
- 关键点: 选择合适的分区键(高基数、常用过滤条件),避免分区粒度过细(如按秒分区可能导致大量小文件)。
-
分桶 (Bucketing)
- 原理: 根据某列的哈希值将数据划分成固定数量的文件(桶)。常用于优化
JOIN、GROUP BY和采样。 - 案例:
user_profile表和order_info表都按user_id分成 128 个桶。- 查询
SELECT u.name, o.order_amount FROM user_profile u JOIN order_info o ON u.user_id = o.user_id; - 优化前: 需要全表 Shuffle Join。
- 优化后: 开启 Map Join 或 SMB Join 时,相同
user_id的记录必然在相同编号的桶文件中。Map 任务可以直接读取对应桶进行本地 Join (Map Join) 或排序合并 Join (SMB Join),极大减少 Shuffle 数据量和网络传输。
- 关键点: 选择高基数的列作为分桶键(通常是 Join Key),桶的数量通常是 2 的幂次方(与 Reduce 任务数匹配)。
- 原理: 根据某列的哈希值将数据划分成固定数量的文件(桶)。常用于优化
-
选择合适的文件格式
- 原理: 列式存储(ORC, Parquet)比行式存储(TextFile)更高效,支持列剪裁、谓词下推、更好的压缩。
- 案例:
- 表
page_view最初使用TextFile格式,大小 1TB。 - 优化后: 转换为
ORC格式(使用 ZLIB 压缩),大小缩减到 150GB。 - 查询
SELECT user_id, page_url FROM page_view WHERE country = 'US'; - 优化前 (TextFile): 读取所有列的所有数据(1TB),再过滤出
country='US'的行。 - 优化后 (ORC): 利用列剪裁只读取
user_id,page_url,country三列的数据块;利用 ORC 索引和谓词下推,可能只读取满足country='US'的行组 (Row Group)。I/O 量减少 90% 以上。
- 表
- 关键点: ORC 通常在 Hive 生态中性能最优,尤其是开启
Vectorization。Parquet 跨生态兼容性好。
-
数据压缩
- 原理: 减少磁盘存储空间和 I/O 传输量。
- 案例: 同上例,ORC 使用 ZLIB (压缩率高) 或 Snappy (压缩解压速度快) 压缩后,存储空间大幅减少,查询时读取的数据量也相应减少,提升了 I/O 效率。
- 关键点: Map 输出压缩 (
mapreduce.map.output.compress)、最终输出压缩 (hive.exec.compress.output) 也要开启。根据场景选择压缩算法(CPU vs I/O 平衡)。
-
合并小文件

最低0.47元/天 解锁文章
1429

被折叠的 条评论
为什么被折叠?



