- 最新
- 投票最多
- 评论最多
【以下的回答经过翻译处理】 Toebs2是正确的,因为您无法控制具有单个DISTKEY值的文件将由哪个片段处理,因为Redshift不公开其散列算法和映射算法,其中一些散列值的某个函数映射(可能是一些形式)的环上的哪个片段。
其他分析列存储(如Vertica)公开此信息,因此支持数据加载优化,将文件直接分配给COPY命令中的节点(或片)。
但是,预分割要加载的文件将对性能产生影响。我只能说这个影响可能好也可能坏,或者由于其他因素影响而变化。有许多变量会影响对于任何给定的工作负载,或好或坏。
考虑一个一般情况,在其中有一个输入文件COPY命令,其中包含一个大量的DISTKEY值集,将分布到所有片段。该文件被指定为要处理的一个片段。这个片段,让我们称之为“启动片段”,必须自己执行以下步骤:
- 执行所有输入文件的文件读取。
- 将所有输入从输入格式(可能是分隔文本行之类的东西)解析为记录,并使用COPY命令中的信息验证字段数据类型。
- 计算每个记录的DISTKEY,这里是哈希值。
- 计算DISTKEY哈希映射到环形上的哪个片段以确定将存储该行的片段。
- 将该记录缓冲到目标片段。
- 将记录缓冲区发送到整个群集互连网络上的片段。
所有片段都必须独立执行以下步骤,包括执行上述所有工作的"initiator slice"(希望"initiator slice"采用内存映射的网络缓冲区快捷方式,以减轻其执行COPY命令时的一些不对称工作的成本):
- 接收要本地存储的记录缓冲区。
- 将该数据转换为Redshift列块。
- 对接收到的所有记录进行列块写入。
上述内容展示了在COPY命令中,对包含大量DISTKEY值的一个文件进行工作负载时,工作负载呈不对称分布,其中的"initiator slice"承担了大部分工作量,而目标片段的工作量相对较少。
现在很明显,当COPY命令只处理包含一个DISTKEY值的文件时,工作模式会退化为"initiator slice"只需要将网络缓冲发送到一个目标片段。总体而言,这将减轻"initiator slice"的工作负载,但会增加单个目标片段的工作负载。因此,这可能会导致处理该文件的吞吐量下降,因为只有一个网络路径被使用,而只有一个片段负责所有的块格式化和写入。
然而,还有其他整个集群的考虑因素。对于一个多文件COPY命令的最终一般情况,每个片段都需要处理一个或多个文件,并将记录缓冲发送到每个片段(这是最困难的工作),同时每个片段还接收来自其他片段的记录缓冲。实际上,这是一个完全混乱的集群通信任务,如果不饱和,则倾向于对集群互连网络施加高负载。
现在,如果我们将所有输入数据预先拆分为每个文件一个DISTKEY值,可以很容易地看出,虽然"initiator slices"上的负载减少了,因为它只需与一个目标片段通信,而每个目标片段的负载增加了,但整个集群互连网络的负载已经降低。也许这将使集群互连负载降低到饱和点以下,如果未饱和,则释放出集群互连网络的容量,以处理来自其他并发语句甚至其他并发COPY命令的片间通信。此外,减少的"initiator slice"工作量还为节点本地资源(如CPU、内存和集群互连网络带宽)释放了空间,以便处理其他并发语句的工作。因此,整体集群吞吐量可能会提高。
只有通过使用真实数据和真实SQL工作负载的真实世界基准测试,才能判断预先拆分COPY命令的输入文件是否会在语句级别或整体集群吞吐量级别上改善或降低性能。
如常所言,"结果因情况而异"。;-)
希望这有助于分解和解释COPY命令的工作如何在集群中分布,并对集群和片段级别的资源产生影响。
相关内容
- AWS 官方已更新 9 个月前
- AWS 官方已更新 8 个月前