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;
  }

在此处查看问题单:https://issues.apache.org/jira/browse/SPARK-17814