Я прочитал об этом сообщении, Python multiprocessing: sharing a large read-only object between processes?, но все еще не уверен, как действовать дальше.Как разделить очень большой словарь среди процессов в Python
Вот моя проблема:
я анализирую массив миллионов строк с использованием multiprocessing
, и должна быть проверена на большой Словарь, который состоит из примерно 2 миллиона долларов (может быть, выше) ключей каждой строки. Его значения - это объекты настраиваемого класса Python под названием Bloomfilter
(поэтому они не просто простые int или float, либо массивы), а их размеры варьируются от нескольких байтов до 1,5 Гб. Анализ для каждой строки в основном проверяет, находится ли строка в определенном количестве цветных фильтров в словаре. Это зависит от самой строки, чтобы решить, какие цветущие фильтры имеют значение. Словарь представляет собой преобразование 30G sqlite3 db. Мотивация состоит в том, чтобы загрузить весь объем sqlite3 db в память, чтобы ускорить обработку, но я не нашел способ эффективно делиться dict. У меня около 100G памяти в моей системе.
Вот что я попытался:
Анализа для каждой строки является CPU переплета, поэтому я выбрал многопроцессорный над многопоточностью. Ключ заключается в том, как разделить большой dict среди процессов без копирования. multiprocess.Value
и multiprocessing.Array
не могут обрабатывать сложные объекты, такие как dict. Я пробовал multiprocessing.Manager()
, но так как диктофон настолько велик, что я получаю ошибку IOError: bad message length
. Я также попытался использовать базу данных в памяти, такую как Redis на localhost, но битаррей, который используется для создания Bloomfilter после извлечения, слишком велик, чтобы вписаться, и это заставляет меня думать, что передача больших сообщений среди процессов просто слишком дорого (это?)
Мой вопрос:
Что такое правильный способ обмена такой словарь между различными процессами (или нитями, если есть способ обойти GIL)? Если мне нужно использовать базу данных, которую я должен использовать? Мне нужно очень быстрое чтение, и база данных должна иметь возможность хранить очень большие значения. (Хотя я не думаю, что база данных будет работать, потому что прохождение вокруг очень больших значений не будет работать, верно? Пожалуйста, исправьте меня, если я ошибаюсь)
Вы используете Unix? Вы могли бы просто использовать fork() столько раз, сколько необходимо, что дало бы вам копию структуры данных в каждом процессе. Если вы используете окна, это, вероятно, более сложно, поскольку я не думаю, что fork реализован совершенно так. – Max
Да, я на Linux. Не могли бы вы немного подробнее рассказать о '' fork() '' или указать мне ссылку? – zyxue
Хорошо, имейте в виду, что fork - инструмент очень низкого уровня, но он находится в модуле os: https://docs.python.org/2/library/os.html#os.fork (та же идея в python 3) , Он буквально клонирует процесс, поэтому они имеют все те же данные; если после этого вы не выполните никаких операций с записью структуры данных, процессы должны совместно использовать соответствующие страницы памяти. Затем вам может понадобиться написать свои собственные методы для подсчета вычисленных данных в конце. – Max