2016-06-09 3 views
0

Я новичок в Scala и, очевидно, не понимаю, почему этот код не работает.Scala. Пустая переменная после сопоставления

Я создаю массив из первого DataFrame и при создании второго массива запускает проверку идентичных данных в обоих массивах. В случае идентичных данных - переменная оснастки текст.

var text = "Hello!" 
val dfOriginDate = sqlContext.sql("SELECT name, age FROM table2") 
val arrOriginDate = dfOriginDate.rdd.map(r => { 
    r(0).toString + r(1).toString 
    }).collect() 

val dfNewDate = sqlContext.sql("SELECT name, age FROM table") 
dfNewDate.rdd.map(r => { 
    if (arrOriginDate contains(r(0).toString + r(1).toString)) { 
    text += "found some stupid things" 
    print(text + " for the first time\r\n") 
    } 
}).collect() 

println(text + " for the second time") 

На выходе у меня есть это:

Hello! found some stupid things for the first time 
Hello! for the second time 

Почему, когда я печатаю текст в то время как отображение переменной реализуется, но когда я печатаю его снова после того, как карта - кажется, что это никогда не был на карте?

__

И когда я пытаюсь сделать это с ListBuffer[String]() он дал мне тот же эффект.

То, что я пытаюсь сделать с этим кодом - найти одинаковые данные в разных таблицах от Кассандры __ Не знаю, какой ответ лучше> < и приемлемо для моей проблемы =)

ответ

1

Функции что вы пишете rdd.map, делает ОГРОМНЫЕ вещи на бэкэнде. Причина, по которой вы видите это поведение, состоит в том, что ваш основной код и функция rdd.map работают в разных потоках. Переменные не могут проходить и обратно просто в случае параллельного контекста.

Для этого используйте для этого accumulator. Вот почему никогда не рекомендуется использовать изменяемые переменные. Это смущает вас в тех местах, где вы не должны были застревать, если бы они были неизменными.

+0

Спасибо! Мне кажется, мне нужно прочитать какую-нибудь книгу о Scala \ Spark combination =) – ANTVirGEO

+0

Как метод обучения попробуйте использовать класс, который не является сериализуемым (в отличие от String). Вы получите исключение, исключающее сериализацию объекта. Что происходит во время выполнения кода: Вы ссылаетесь на переменную из локального контекста в параллельном контексте. Переменная получает сериализован и передается (через сеть, если задача выполняется на разных машинах) в mapper. – Sohaib

1

Речь идет не о Scala, это проблема Spark. Вы не можете использовать изменяемые переменные, подобные этому, потому что код в анонимных функциях, переданный в map, будет выполнен на других машинах (это точка использования Spark!) И изменит их копия text, а не та, что в водитель.

Подробное описание http://spark.apache.org/docs/latest/programming-guide.html#understanding-closures-a-nameclosureslinka с очень похожим примером.

+0

Большое спасибо, не запечатлел всю картину в моем сознании – ANTVirGEO