2017-01-25 3 views
0

Я намерен сделать структуру программы, как показано нижеПопутный переменные между двумя питона процессами

Program Structure

PS1 программа питон настойчиво работает. PC1, PC2, PC3 являются клиентскими программами python. PS1 имеет переменную хеш-таблицу, всякий раз, когда PC1, PC2 ... запрашивает хэш-таблицу, PS1 передает ее им.

Цель состоит в том, чтобы сохранить таблицу в памяти, поскольку она представляет собой огромную переменную (занимает 10 ГБ памяти), и ее дорого рассчитать каждый раз. Невозможно сохранить его на жестком диске (используя pickle или json) и читать его каждый раз, когда это необходимо. Чтение занимает слишком много времени.

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

+2

Сохраните его в базе данных? Именно для этих целей используются базы данных. Альтернативой является выделение разделяемой памяти для переменной и возможность другим процессам python получить к ней доступ. – DyZ

+1

Рассматривали ли вы использование базы данных? Когда вы говорите «Хэш-таблицу 10 ГБ», моя первая мысль - «MongoDB» (или аналогичная настройка хранилища ключей). Прохождение около 10 ГБ хэш-таблиц кажется совершенно ненужным. – ShadowRanger

+1

http://stackoverflow.com/questions/6832554/python-multiprocessing-how-do-i-share-a-dict-among-multiple-processes –

ответ

0

Чтобы сделать то, о чем вы просите, вам нужно создать массив байтов как RawArray из модуля multiprocessing.sharedctypes, который достаточно велик для всей хэш-таблицы на сервере PS1, а затем сохранить хэш-таблицу в что RawArray. PS1 должен быть процессом, который запускает PC1, PC2 и т. Д., Которые затем могут наследовать доступ к RawArray. Вы можете создать свой собственный класс объекта, который предоставляет интерфейс хеш-таблицы, через который будут доступны отдельные переменные в таблице, которые могут быть отдельно переданы каждому процессу ПК #, который читается из общего RawArray.

+0

_PS1 должен быть процессом, который запускает PC1, PC2 и т. Д. Есть ли способ сделать PC1, PC2.etc независимым от PS1? При запросе «таблицы» это просто как посещение веб-сайта и «загрузка» таблицы, но все произошло в памяти? –

+0

Что вы подразумеваете под «независимым»? После того, как PS1 запустит PC1, PC2 и т. Д., Они будут полностью отдельными процессами. Когда я говорю, что PS1 запускает другие, я просто говорю, что у него будет строка, которая говорит что-то вроде 'p = process (...; p.start()'. Это было бы против вас, запуская PS1 из командной строки, а затем вручную запустить PC1 из командной строки или запустить другой процесс PS1, а затем PC1. – RichardB

0

Вы пытаетесь изобрести квадратное колесо, когда хорошие круглые колеса уже существуют!

Давайте на один уровень вверх, как вы описали ваши потребности:

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

ИМХО, мы точно сталкиваемся с тем, для каких баз данных были созданы. Для случаев общего использования, имея много процессов, все из которых используют свою собственную копию объекта 10G, это отходы памяти, а общий способ заключается в том, что один процесс имеет данные, а остальные отправляют запросы на данные. Вы не опишете вашу проблему достаточно, поэтому я не могу сказать, лучшим решением будет:

  • базы данных SQL, как PostgreSQL или MariaDB - как они могут кэша, если у вас достаточно памяти, все будет проходить автоматически в памяти
  • база данных NOSQL (MongoDB и т. д.).), если ваша единственная (или основная) необходимость - доступ к одним ключам - очень приятно при работе с множеством данных, требующих быстрого, но простого доступа
  • выделенный сервер с использованием языков заданного запроса, если ваши потребности очень специфичны, и ни одно из вышеперечисленных решений встретить их
  • процесс создания огромный кусок разделяемой памяти, который будет использоваться процессами клиента - безусловно, будет самым быстрым при условии, что последнее решение:
    • все клиенты делают только для чтения доступ - он может быть продлен до r/w, но может привести к кошмару синхронизации
    • у вас наверняка будет достаточно памяти в вашей системе, чтобы никогда не использовать swap - если вы вы потеряете все оптимизации кэша, которые реализуют реальные базы данных
    • размер базы данных и количество клиентских процессов и внешняя нагрузка всей системы никогда не увеличиваются до уровня, в котором вы попадаете в проблему подкачки выше

TL/DR: Мой совет состоит в том, чтобы поэкспериментировать с результатами работы с качественной базой данных и, возможно, с помощью специального chache. Это решение позволяет практически полностью балансировать нагрузку на разные машины. Только если это не сработает, внимательно проанализируйте требования к памяти и обязательно задокументируйте ограничения количества клиентских процессов и размера базы данных для дальнейшего обслуживания и использования разделяемой памяти. Данные только для чтения являются подсказкой, что разделяемая память может быть хорошим решением.

Смежные вопросы