Создание системы, в которой два или более узла идеально синхронизированы, по определению невозможно. Однако на практике вы можете подобраться достаточно близко, чтобы это помогло решить вашу конкретную проблему.
Вы не называете точную причину работы на двух узлах, поэтому я собираюсь предположить, что это для масштабируемости. Со многими узлами ваша система также станет более доступной и отказоустойчивой, если вы сделаете это правильно. Однако проблема может быть упрощена, если вы знаете, что когда-либо будете работать только на одном узле, и вам понадобится другой узел в качестве горячего подчиненного устройства, если хозяин недоступен.
Чтобы установить соединение между двумя процессами на двух разных узлах, вам нужна глобальная адресация (идентификатор пользователя 123 - это pid <123,456,0>). Если вы также заботитесь только об одном процессе, запущенном для пользователя А, работающем одновременно, вам также нужна блокировка или разрешить только уникальные регистрации адресации. Если вы также хотите расти, вам нужен способ добавить больше узлов, когда ваша система работает или когда она остановлена.
Теперь уже есть некоторые решения, которые помогут решить вашу проблему, с различными компромиссами:
gproc в глобальном режиме, позволяет зарегистрировать процесс под заданным ключом (который дает вам адресацию и блокировку). Он распространяется на весь кластер без единой точки отказа, однако выбор лидера (по крайней мере, когда я в последний раз смотрел на него) работает только для узлов, которые были доступны при запуске системы. Добавление новых узлов требует экспериментальной версии gen_leader или остановки системы. В вашем собственном коде, если вы знаете, что два игрока будут когда-либо разговаривать друг с другом, вы можете запустить их на одном узле.
riak_core, позволяет строить на основе проверенной и проверенной архитектуры, используемой в riak KV и riak search. Он отображает ключи в сегменты таким образом, который позволяет добавлять новые узлы и перераспределять ключи. Вы можете подключиться к этому механизму и переместить ваши процессы. Этот подход не позволяет вам решить, с чего начать процессы, поэтому, если между вами много связей, они будут проходить через сеть.
Использование mnesia с распределенными транзакциями позволяет вам гарантировать, что каждый узел имеет данные до совершения транзакции, это даст вам распределение адресации и блокировки, но вам придется делать все остальное поверх это (как снятие блокировки). Примечание. Я никогда не использовал распределенные транзакции в производстве, поэтому не могу сказать, насколько они надежны. Кроме того, из-за распределения ожидайте задержки. Примечание 2: Вы должны точно проверить, как бы вы добавили больше узлов и реплицировали таблицы, например, если это возможно без остановки mnesia.
Zookeper / doozer / roll your own предоставляет централизованную высокодоступную базу данных, которую вы можете использовать для хранения адресации. В этом случае вам нужно будет справиться с отменой регистрации. Добавить узлы во время работы системы легко с точки зрения адресации, но вам нужен какой-то способ, чтобы приложение узнало о новых узлах и запустило процессы там.
Кроме того, нет необходимости хранить узел, так как pid содержит достаточно информации для отправки сообщений непосредственно на правильный узел.
Как крутой трюк, о котором вы, возможно, уже знаете, pids может быть сериализован (как и все данные в виртуальной машине) в двоичный файл. Используйте term_to_binary/1
и binary_to_term/1
для преобразования между фактическим pid внутри виртуальной машины и двоичным файлом, который вы можете хранить в любом месте, принимающем двоичные данные, без каких-либо глупых искажений.