Межпроцессное взаимодействие с использованием ZeroMQ: передача больших массивов

Мне нужно установить связь между процессом Scala (JeroMQ) и процессом C (ZeroMQ). Процесс Scala должен отправлять большие массивы (100 миллионов чисел с плавающей запятой на массив). Сначала это преобразуется в строку JSON, и, как вы можете видеть ниже, у меня возникают проблемы с памятью:

java.lang.OutOfMemoryError: Requested array size exceeds VM limit
    at java.lang.StringCoding.encode(StringCoding.java:350)
    at java.lang.String.getBytes(String.java:939)
    at org.zeromq.ZMQ$Socket.send(ZMQ.java:1276)

100 миллионов чисел с плавающей запятой соответствуют 762 МБ. Мне кажется, что сериализованная строка JSON становится огромной. Если да, то как лучше всего передавать данные такого размера.


person user1274878    schedule 29.03.2016    source источник
comment
Ваш вариант использования как-то выигрывает или наказывает за передачу такого большого объема данных? Как правило, системы, ориентированные на задержку и работающие в реальном времени, могут скорее выиграть от распределенной обработки и, таким образом, передать только минималистичный продукт для принятия решений (защищенный для отказоустойчивого метода работы), необходимый в удаленном процессе. Считаете ли вы, что это гораздо более эффективный способ распределенной обработки?   -  person user3666197    schedule 29.03.2016
comment
лучшее основано на мнении, поэтому голосование за закрытие. Если вы хотите это исправить, определите точные критерии наилучшего. Кстати: Вы искали в Интернете сообщение об ошибке?   -  person Ulrich Eckhardt    schedule 29.03.2016
comment
@ user3666197: я интегрирую свой OpenCL (код C) с Apache Spark. Клиент Spark, работающий на узле, получит большой объем данных, которые будут отправлены процессу C и в конечном итоге переданы на GPU. Итак, да, мне нужно передавать большой объем данных между двумя процессами.   -  person user1274878    schedule 29.03.2016
comment
как объяснено ниже, ваши варианты были бы гораздо более многообещающими, если бы вам удавалось поддерживать постоянно зеркальную или теневую реплику данных, которая постепенно строится в естественном порядке/темпе с полной эволюцией базовой модели ( наблюдения). Любая попытка переместить специальную копию (через любую форму BLOB) постфактум в основном пострадает от описанных ниже неблагоприятных воздействий.   -  person user3666197    schedule 30.03.2016


Ответы (3)


Как предлагает страница часто задаваемых вопросов ZeroMQ, вы можете использовать любой формат сортировки данных, который поддерживается как в Java (и, следовательно, в Scala ) и C. Их много (для некоторых поддержка C является сторонней, хотя C++ обычно нет): Protocol Buffers, MsgPack, Avro, Thrift, BSON и т. д.

person Alexey Romanov    schedule 29.03.2016

Во-первых, в json или любом другом формате сериализации данных нет ничего, что делало бы его нежизнеспособным для больших наборов данных — вам просто нужно убедиться, что на вашем компьютере есть необходимые ресурсы для его обработки.

Некоторые форматы могут быть более эффективными с точки зрения использования памяти, чем другие, скорее всего, вам больше подойдет двоичный формат.

Однако, в зависимости от ваших обстоятельств (например, если вам постоянно требуется обновленный доступ ко всему набору данных), ответ user3666197, вероятно, больше подходит для вашего сценария.

Позвольте мне разделить разницу.

Если ваш вариант использования соответствует следующим параметрам:

  1. Вам нужен редкий доступ ко всему набору данных.
  2. Вы можете справиться с длительными задержками
  3. Вы не можете увеличить ресурсы, доступные на хосте-получателе.
  4. Вы не можете (или это непозволительно сложно) создать постоянно обновляемое локальное хранилище данных на принимающем хосте.

... тогда лучше всего просто разделить набор данных. Посмотрите, насколько большое сообщение вы можете отправить и проанализировать, не исчерпав ресурсы, дайте себе где-то между 20-50% буфера (в зависимости от вашей терпимости), разделите свои данные на куски соответствующего размера, отправьте куски и соберите их заново. . Это работает при условии, что проблема с памятью возникает из-за одновременной работы с сериализованными и несериализованными данными в памяти в процессе десериализации. Если это неправда, а несериализованный набор данных сам по себе слишком велик, чтобы поместиться в памяти, вам придется просто обрабатывать данные по частям без их повторной сборки. В таком случае я настоятельно рекомендую найти какой-нибудь способ увеличить ресурсы памяти, потому что вы живете на грани.

person Jason    schedule 04.04.2016

Размер? Нет, ограничение, связанное с транспортной философией, имеет значение.

В оркестровке транспорта ZeroMQ есть более важная проблема, чем выбор политики SER/DES для внешнего сериализатора данных.

Никто не может запретить вам пытаться отправлять как можно большие BLOB, хотя строка, оформленная в JSON, уже показала вам темную сторону таких подходов, есть и другие причины не идти по этому пути. .

ZeroMQ, вне всякого сомнения, отличный и мощный набор инструментов. Тем не менее, требуется некоторое время, чтобы получить представление, необходимое для действительно умного и высокопроизводительного развертывания кода, которое максимально использует эту мощную рабочую лошадку.

Одним из побочных эффектов многофункциональной внутренней экосистемы «под капотом» является малоизвестная политика, скрытая в концепции доставки сообщений.

Можно отправить любое сообщение разумного размера, при этом доставка не гарантируется. Оно либо полностью доставлено, либо вообще ничего не выходит, как сказано выше, ничего не гарантируется.

Ой?!

Да, не гарантируется.

Основываясь на этой базовой философии Zero-Guarantee, нужно тщательно выбирать шаги и меры, особенно если вы планируете перемещать «Gigabyte BEAST» туда и обратно.

Именно в этом смысле может быть количественно подтверждено реальным тестированием SUT, что сообщения небольшого размера могут передаваться (если вам действительно все еще нужно перемещать GB-s ( ref. комментировать выше, под OP) и не иметь другого выбора) весь объем данных сегментирован на более мелкие части с подверженными ошибкам мерами повторной сборки, что приводит к гораздо более быстрому и гораздо более безопасному завершению окончательное решение, чем пытаться использовать тупую силу и указывать коду сбрасывать около GB данных на любые доступные ресурсы (принцип Zero-Copy ZeroMQ не может и не будет сам по себе спасти вас в этих усилиях).

Для получения подробной информации о другой скрытой ловушке, связанной с неполной реализацией Zero-Copy, прочитайте Мартина САСТРИКА, соучредителя ZeroMQ, замечает о Zero-Copy "до границы ядра" (так что, как минимум удвоить ожидаемое выделение пространства памяти...).< /а>


Лучший следующий шаг?

Хотя это и не решит вашу проблему с помощью нескольких SLOC-ов, лучше всего, если вы серьезно намерены вложить свои интеллектуальные силы в распределенную обработку, прочитать прекрасную книгу Питера ХИНТЬЕНА "Code Connected, Том 1"

Да, требуется некоторое время, чтобы сформировать собственное понимание, но это поднимет вас во многих аспектах на другой уровень профессионального проектирования кода. Стоит потратить время. Стоит усилий.

person user3666197    schedule 29.03.2016