我正在研究局部性如何影响火花SQL作业中的任务读取时间。
测试:
- 为了方便分析,我运行一个简单的SQL查询,该查询执行表扫描并且不返回任何数据,该任务需要时间读取块,然后对其进行处理。
- 查询:"创建表target_table为 从source_table中选择 *,其中 column_name>1000"。
- 选择性等于 0(即column_name永远不会是 1000 的刨丝器)
- Spark 上下文仅使用一个执行器创建,以便观察NODE_LOCAL和RACK_LOCAL任务。
- 我的集群由 7 个节点组成,每个节点在单个机架中配备 8 个内核,并通过千兆位 swithch(1 GB 点对点)链接在一起
在进入我的问题之前,我想陈述几个假设:
- 每个任务处理一个块
- 由于首选数据局部性,因此驱动程序首先分配NODE_LOCAL任务,然后分配RACK_LOCAL任务
- 当分配了多个VCore时,任务最初在本地硬盘驱动器上竞争以获取其块,然后在其他节点上远程完成获取
- 网络吞吐量优于硬盘驱动器吞吐量,因此在压力下硬盘驱动器是瓶颈
最后问题是:)
当在单个执行器中分配许多 VCore(例如 8 个)时,鉴于上述假设,我希望RACK_LOCAL任务的读取时间比NODE_LOCAL任务的读取时间快。
根据我的测试,RACK_LOCAL阅读时间平均比NODE_LOCAL慢几个百分点,如图所示。显然我错过了一些东西,但我四处挖掘而没有给出原因。这是什么东西?
链接的图显示了不断增加的 VCore 数量NODE_LOCAL和RACK_LOCAL平均任务持续时间。
谢谢洛伦佐
实际上,我发现我的一个假设是不正确的:"网络吞吐量优于硬盘驱动器吞吐量,因此在压力下硬盘驱动器是瓶颈"
千兆交换机的平均运行速度是其 0.8,这意味着两个节点链接在一起,网络吞吐量为 100MB/s。 HDD 通常可以以 150MB/s 的速度读取。
由于远程读取和网络传输是在管道中执行的,因此NODE_LOCAL和RACK_LOCAL之间的微小差异是由于读取和传输之间发生的远程缓冲时间
>RACK_LOCAL表示从远程节点上的HDD读取块,然后通过网络传递。NODE_LOCAL意味着正在该节点上读取一个块,因此省略了"网络"部分,因此NODE_LOCAL通常应该更快。