Джава:Сериализация огромного количества данных в один файл

StackOverflow https://stackoverflow.com/questions/129695

  •  02-07-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

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

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Увеличение скорости

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

опцияоптимизировать_для = СКОРОСТЬ;

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top