Python, Solr и огромное количество запросов: нужны предложения - PullRequest
1 голос
/ 29 февраля 2012

Я столкнулся с проблемой дизайна в моем проекте.

ПРОБЛЕМА
Мне нужно запросить solr со всеми возможными комбинациями (более или менее 20 миллионов) некоторых параметров, извлеченных из наших списков, чтобы проверить, дают ли они хотя бы 1 результат. в противном случае эта комбинация вставляется в черный список (используется для статистического анализа и создания карты сайта)

КАК Я ДЕЛАЮ СЕЙЧАС
вложенный в циклы для объединения параметров (извлеченных из списков Python) и передачи их в метод (тот же, который я использую в производственной среде для запроса БД на веб-сайте), который проверяет на 0-результаты. если это 0, есть метод вставки в черный список
Нет необходимости в потоке

КАК Я НРАВИТСЯ ЭТОМУ
Я хотел бы поместить все комбинации в очередь и позволить объекту потока их извлекать, запрашивать и вставлять для лучшей производительности

Какие проблемы я испытываю
медлительность : будучи однопоточным, теперь требуется много времени для завершения (когда и если он завершится)

сброс соединения по одноранговому узлу [104] : это ошибка, выдаваемая solr через некоторое время, когда его запрашивают (я увеличил размер пула, но ничего не меняется), это самая повторяющаяся (и раздражающая) ошибка , в данный момент.

Python Hanging : это я решил с помощью декоратора тайм-аута (что не является правильным решением, но, по крайней мере, это помогает мне пройти всю обработку и получить быстрый тестовый вывод на данный момент. I ' оставлю это всякий раз, когда смогу найти разумное решение)

максимальный размер очереди : объект очереди может содержать до 32 тыс. Элементов, поэтому он не будет соответствовать моим числам

ЧТО Я ИСПОЛЬЗУЮ
питон 2,7
MySQL
апач-Solr
загорелое (интерфейс Python для Solr)
linux box

Мне не нужна никакая отладка кода, так как я бы предпочел выбросить то, что я сделал для начала, вместо того, чтобы исправлять это снова и снова ... "Проба по ошибке" - это не то, что мне нравится.

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

Заранее всем спасибо за помощь! Если вы что-то не поняли, просто спросите, я отвечу / обновлю сообщение, если необходимо!

РЕДАКТИРОВАТЬ НА ОСНОВЕ НЕКОТОРЫХ ОТВЕТОВ (сохранит это обновление)
я, вероятно, отброшу потоки Python для многопроцессорной библиотеки : это может решить мои проблемы с производительностью

метод построения "разделяй и властвуй" : это должно добавить некоторую логику в мою конструкцию параметров, без необходимости грубого подхода

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

NB: пока я не приму никакого ответа, так как я хотел бы поддерживать этот пост на некоторое время живым, просто чтобы собрать все больше и больше идей (не только для меня, но, возможно, для дальнейшего использования другими, поскольку это общая природа)

Еще раз всем спасибо!

Ответы [ 2 ]

3 голосов
/ 29 февраля 2012

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

1 голос
/ 29 февраля 2012

Модуль stdlib «multiprocessing» можно использовать для того, чтобы несколько подпроцессов работали с вашими комбинациями. Это работает лучше, чем потоки Python, и позволяет по крайней мере каждому логическому ядру ЦП в вашей конфигурации работать одновременно.

Вот минималистский пример того, как это работает:

import random
from multiprocessing import Pool

def a(a):
    if random.randint(0, 100000) == 0:
        return True
    return False

# the number bellow should be a equal to your number of processor cores:
p = Pool(4)

x = any(p.map(a, xrange(1000000)))
print x

Итак, это тест на 10 миллионов, разделенный на 4 "рабочих" процесса, без проблем с масштабированием.

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

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