Самое лучшее, это держать сессии и общее состояние (например, модель игрового мира или машину состояний, используемую для управления объектом промышленной автоматизации и т.д.) в оперативной памяти. Сессии только в одном процессе, а общее состояние в каждом процессе. Чтобы клиент подключался всегда к тому процессу, в котором лежит его сессия, то соединение должно быть подписано специальной cookie с номером процесса, кука эта может устанавливаться при аутентификации и после этого, сетевой маршрутизатор или реверс-прокси будет передавать все запросы, помеченные этой кукой, именно в нужный процесс. Но процессы дохнут периодически, поэтому сессии нужно сохранять в БД, но лучше это делать в ленивом (lazy) режиме, т.е. не во время HTTP запроса от клиента, а поставить периодическое событие и сбрасывать из памяти в БД, и иметь механизм восстановления из БД. Если процесс пользователя погиб, то при первом следующем запросе состояние восстановится и дальше будет опять браться из памяти. Можно сделать упреждающее чтение, если процесс погибает, то в БД хранить для каждого процесса массив пользователей, чье состояние он обрабатывал и сразу после повторного запуска, процесс восстановит из БД все сессии и будет ждать "своих" пользователей. Что касается общего для многих пользователей состояния, то его можно синхронизировать между процессами при помощи нехитрого API, пересылающего лог изменений состояния из того процесса, в котором они произошли во все другие при помощи IPC, HTTP или ZeroMQ. Пример такого API вот тут:
https://github.com/tshemsedinov/impress/blob/maste... Вкратце, оно имеет функции inc(path, value, delay); dec(path, value, delay); set(path, value, delay); get(path); delete(path, delay); и т.д. тут path - это путь к данным в объекте состояния, например inc('myCar.speed', 15, "2s") - увеличить скорость машины в модели на 15 с гарантированной синхронизацией между процессами в течении 2 секунд (это для того, чтобы сократить кол-во пересылок изменений, они склеятся в течении 2 секунд). Все inc/dec изменения аддитивны в любом порядке, поэтому их можно пересылать как угодно, а в другом процессе можно подписаться на изменение subscribe('myCar.speed', function(path, value, remote) { ... }); где path - 'myCar.speed', value - новое значение, remote - true если изменение из другого процесса. Думаю, что Вы найдете и более подходящие реализации, но пример должен быть понятен. Можно конечно держать и сессии и общее состояние в БД, например в MongoDB, но это приводит к тому, что во время HTTP запросов случается I/O, и запрос ждет, а согласитесь, что ни какого I/O это быстрее, чем асинхронное I/O, брать из памяти - всегда лучше, а синхронизировать в свободное время (пусть с ограниченной точностью, с отставанием), а если личные сессии, то ни какого отставания вообще нет.