Java: Сериализация огромного количества данных в один файл - PullRequest
5 голосов
/ 25 сентября 2008

Мне нужно сериализовать огромное количество данных (около 2 гигабайт) небольших объектов в один файл для последующей обработки другим процессом Java. Производительность очень важна. Кто-нибудь может предложить хороший метод для достижения этой цели?

Ответы [ 9 ]

4 голосов
/ 25 сентября 2008

Вы смотрели на буферы протокола Google ? Походит на случай использования для этого.

4 голосов
/ 25 сентября 2008

Я не знаю, почему в сериализации Java отказали, это совершенно жизнеспособный механизм.

Из исходного поста не понятно, но все ли 2G данных в куче одновременно? Или ты что-то еще выбрасываешь?

Сериализация из коробки не является «идеальным» решением, но если вы реализуете Externalizable на своих объектах, Serialization может работать просто отлично. Сериализация требует больших затрат, чтобы понять, что писать и как писать. Внедряя Externalizable, вы берете эти решения из-под контроля, тем самым значительно повышая производительность и экономя пространство.

Хотя ввод-вывод является основной стоимостью записи больших объемов данных, побочные затраты на преобразование данных также могут быть очень дорогими. Например, вы не хотите преобразовывать все свои числа в текст, а затем обратно, лучше, если возможно, сохранить их в более "родном" формате. ObjectStream имеет методы для чтения / записи собственных типов в Java.

Если все ваши данные предназначены для загрузки в единую структуру, вы можете просто сделать ObjectOutputStream.writeObject (yourBigDatastructure) после того, как вы реализовали Externalizable.

Однако вы также можете перебирать свою структуру и вызывать writeObject для отдельных объектов.

В любом случае вам понадобится некоторая подпрограмма «objectToFile», возможно, несколько. И это действительно то, что обеспечивает Externalizable, а также структура для обхода вашей структуры.

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

0 голосов
/ 31 января 2012

Apache Avro также может быть полезным. Он разработан, чтобы быть независимым от языка и имеет привязки для популярных языков .

Проверьте это.

0 голосов
/ 21 октября 2008

Я разработал JOAFIP в качестве альтернативы для базы данных.

0 голосов
/ 25 сентября 2008

Если производительность очень важна, вам нужно написать ее самостоятельно. Вы должны использовать компактный двоичный формат. Потому что с 2 ГБ операция ввода-вывода диска очень важна. Если вы используете любой читаемый человеком формат, например XML или другие сценарии, вы изменяете размер данных с коэффициентом 2 или более.

В зависимости от данных это может быть ускорено, если вы сжимаете данные на лету с низкой степенью сжатия.

Сериализация Java не нужна, поскольку при чтении Java проверяется каждый объект, является ли он ссылкой на существующий объект.

0 голосов
/ 25 сентября 2008

буфер протокола: имеет смысл. Вот выдержка из их вики: http://code.google.com/apis/protocolbuffers/docs/javatutorial.html

Получение большей скорости

По умолчанию компилятор буфера протокола пытается генерировать файлы меньшего размера, используя отражение для реализации большей части функциональности (например, анализ и сериализация). Тем не менее, компилятор также может генерировать код, оптимизированный явно для ваших типов сообщений, часто обеспечивая увеличение производительности на порядок, но также удваивая размер кода. Если профилирование показывает, что ваше приложение проводит много времени в библиотеке буферов протокола, вам следует попробовать изменить режим оптимизации. Просто добавьте следующую строку в ваш файл .proto:

опция optimize_for = SPEED;

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

0 голосов
/ 25 сентября 2008

Самый простой подход, который сразу приходит мне в голову, это использование отображенного в памяти буфера NIO (java.nio.MappedByteBuffer). Используйте один буфер (приблизительно), соответствующий размеру одного объекта, и при необходимости добавьте их в выходной файл. Отображаемые в память буферы очень эффективны.

0 голосов
/ 25 сентября 2008

Вам, вероятно, следует подумать о решении для базы данных - все, что делают базы данных, это оптимизирует их информацию, и если вы используете Hibernate, вы сохраняете свою объектную модель как есть и даже не задумываетесь о вашей БД (я думаю, именно поэтому она называется в спящем режиме, просто сохраните свои данные, а затем верните их обратно)

0 голосов
/ 25 сентября 2008

Вы пробовали сериализацию Java? Вы могли бы записать их, используя ObjectOutputStream , и прочитать их обратно, используя ObjectInputStream . Конечно, классы должны быть Serializable. Это было бы решение, не требующее больших усилий, и, поскольку объекты хранятся в двоичном виде, оно будет компактным и быстрым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...