Десериализация бед с clojure и игристые - PullRequest
0 голосов
/ 24 августа 2018

Я новичок в Spark и довольно новичок в Clojure (хотя мне действительно нравится то, что Clojure может делать до сих пор).В настоящее время я пытаюсь проанализировать JSON в Clojure с помощью сверкающего файла, и у меня возникают проблемы с основами преобразования данных и их возврата в форму, которую я могу понять и отладить.Я использую фиктивные данные в приведенном ниже примере, но мои фактические данные превышают 400 ГБ.

В качестве примера я сначала попытался разбить каждую строку ввода JSON (каждая строка является полной записью) запятыми, чтобы ябудет иметь список ключей и значений (для возможного преобразования в ключевые слова и карты значений).В Scala (для которой проще найти примеры Spark) с фиктивными данными это прекрасно работает:

val data = sc.parallelize(Array ("a:1,b:2","a:3,b:4"))
val keyVals = data.map(line => line.split(","))
keyVals.collect()

Возвращает Array [Array [String]] = Array (Array (a: 1, b:2), Array (a: 3, b: 4)), который является по крайней мере разумной отправной точкой для сопоставления значения ключа.

Однако, когда я запускаю следующее в clojure с игристым:

(def jsony-strings (spark/parallelize sc ["a:1,b:2","a:3,b:4"]))
(def jsony-map (->> jsony-strings
     (spark/map (fn [l] (string/split l #",")))
               ))

(spark/collect jsony-map)

Я получаю обычные спагетти параллелизма от JVM, суть которых, кажется, такова:

2018-08-24 18: 49: 55,796 WARN serialization.Utils: 55 - Ошибка десериализации объекта(clazz: gdelt.core $ fn__7437, пространство имен: gdelt.core)

java.lang.ClassNotFoundException: gdelt.core $ fn__7437

Это ошибка, которую я, по-видимому, получаю почти все, что япопробуйте сделать что-то более сложное, чем подсчет.

Может кто-нибудь указать мне правильное направление?


Полагаю, я должен заметить, что моя большая проблема - это обработка множества строкJSON в наборе данных больше, чем память (400G).Я буду использовать ключи JSON для фильтрации, сортировки, вычисления и т. Д., И конвейеры Spark выглядели хорошими как для быстрой параллельной обработки, так и удобными для этих функций.Но я, безусловно, открыт для рассмотрения других альтернатив для обработки этого набора данных.

1 Ответ

0 голосов
/ 24 августа 2018

Вы должны использовать Чешир для этого:

;; parse some json
(parse-string "{\"foo\":\"bar\"}")
;; => {"foo" "bar"}

;; parse some json and get keywords back
(parse-string "{\"foo\":\"bar\"}" true)
;; => {:foo "bar"}

Мне нравится использовать ярлык для второго случая, так как я всегда хочу преобразовать строковые ключив ключевые слова clojure:

(is= {:a 1 :b 2} (json->edn "{\"a\":1, \"b\":2}"))

Это просто простая оболочка с (я думаю) более легким для запоминания именем:

(defn json->edn [arg] 
  "Shortcut to cheshire.core/parse-string"
  (cc/parse-string arg true))             ; true => keywordize-keys

(defn edn->json [arg] 
  "Shortcut to cheshire.core/generate-string"
  (cc/generate-string arg))

Обновление: Обратите внимание, что Cheshire может работать с ленивыми потоками:

;; parse a stream lazily (keywords option also supported)
(parsed-seq (clojure.java.io/reader "/tmp/foo"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...