2016-02-24 2 views
1

Я пытаюсь создать таблицу искры SQL, создав RDD в программе Scala с числом столбцов 200+. Компиляция (SBT компиляции) не с исключением java.lang.StackOverflowError, когда я создаю мой схемы, как:Spark SQL table max column count

StructField("RT", StringType,nullable = true) :: 
StructField("SERIALNO", StringType,nullable = true) :: 
StructField("SPORDER", StringType,nullable = true) :: 
// ... remaining 200+ columns 

Не удается вставить StackTrace как это больше, чем 1.5K линии

При уменьшении количество столбцов до 100-120 компиляция завершается успешно. Кроме того, когда я создаю схему с использованием строки схемы (расщепляя строку схемы и затем создавая ее карту), компиляция завершается успешно (первый пример под заголовком «с программным указанием схемы» в https://spark.apache.org/docs/1.3.0/sql-programming-guide.html).

Что, по-видимому, связано с ручной установкой схемы, которая приводит к исключению?

+1

Создать суть над стеком ошибок и добавить его на вопрос, пожалуйста! Ваш вопрос не спасен, как сейчас, и довольно широко, так что он будет проголосован за закрытие. – eliasah

+0

Я предполагаю, что автоматическое обнаружение схемы использует рекурсию, и это 'tailrec'. Я бы опубликовал вопрос о Spark JIRA. – Reactormonk

+0

@Reactormonk Не нужно сообщать об этом. Это вопрос «Scala», а не проблема Spark. Смотри ниже. – DemetriKots

ответ

2

Основная проблема заключается в том, что вы выполняете конкатенацию списка на каждом этапе для каждого StructField. Оператор :: на самом деле является членом List not StructField. Хотя код гласит:

val fields = field1 :: field2 :: field3 :: Nil 

Это эквивалентно:

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

или даже

val fields = Nil.::(field1).::(field2).::(field3) 

Так, на исполнение, виртуальная машина должна рекурсивно оценить вызовы метода :: , JVM увеличивает глубину стека пропорционально количеству элементов в списке. Причина, по которой разделение строки имен полей и работы по составлению карт происходит из-за того, что она выполняет итерацию через разделенную строку имен полей, а не используя рекурсию.

Это не проблема искры. Вы можете воспроизвести эту же ошибку переполнения стека в серии конкатенаций List любого типа в 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) 
) 
)