我正在阅读高性能 Spark,作者介绍了一种技术,该技术可用于对高度倾斜的数据执行连接,方法是有选择地过滤数据以使用包含最常用键的数据构建 HashMap。然后将此 HashMap 发送到所有分区以执行广播连接。结果数据在最后与联合操作连接起来。
提前致歉,但文中没有给出使用代码的这种技术的例子,所以我不能分享一个代码片段来说明它。
正文如下。
有时,并非所有较小的 RDD 都适合内存,但某些键在大型数据集中的表现如此之多,以至于您只想广播最常见的键。如果一个键太大以至于不能放在单个分区上,这将特别有用。在这种情况下,您可以在大型 RDD 上使用 countByKeyApprox 来大致了解哪些键最能从广播中受益。然后,您只为这些键过滤较小的 RDD,在 HashMap 中本地收集结果。使用 sc.broadcast,您可以广播 HashMap,以便每个工作人员只有一个副本并手动执行对 HashMap 的连接。然后,使用相同的 HashMap,您可以过滤大型 RDD 以不包含大量重复键并执行标准联接,将其与手动联接的结果结合起来。
对于那些不知道的人,广播连接是一种技术,用户可以通过将较小的数据块发送给每个执行程序来避免连接两个数据块时发生的洗牌。然后每个执行者自己执行连接。这个想法是,洗牌是如此昂贵,以至于让每个执行者执行连接然后丢弃它不需要的数据有时是最好的方法。
文本描述了可以使用广播连接提取和连接数据块的一部分的情况。然后将连接的结果与其余数据合并。
这可能是必要的原因是,通常可以通过确保由两个块中的相同键组成的数据都存在于同一个分区中来避免过度洗牌,以便同一个执行程序处理它。但是,在某些情况下,单个键太大而无法容纳在单个分区上。在这种情况下,作者建议将过度表示的键分离为 HashMap 并仅对过度表示的键执行广播连接可能是一个好主意。
这是一个好主意吗?而且,像这样的技术看起来非常有情景,所以 Catalyst 可能不会使用这种技术。那是对的吗?Catalyst 是否真的不使用这种技术?如果是这样,这是否意味着在高度倾斜的数据上,这种使用 RDD 的技术可以击败在 Dataframes 或 Datasets 上运行的 Catalyst?