Scala via Spark with yarn - 缺少大括号字符串
Scala via Spark with yarn - curly brackets string missing
我做了一些 scala 代码,它看起来像这样。
object myScalaApp {
def main(args: Array[String]) : Unit = {
val strJson = args.apply(0)
println( "strJson : " + strJson)
并从 yarn 中调用这个 scala jar 文件。
Process spark = new SparkLauncher()
.setAppResource("/usr/local/myJar/myApp.jar")
.setMainClass("com.myScalaApp")
.setMaster("yarn")
.setDeployMode( "cluster")
.addAppArgs( data)
.launch();
当我设置 json 如下所示的字符串时
{\"aaa\" : \"a1111\",\"bbbb\" : \"b1111\"}
它打印在下面(如我所料)
strJson : {"aaa" : "a1111","bbbb" : "b1111"}
但是当我设置 json 如下所示的字符串时
{\"aaa\" : \"a1111\",\"bbbb\" : \"b1111\",\"ccc\" : {\"c1\" :
\"c111\"}}
它打印在下面
strJson : {"aaa" : "a1111","bbbb" : "b1111","ccc" : {"c1" : "c111"
为什么所有的右花括号都消失了?
额外样本
1
\"{\"aaa\" : \"a1111\",\"bbbb\" : \"b1111\",\"ccc\" : {\"c1\" :
\"c111\"}}\"
strJson : "{"aaa" : "a1111","bbbb" : "b1111","ccc" : {"c1" : "c111""
2
{\"aaa\" : \"a1111\",\"bbbb\" : \"b1111\",\"ccc\" : {\"c1\" :
\"c111\"}a}
strJson : {"aaa" : "a1111","bbbb" : "b1111","ccc" : {"c1" : "c111"}a}
我想你错过了字符串开头和结尾的双引号。
请尝试使用双引号
"{\"aaa\" : \"a1111\",\"bbbb\" : \"b1111\",\"ccc\" : {\"c1\" : \"c111\"} }";
为什么不用三引号?
""" {"aaa" : "a1111","bbbb" : "b1111","ccc" : {"c1" : "c111"}} """
它更容易阅读,并且会解决您的问题。
我仍然不确定为什么会这样,但可以通过在大括号之间添加 'space' 来解决,如下所示。
}} -> } }
这个问题的发生是因为 YARN 尝试用对环境变量的引用替换命令中的参数扩展标记 {{
和 }}
。
例如,如果您将 run_job.sh {{MY_VARIABLE}}
传递给 YARN,它会将其转换为 run_job.sh $MY_VARIABLE
,以便使用环境变量。
因此,如果您在命令行中使用嵌套对象 JSON(或其他带有两个花括号的东西),就会发生此问题。只有当您使用 YARN 作为主节点和集群部署模式时才会发生这种情况。 Spark standalone 和 YARN 客户端模式不受影响。
要解决此问题,请使用 JSON 以外的其他数据格式,或者确保两个花括号没有相邻。
例如 Python 你可以像这样快速解决这个问题:
def fix_json_for_yarn(json_string):
# See https://issues.apache.org/jira/browse/SPARK-17814
# Due to that YARN bug we need to make sure that our json string
# doesn't contain {{ or }} because those get replaced by YARN.
return json_string.replace("}}", "} }").replace("{{", "{ {")
您可以在此处查看有问题的 YARN 代码:
@VisibleForTesting
public static String expandEnvironment(String var,
Path containerLogDir) {
var = var.replace(ApplicationConstants.LOG_DIR_EXPANSION_VAR,
containerLogDir.toString());
var = var.replace(ApplicationConstants.CLASS_PATH_SEPARATOR,
File.pathSeparator);
// replace parameter expansion marker. e.g. {{VAR}} on Windows is replaced
// as %VAR% and on Linux replaced as "$VAR"
if (Shell.WINDOWS) {
var = var.replaceAll("(\{\{)|(\}\})", "%");
} else {
var = var.replace(ApplicationConstants.PARAMETER_EXPANSION_LEFT, "$");
var = var.replace(ApplicationConstants.PARAMETER_EXPANSION_RIGHT, "");
}
return var;
}
我做了一些 scala 代码,它看起来像这样。
object myScalaApp {
def main(args: Array[String]) : Unit = {
val strJson = args.apply(0)
println( "strJson : " + strJson)
并从 yarn 中调用这个 scala jar 文件。
Process spark = new SparkLauncher()
.setAppResource("/usr/local/myJar/myApp.jar")
.setMainClass("com.myScalaApp")
.setMaster("yarn")
.setDeployMode( "cluster")
.addAppArgs( data)
.launch();
当我设置 json 如下所示的字符串时
{\"aaa\" : \"a1111\",\"bbbb\" : \"b1111\"}
它打印在下面(如我所料)
strJson : {"aaa" : "a1111","bbbb" : "b1111"}
但是当我设置 json 如下所示的字符串时
{\"aaa\" : \"a1111\",\"bbbb\" : \"b1111\",\"ccc\" : {\"c1\" : \"c111\"}}
它打印在下面
strJson : {"aaa" : "a1111","bbbb" : "b1111","ccc" : {"c1" : "c111"
为什么所有的右花括号都消失了?
额外样本
1
\"{\"aaa\" : \"a1111\",\"bbbb\" : \"b1111\",\"ccc\" : {\"c1\" : \"c111\"}}\"
strJson : "{"aaa" : "a1111","bbbb" : "b1111","ccc" : {"c1" : "c111""
2
{\"aaa\" : \"a1111\",\"bbbb\" : \"b1111\",\"ccc\" : {\"c1\" : \"c111\"}a} strJson : {"aaa" : "a1111","bbbb" : "b1111","ccc" : {"c1" : "c111"}a}
我想你错过了字符串开头和结尾的双引号。 请尝试使用双引号
"{\"aaa\" : \"a1111\",\"bbbb\" : \"b1111\",\"ccc\" : {\"c1\" : \"c111\"} }";
为什么不用三引号?
""" {"aaa" : "a1111","bbbb" : "b1111","ccc" : {"c1" : "c111"}} """
它更容易阅读,并且会解决您的问题。
我仍然不确定为什么会这样,但可以通过在大括号之间添加 'space' 来解决,如下所示。
}} -> } }
这个问题的发生是因为 YARN 尝试用对环境变量的引用替换命令中的参数扩展标记 {{
和 }}
。
例如,如果您将 run_job.sh {{MY_VARIABLE}}
传递给 YARN,它会将其转换为 run_job.sh $MY_VARIABLE
,以便使用环境变量。
因此,如果您在命令行中使用嵌套对象 JSON(或其他带有两个花括号的东西),就会发生此问题。只有当您使用 YARN 作为主节点和集群部署模式时才会发生这种情况。 Spark standalone 和 YARN 客户端模式不受影响。
要解决此问题,请使用 JSON 以外的其他数据格式,或者确保两个花括号没有相邻。
例如 Python 你可以像这样快速解决这个问题:
def fix_json_for_yarn(json_string):
# See https://issues.apache.org/jira/browse/SPARK-17814
# Due to that YARN bug we need to make sure that our json string
# doesn't contain {{ or }} because those get replaced by YARN.
return json_string.replace("}}", "} }").replace("{{", "{ {")
您可以在此处查看有问题的 YARN 代码:
@VisibleForTesting
public static String expandEnvironment(String var,
Path containerLogDir) {
var = var.replace(ApplicationConstants.LOG_DIR_EXPANSION_VAR,
containerLogDir.toString());
var = var.replace(ApplicationConstants.CLASS_PATH_SEPARATOR,
File.pathSeparator);
// replace parameter expansion marker. e.g. {{VAR}} on Windows is replaced
// as %VAR% and on Linux replaced as "$VAR"
if (Shell.WINDOWS) {
var = var.replaceAll("(\{\{)|(\}\})", "%");
} else {
var = var.replace(ApplicationConstants.PARAMETER_EXPANSION_LEFT, "$");
var = var.replace(ApplicationConstants.PARAMETER_EXPANSION_RIGHT, "");
}
return var;
}