我有一个8节点集群,我从jdbc源加载了两个数据帧,如下所示:
positionsDf = spark.read.jdbc(
url=connStr,
table=positionsSQL,
column="PositionDate",
lowerBound=41275,
upperBound=42736,
numPartitions=128*3,
properties=props
)
positionsDF.cache()
varDatesDf = spark.read.jdbc(
url=connStr,
table=datesSQL,
column="PositionDate",
lowerBound=41275,
upperBound=42736,
numPartitions=128 * 3,
properties=props
)
varDatesDF.cache()
res = varDatesDf.join(positionsDf, on='PositionDate').count()
我可以从应用程序UI的存储选项卡中得知分区均匀分布在集群节点上。然而,我不知道的是它们是如何分布在节点上的。理想情况下,这两个数据框都应该以这样一种方式进行分布,即连接始终是节点的本地连接,或者最好是执行器的本地连接。
换句话说,将包含PositionDate="01 Jan 2016"记录的positionsDF dataframe分区,位于相同的执行器内存空间作为包含PositionDate="01 Jan 2016"记录的varDatesDf dataframe分区?它们会在同一个节点上吗?还是只是随机的?
是否有办法查看哪个节点上有哪些分区?
spark是否以确定性的方式跨节点分布使用这样的列键创建的分区?它们是否总是本地的节点/执行器?
包含PositionDate="01 Jan 2016"记录的positionsDF dataframe分区是否与包含PositionDate="01 Jan 2016"记录的varDatesDf dataframe分区位于相同的执行器内存空间
它不会是一般的。即使数据是共分区的(这里没有),也不意味着共定位。
是否有办法查看哪个节点上有哪些分区?
这种关系不需要随着时间的推移而固定。例如,任务可以重新安排。您可以使用不同的RDD
技巧(TaskContext
)或数据库日志,但它不可靠。
将以这样一种方式分布,即连接始终是节点的本地连接,甚至更好地是执行器的本地连接。
Scheduler有它的内部优化和低级api允许你设置节点首选项,但这类事情在Spark SQL中是不可控制的。