Подтвердить что ты не робот

Scala + Akka: Как разработать многомашинный высокодоступный кластер

Мы разрабатываем серверную систему в Scala + Akka для игры, которая будет обслуживать клиентов в Android, iPhone и Second Life. Есть части этого сервера, которые должны быть высокодоступными, работающих на нескольких машинах. Если один из этих серверов умирает (скажем, сбой оборудования), система должна продолжать работать. Я думаю, что я хочу, чтобы у клиентов был список машин, с которыми они будут пытаться соединиться, подобно тому, как работает Cassandra.

Примеры с несколькими node, которые я видел до сих пор с Akka, кажутся мне сосредоточенными вокруг идеи масштабируемости, а не высокой доступности (по крайней мере, в отношении аппаратного обеспечения). В примерах multi- node всегда есть одна точка отказа. Например, есть балансировщики нагрузки, но если мне нужно перезагрузить одну из машин с балансировщиками нагрузки, моя система будет страдать от простоев.

Есть ли примеры, показывающие эту аппаратную отказоустойчивость для Akka? Или у вас есть мысли о хороших способах сделать это?

До сих пор лучшим ответом, который я смог придумать, является изучение документов Erlang OTP, размышление над ними и попытка выяснить, как объединить мою систему с помощью строительных блоков, доступных в Akka.

Но если есть ресурсы, примеры или идеи о том, как разделить состояние между несколькими машинами таким образом, что если один из них идет вниз, все будет работать, я бы их оценил, потому что я обеспокоен тем, что могу быть повторно изобретая колесо здесь. Может быть, существует контейнер multi- node STM, который автоматически синхронизирует общее состояние между несколькими узлами? Или, может быть, так легко сделать, что документация не беспокоит показ примеров того, как это сделать, или, может быть, я недостаточно тщательно изучил и экспериментировал. Любые мысли или идеи будут оценены.

4b9b3361

Ответ 1

HA и управление нагрузкой - очень важный аспект масштабируемости и доступен как часть коммерческого предложения AkkaSource.

Ответ 2

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

Вы можете предложить услугу предложения хоста и рекомендовать клиенту, к какой машине они должны подключиться (на основе текущей нагрузки или что-то еще), тогда клиент может подключиться к ней до тех пор, пока соединение не завершится с ошибкой.

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

В идеале при первом запуске клиент будет подключаться к службе предложения узла, а не только получать соответствующий хост, но и список других потенциальных хостов. Этот список может регулярно обновляться каждый раз, когда клиент подключается.

Если служба запроса хоста снижается с первой попытки клиента (маловероятно, но...), вы можете предварительно развернуть список хостов в клиентской установке, чтобы он мог сразу же начать случайный выбор хостов с самого начала, если он тоже.

Убедитесь, что ваш список хостов - это фактические имена хостов, а не IP-адреса, которые дают вам большую гибкость в долгосрочной перспективе (т.е. вы всегда будете иметь "host1.example.com", "host2.example.com..." ). даже если вы перемещаете инфраструктуру и меняете IP-адреса).

Ответ 3

Вы можете посмотреть, как RedDwarf, а fork DimDwarf. Они являются одновременно масштабируемыми по горизонтали серверами приложений для игр с ошибками, а DimDwarf частично написаны в Scala (новые функции обмена сообщениями). Их подход и архитектура должны соответствовать вашим потребностям достаточно хорошо.

Ответ 4

2 цента.

", как разделить состояние между несколькими машинами таким образом, что если один из них идет вниз, все работает"

Не разделяйте состояние между машинами, а вместо этого - состояние раздела между машинами. Я не знаю вашего домена, поэтому я не знаю, будет ли это работать. Но по существу, если вы назначаете определенные агрегаты (в терминах DDD) на определенные узлы, вы можете хранить эти агрегаты в памяти (актер, агент и т.д.), Когда они используются. Для этого вам нужно будет использовать что-то вроде zookeeper, чтобы координировать, какие узлы обрабатывают, какие агрегаты. В случае сбоя вы можете привести агрегат на другой node.

Кроме того, если вы используете модель источников событий для построения своих агрегатов, становится практически тривиально иметь копии в реальном времени (сводные) вашего агрегата на других узлах теми узлами, которые прослушивают события и сохраняют свои собственные копии.

Используя Akka, мы удаляем удаленные узлы почти бесплатно. Это означает, что когда-либо node обрабатывает запрос, который может потребоваться для взаимодействия с Aggregate/Entity на других узлах, может сделать это с помощью RemoteActors.

То, что я здесь изложил, очень общий, но дает подход к распределенной отказоустойчивости с Akka и ZooKeeper. Это может или не поможет. Надеюсь, это так.

Все самое лучшее, Andy