Масштабирующее приложение, которое читает большие файлы XML - PullRequest
3 голосов
/ 10 сентября 2011

У меня есть приложение, которое периодически читает большой набор XML-файлов (кратно 20-30), например, раз в 10 минут. Теперь каждый XML-файл может иметь размер не менее 40-100 МБ. После прочтения каждого XML-файла из файла создается карта, а затем карта передается по цепочке процессоров (10-15), каждый процессор использует данные, выполняет некоторый фильтр или записывает данные в базу данных и т. Д.

Теперь приложение работает в 32-битной JVM. Сейчас нет намерения переходить на 64-битную JVM. Объем памяти, как и ожидалось, очень высок ... приближается к порогу 32-битной JVM. На данный момент, когда мы получаем большие файлы, мы сериализуем сгенерированную карту на диск и одновременно выполняем по цепочке процессоров максимум 3-4 карты, как если бы мы пытались обрабатывать все карты одновременно, она легко вышла бы из OutOfMemory. Также сборка мусора довольно высока.

У меня есть некоторые идеи, но я хотел посмотреть, есть ли варианты, которые люди уже попробовали / оценили. Итак, каковы варианты масштабирования такого рода приложений?

Ответы [ 3 ]

2 голосов
/ 10 сентября 2011

Да, чтобы попугать @aaray и @MeBigFatGuy, вы хотите использовать для этого какой-то парсер, основанный на событиях, упомянутый dom4j, или SAX или StAX.

В качестве простого примера, что XML объемом 100 МБ потребляетминимум 200 МБ ОЗУ, если вы загружаете его оптом, поскольку каждый символ немедленно расширяется до 16-битного символа.

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

ЕСЛИ (и это БОЛЬШОЕ ЕСЛИ), вы используете многоДостаточно небольшой набор строк, вы можете сэкономить память, используя String.intern ().Это процесс канонизации, который проверяет, существует ли строка в jvm, является ли она общей.Недостатком этого является то, что он загрязняет ваш permgen (после интернирования, всегда интернированного).PermGen довольно ограничен, но, с другой стороны, он в значительной степени невосприимчив к GC.

Рассматривали ли вы возможность запуска XML через внешний XSLT для удаления всей ненужной обработки, которую вы не хотите обрабатыватьеще до того, как он войдет в вашу JVM?Существует несколько автономных XSL-процессоров командной строки, которые вы можете использовать для предварительной обработки файлов до чего-то более разумного.Это действительно зависит от того, сколько данных, которые вы в действительности используете, получаете.

Используя модель обработки XML на основе событий, шаг XSLT в значительной степени избыточен.Но все модели, основанные на событиях, в основном ужасны в использовании, поэтому, возможно, использование шага XSLT позволит вам повторно использовать некоторую существующую логику DOM (при условии, что это именно то, что вы делаете).

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

1 голос
/ 11 сентября 2011

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

1 голос
/ 10 сентября 2011

У нас была похожая проблема при обработке больших файлов XML (около 400 МБ). Мы значительно сократили объем памяти приложения, используя это:

http://dom4j.sourceforge.net/dom4j-1.6.1/faq.html#large-doc

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