Scala Spark SQL表最大列数

Scala Spark SQL表最大列数,scala,apache-spark-sql,Scala,Apache Spark Sql,我试图通过在Scala程序中创建列数为200+的RDD来创建spark SQL表。当我以以下方式创建架构时,编译(sbt编译)失败,java.lang.StackOverflower异常: StructField(“RT”,StringType,nullable=true):: StructField(“SERIALNO”,StringType,nullable=true):: StructField(“SPORDER”,StringType,nullable=true):: // ... 剩余

我试图通过在Scala程序中创建列数为200+的RDD来创建spark SQL表。当我以以下方式创建架构时,编译(sbt编译)失败,java.lang.StackOverflower异常:

StructField(“RT”,StringType,nullable=true)::
StructField(“SERIALNO”,StringType,nullable=true)::
StructField(“SPORDER”,StringType,nullable=true)::
// ... 剩余200多列
无法粘贴stacktrace,因为它超过1.5k行

将列数减少到100-120左右时,编译成功。此外,当我使用模式字符串创建模式(拆分模式字符串,然后创建其映射)时,编译成功(标题“下的第一个示例以编程方式指定中的模式”)


手动指定会导致异常的架构似乎有什么问题?

这里的基本问题是,您在每个步骤中为每个StructField执行列表连接。运算符::实际上是List not StructField的成员。而代码是:

val fields = field1 :: field2 :: field3 :: Nil
这相当于:

val fields = field1 :: (field2 :: (field3 :: Nil))
甚至

val fields = Nil.::(field1).::(field2).::(field3)
因此,在执行时,JVM需要递归地计算对
方法的调用。JVM正在根据列表中的项目数按比例增加堆栈的深度。拆分字段名字符串和映射之所以有效,是因为它遍历拆分的字段名字符串,而不是使用递归

这不是火花问题。一旦进入数百个项目,您就可以在Scala repl中的任何类型的一系列列表串联上重现相同的堆栈溢出错误。只需使用另一种方法来创建不会导致堆栈溢出的StructFields列表

例如,类似这样的方法可以很好地工作:

val structure = StructType(
  List(
    StructField("RT", StringType,nullable = true),
    StructField("SERIALNO", StringType,nullable = true),
    StructField("SPORDER", StringType,nullable = true),
    // Other Fields
    StructField("LASTFIELD", StringType,nullable = true)
  )
)

这里的基本问题是,在每个StructField的每个步骤中都要进行列表连接。运算符::实际上是List not StructField的成员。而代码是:

val fields = field1 :: field2 :: field3 :: Nil
这相当于:

val fields = field1 :: (field2 :: (field3 :: Nil))
甚至

val fields = Nil.::(field1).::(field2).::(field3)
因此,在执行时,JVM需要递归地计算对
方法的调用。JVM正在根据列表中的项目数按比例增加堆栈的深度。拆分字段名字符串和映射之所以有效,是因为它遍历拆分的字段名字符串,而不是使用递归

这不是火花问题。一旦进入数百个项目,您就可以在Scala repl中的任何类型的一系列列表串联上重现相同的堆栈溢出错误。只需使用另一种方法来创建不会导致堆栈溢出的StructFields列表

例如,类似这样的方法可以很好地工作:

val structure = StructType(
  List(
    StructField("RT", StringType,nullable = true),
    StructField("SERIALNO", StringType,nullable = true),
    StructField("SPORDER", StringType,nullable = true),
    // Other Fields
    StructField("LASTFIELD", StringType,nullable = true)
  )
)

请在你的错误堆栈上创建一个要点,并将其添加到问题中!你的问题现在是无法挽回的,而且范围很广,因此很明显,它将被投票表决为接近。我猜自动模式检测使用递归,它是
tailrec
。我会在Spark JIRA上发布一个问题。@Reactormonk无需报告。这是一个Scala“问题”,而不是火花问题。请看下面。在错误堆栈上创建一个要点,并将其添加到问题中!你的问题现在是无法挽回的,而且范围很广,因此很明显,它将被投票表决为接近。我猜自动模式检测使用递归,它是
tailrec
。我会在Spark JIRA上发布一个问题。@Reactormonk无需报告。这是一个Scala“问题”,而不是火花问题。见下文。