Обработка дублирующихся данных при разборе огромных XML-каналов - PullRequest
0 голосов
/ 01 апреля 2011

Я пишу компонент, который анализирует xml-фид с биржевыми котировками и сохраняет результат в базе данных. Проблема довольно проста, за исключением того, что канал не может быть прочитан постепенно. То есть, нет никакого способа указать, что вы хотите, чтобы X изменял только последнюю цитату или только изменения, более новые, чем X минут, скажем. Я знаю, что реальная проблема заключается в том, что канал глуп и что провайдер должен исправить свои вещи, но это не вариант, атм.

Лента представляет собой огромный XML-файл, который содержит 100000 последних котировок акций поставщика. Канал опрашивается один раз в минуту, в течение которого изменяется от 50 до 100 котировок. Остальные - повторяющиеся цитаты, которые читаются снова и снова и снова.

Во время каждого опроса канала я анализирую все кавычки (используя lxml) для объектов. Затем для каждого объекта цитаты я проверяю, существует ли цитата в базе данных. Если это произойдет, я откажусь от него, а если нет, я сохраню Эта процедура чрезвычайно расточительна, поскольку только около 0,1% - это новые данные, остальное - дубликаты. Чтобы немного его оптимизировать, я создаю таблицу поиска, запрашивая базу данных один раз для котировок, обновленных за последние X часов. Кавычки являются уникальными в базе данных по ключу (last_update, stock_id), поэтому эта оптимизация уменьшает количество запросов примерно на 50%.

Но все еще есть запросы по 50 КБ, где каждая цитата должна проверяться индивидуально, если она существует или нет, что очень обременительно для базы данных.

Итак, я ищу идеи о том, как ускорить мой анализатор каналов. Может быть, есть способ изменить последний извлеченный XML-файл новым?

Ответы [ 2 ]

1 голос
/ 01 апреля 2011

Ваша проблема делится на две области: 1) как избежать синтаксического анализа того, что вам не нужно анализировать, и 2) как избежать операций с базой данных, которые вам не нужны.

Если сами кавычки очень малы, вы, вероятно, не сильно выиграете от попыток решить (1). В противном случае вы можете создать фильтр (например, используя XSLT или SAX), который будет отбрасывать кавычки, которые вам не нужны, а затем выполнить полный анализ DOM для остальных.

Чтобы решить (2), в общем, различие в XML-файлах может быть непростым делом, потому что изменения в пробелах в вашем XML-документе, слишком часто встречающиеся у некоторых провайдеров, могут привести к ложным срабатываниям, и вам обычно нужно что-то, что анализирует реальный Структура XML, а не простой текстовый построчный diff. Если вы не думаете, что это будет проблемой для вас, вы можете изучить несколько тем переполнения стека, но я думаю, что они также продемонстрируют, что различия в XML по-прежнему немного шероховаты, особенно в области открытого кода:

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

1 голос
/ 01 апреля 2011

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

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

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