临时变量如何在 Worker 上可用

Posted

技术标签:

【中文标题】临时变量如何在 Worker 上可用【英文标题】:How Transient Variables are available on Workers 【发布时间】:2016-08-29 15:34:02 【问题描述】:

我想知道工作人员如何使用瞬态变量。 例如:- 通过序列化 MapFunction 对象,从驱动程序将映射任务命令发送到执行程序。执行器反序列化命令,并在分区上执行它。 现在,如果在那个 mapFunction 中我使用了一个瞬态变量,它如何在工作人员上可用,因为它没有被序列化并发送给工作人员。

同样在以下链接https://www.mapr.com/blog/how-log-apache-spark的例子中

例子:

Class Test

transient static SparkSession sparkSession;

public static void main(String[] args)


    sparkSession = //Initialize SparkSession

    Dataset<Row> dataset = sparkSession.read().csv("A.csv");

    dataset.createOrReplaceTempView("TEMP_TABLE");

    Dataset<Row> dataset2 = sparkSession.sql("SELECT * FROM TEMP_TABLE");

    Dataset<String> stringDataset = dataset2.map((MapFuction<Row,String>) (row)->

                        Dataset<Row> tempDataset = sparkSession.sql("SELECT NAME FROM TEMP_TABLE WHERE ID='" + row.getString(0) + "'");

                        String temp = tempDataset.first().getString(0);

                        return temp;
                    ,Encoders.STRING());

    stringDataset.show();       


在上面的示例中,sparkSession 是如何在工作人员上解决的,因为它是在驱动程序上创建的,并且在将关闭发送给工作人员时 sparkSession 没有发送,因为它没有被序列化,所以它不应该在工作人员上为空,但事实并非如此。为什么?

由于 sparkSession 是一个静态变量,所以它存储在类定义中,所以当该闭包发送给工作人员时,测试类定义是否也通过序列化闭包发送给工作人员?

【问题讨论】:

请显示您使用的确切代码。 代码中还需要什么? 有什么可以遵守的吗?例如,我认为 sparkSession 必须是静态的。 哦,抱歉,它是静态的,我只是提供了一个示例代码。我想知道的是临时变量在workers上是如何可用的。我刚刚通过网上看写了一个临时变量的示例程序。 请查看问题中的示例链接 【参考方案1】:

我不确定 lambda 是如何序列化的,但您创建的 lambda 肯定引用了 sparkSession 的值。 lambda 中使用的任何内容都将成为它的一部分。

【讨论】:

感谢您的回答,是的,lambda 具有对 sparkSession 的引用,但是工作人员如何具有相同的引用。由于 sparkSession 是一个静态变量,所以它存储在类定义中,所以当该闭包发送给工作人员时,测试类定义是否也通过序列化闭包发送给工作人员? 发送给工作人员的不是“变量”,而是变量引用的对象。所以Test 类不相关,变量sparkSession 不相关。相关的是使用 lambda 序列化的 SparkSession 类的实例。在内部,该实例由实现 lambda 的类的隐藏成员变量持有。 控制权返回驱动程序执行瞬态变量行部分,并再次返回工作人员执行其余部分。今天有人告诉我这个,但我不相信,所以我想确定它是否真的像那样工作。 据我所知,Lambda 的整个执行都发生在 executor 上。该系统依赖于驱动程序 JVM 和执行程序 JVM(或线程,但在这种情况下很明显)可用的相同代码(相同的 jar)。 (编辑:“执行变量”?这是不对的) 确实如此。 更改 静态变量 after 你创建了 lambda 什么都不做。但是序列化的 lambda 本身包含会话对象的状态副本(不是变量,它引用的 OBJECT),就像它在 lambda 序列化时一样。当 lambda 在另一个 JVM 上反序列化时,会创建一个 NEW 会话对象,并将该对象的状态设置为与原始 JVM 中会话对象的状态完全相同。当然,变量在新的 JVM 中不存在。唯一引用新对象的是 lmbd 中的 hdden 字段

以上是关于临时变量如何在 Worker 上可用的主要内容,如果未能解决你的问题,请参考以下文章

window配置临时环境变量

模板表达式如何摆脱临时变量

如何使用临时变量交换两个以上的变量

如何在 NSPredicate 中定义临时变量?

如何拆分字符串并将其存储在临时变量中[重复]

如何将临时变量声明为 C# 表达式?