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

Это продолжение моегопредыдущий вопрос, Как предположил Тим Питерс, используяManager не обязательно может быть лучшим подходом. К сожалению, Я'у меня слишком много кода для размещения лесаSSCCE, Вместо этого яЯ постараюсь предоставить подробное объяснение моей проблемы. Пожалуйста, не стесняйтесь просматривать всю кодовую базу наGithub, но это'Это немного беспорядок прямо сейчас.

Фон

Я занимаюсь исследованиями в области обработки естественного языка иЯ хотел бы сделать (что-то вроде) словарное сглаживание для классификации документов. Идея обучить классификатор, чтобы связать слова и фразы с правильным ответом. Например, документы, содержащие словоsocialist скорее всего, о политике, и те, которые содержат фразуlava temperature скорее всего о геологии. Система обучается, глядя нанебольшое количество предварительно помеченных примеров. Поскольку язык настолько разнообразен, классификатор никогда не будет "знать о" все возможные фразы, с которыми он может столкнуться в производстве.

Это где словарь входит. Предположим, у нас былодешевый и простой способ получить синонимы почти для любой фразы там (япроцитирую себя, потому что этоплохой вкус). Когда бедный классификатор сталкивается с фразой, он нене знаю, мы могли бы найти это в указанном словаре и сказать классификаторуСмотри, ты не знаешь оcommunism, но это'вроде какsocialistи ты знаешь об этом!, Если словарь разумный, классификатор, как правило, будет работать лучше.

Псевдокод
data = Load training and testing documents (300MB on disk)
dictionary = Load dictionary (200MB - 2GB on disk) and place into a `dict` for fast look-ups
Repeat 25 times:
    do_work(data, dictionary)

def do_work(data, dictionary)
    X = Select a random sample of data
    Train a classifier on X
    Y = Select a random sample of data
    Using dictionary, classify all documents in Y
    Write results to disk
Эта проблема

Цикл выше является идеальным кандидатом для распараллеливания. Я использую Python 2.7multiprocessing.Pool (черезjoblib.Parallel, потому что это'Это легко и дает очень полезную трассировку, если дела пойдут на юг). Все рабочие процессы должны иметь доступ только для чтения к словарю и коллекции документов. Рабочим не нужно общаться друг с другом или с родительским процессом - все, что они делают, это порождают, делают немного магии, пишут файл и умирают.

Словарь должен поддерживать быстрый произвольный доступ. Я не знаю, какие документы образецY будет содержать, поэтому я не могу легко сократить словарь и передать только ту часть, которая нужна каждому работнику. К словарю будут обращаться очень часто - типичное число попаданий на один прогон исчисляется миллионами. В настоящее время мой код связан с памятью, так как (я считаю) копии коллекции документов и словаря создаются для каждого рабочего процесса. Когда разбираетсяdata а такжеdictionary обычно занимают несколько ГБ ОЗУ. Я'мы пытались использоватьmultiprocessing.managers.BaseManager чтобы избежать копирования больших объектов, но это замедлило работу рабочих.

Вопрос

Какие есть альтернативы, чтобы ускорить процесс? Вещи, о которых я думал, включают:

MongoDB / CouchDB / memcached должен хорошо обрабатывать параллельный доступ, но яЯ беспокоюсь о пропускной способности. zeromq был также предложен в комментарии к моему предыдущему вопросу, убежищеу меня был шанс разобраться в этом.в памятиsqlite базы данных и соединения с базой данных не могут быть общими для всех процессов, поэтому каждому работнику потребуется собственное соединение с базой данных на диске. Это означает большое количество операций ввода-вывода и большое использование памяти каждым рабочим.кеш растет.отображение памятииспользуя потоки вместо процессов

Это ТАК вопрос также предположил, что многие реальные проблемы, которые выглядят так, как будто им нужен доступ только для чтения кdict может вызватьfork()s копирование при записи, поэтому может быть невозможно полностью избежать копирования больших объектов.