左连接的 Hive 倾斜缓解

问题描述

我有一个影响左外连接性能的经典倾斜问题(左表“大”,右表“小”)。倾斜的键主要是 NULL(从长远来看),其次是“keyX”。

我尝试了一些不同的方法

  1. 在倾斜的键上添加连接谓词“IS NOT NULL”似乎没有任何明显的影响。此外,我还有“keyX”要处理
  2. 我使用 hive.optimize.skewjoin 得到了不同的结果
  3. 在我发现的几篇文章中引用的“关键盐化”技术效果很好(速度提高了 3 到 4 倍)!但我注意到增加查询的复杂性,它确实需要修改每个问题查询,教育各种其他工程师等
  4. 我刚刚注意到一个非常有前途的功能,您可以specify skew in the metastore 并让 hive 使用它来生成倾斜优化的执行计划。我很想在我回到选项 3 之前对此进行测试,但我似乎无法将 NULL 放入偏斜值列表中。它会接受这个:

alter table T skewed by (skewed_key) on ('keyX');

但不是这个:

alter table T skewed by (skewed_key) on ('keyX',NULL);

知道这种语法有什么问题吗?还是这个特性不接受 NULL Skew 值?

一般来说,我也对偏斜问题的其他解决方案持开放态度:)

解决方法

我的 5 美分:我不打算完全解决这篇文章中的偏斜问题。只是提供一些关于偏斜 NULL 连接键的信息以及我是如何解决它的,希望它会有用

是的,“密钥加盐”有效,其他一切似乎都不稳定或根本不起作用。

如果偏斜的key为NULL并且所有的NULL记录都被分发到同一个reducer,你可以通过将NULL key转换为不在允许范围内的随机key值来解决所以它们不会被加入而是平均分配给许多减速器。

类似这样的:

LEFT JOIN  asset_dim p ON NVL(f.asset_id,-9999999+RAND()*1000.0)%1000) = p.asset_id 

这种方法依赖于这样一个事实,即您在 – 9999999 ... - 9998000 范围内永远不会有负键

对于非 NULL 偏斜键,这种方法是危险的,特别是如果您在 EMR 上运行带有现货节点的节点,这些节点可能会在运行时丢失。重新运行容器将产生不同的 RAND,并且相同的记录将被传递到不同的减速器,这将导致部分数据重复或丢失,但它适用于这种特殊情况下没有加入的 NULL。

同样对于“KeyX”显式拆分连接 + UNION ALL 工作正常,但解决方案有点麻烦:

(select * from t1 where key!='KeyX') left join t2 on t1.key=t2.key --everything else
UNION ALL
(select * from t1 where key=='KeyX') left join t2 on t1.key=t2.key --skewed