首页 > 解决方案 > 左连接的 Hive 倾斜缓解

问题描述

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

我尝试了一些不同的东西:

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

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

但不是这个:

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

任何想法这种语法有什么问题?还是此功能不接受 NULL Skew Values?

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

标签: joinhivehiveqlskewhive-metastore

解决方案


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

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

如果倾斜键为 NULL 并且所有 NULL 记录都被分配到同一个 reducer,您可以通过将 NULL 键转换为不在允许范围内的随机键值来解决它,这样它们就不会被连接而是均匀分布到许多减速机。

像这样的东西:

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

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

对于非 NULL 倾斜键,这种方法很危险,尤其是当您在带有点节点的 EMR 上运行时,这可能会在运行时丢失。重新运行容器将产生不同的 RAND,并且相同的记录将被传递给不同的 reducer,这将导致部分数据重复或丢失,但对于未加入 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

推荐阅读