AWS红移磁盘键和倾斜



我遇到一种情况,我将磁盘键定义为用于将其与其他表连接(以避免重新分发)的列。但是该列不是基数最高的列,所以它会导致数据分布的倾斜。

的例子:

事务表(20M行)

------------------------------
|   user_id           | int  |
|   transaction_id    | int  |
|   transaction_date  | date |
------------------------------

假设在这个表上执行的大多数连接都是在user_id上执行的,但是transaction_id是基数更高的列。因为一个用户可以有多个事务。

在这种情况下应该怎么做?

  • 在transaction_id列上分发表?即使在user_id上与另一个表连接时需要重新分配数据

  • 分布在user_id上,让数据歪斜?在我的例子中,倾斜系数是~15,远远高于AWS红移推荐的倾斜系数4.0

正如John所说,您可能希望倾向于提高连接性能而不是数据倾斜,但这是基于大量可能正确的假设。我在这里列出一些:

  1. 分布(基于磁盘的)倾斜位于主要事实表
  2. 其他表也分布在连接键
  3. 上。
  4. 连接通常在原始表上进行,或者在dist键上执行组连接

Redshift是一个网络集群,节点之间的互连是架构中最低带宽的方面(不是低带宽,只是比其他方面低)。在节点之间移动非常大量的数据是Redshift的反模式,应该尽可能避免。

磁盘倾斜是数据存储在集群中的位置的度量,没有基于查询的信息只影响数据存储的效率。磁盘倾斜的更大影响是执行倾斜——执行查询时每个CPU(片)所做的工作量的差异。由于每个查询的第一步是让每个片处理它"拥有"的数据,因此磁盘倾斜会导致一定程度的执行倾斜。有多少取决于许多因素,尤其是问题中的查询。磁盘倾斜可能导致问题,在某些情况下,这可能超过重新分配成本。由于Redshift的切片性能很高,所以执行倾斜通常不是驱动性能的首要因素。

现在(几乎)所有查询在执行时都必须执行一定数量的数据重新分配。如果您通过一些非磁盘键列对两个表执行group-by,然后将它们连接起来,那么执行连接将需要重新分配。好消息是(希望如此)分组后的数据量会很小,这样重新分配的成本就会很低。重分配的数据量才是关键。

表的distkey只是控制重分发数据量的一种方式。有一些方法可以做到这一点:

  1. 如果维度表是dist-style ALL,那么它不(在基本情况)关系到事实表是由user_id分发的需要连接的数据已经存在于需要连接的节点上。
  2. 您还可以通过减少如何重新分配来控制数据的数量大量数据进入连接。最早有where从句查询中的阶段可以做到这一点。反规范化数据,以便子句列出现在事实表中的位置可能非常大赢。
  3. 在极端情况下,您可以使派生的磁盘键列对齐非常适合user_id,但也大大减少了磁盘和执行倾斜。这是一个更深层次的话题答案,但可以是答案,当你需要最大性能的时候再分配和倾斜是冲突的。

简单说一下"平凡"。这是一个经验法则度量,许多Redshift文档将其作为一种让新用户远离麻烦的方法,但也可以快速解释。这是一种(有用的)过度简化。更高的有序度并不总是更好,在极端情况下是一种反模式——考虑一个表,其中每一行的磁盘键都有一个唯一的值,现在考虑在该表的其他列上执行group-by。本例中的数据倾斜是完美的,但是分组的性能会很差。你想要分发数据来加快需要完成的工作,而不是改进一个指标。

相关内容

  • 没有找到相关文章

最新更新