2010-09-11 2 views
25

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

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

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

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

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

+0

Для общего состояния, может быть, я должен реализовать тип выборов лидера Zookeper алгоритма. Где каждая машина в кластере имеет NodeManager. Первым узлом становится лидер. Каждый последующий узел становится последователем, а следующий узел становится его последователем. Когда лидер умирает, следующий узел встает, чтобы занять его место. Лидер разделяет свое состояние с последователями и так далее. – Unoti

+0

Обновление, в настоящее время рассматривается построение решения на основе JGroups для этого. Код членства кластера Akka использует JGroups. – Unoti

+0

Как все прошло? :-) –

ответ

5

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

+0

Спасибо, Виктор. Я столкнулся с этим, исследуя это также: http://groups.google.com/group/akka-user/browse_thread/thread/636e08b7199c9e46?fwc=2 – Unoti

+0

Просто хочу добавить: На данный момент они открыты для поиска http://groups.google.com/group/akka-user/browse_thread/thread/132b40035d3ced38 – Blub

+0

Он будет в версии 2.0, который выйдет в конце этого года. –

3

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

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

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

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

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

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

+0

Спасибо, сэр. Я сделаю то, что вы предлагаете. Теперь мне просто нужно выяснить, как заставить эти хосты совместно использовать состояние между собой, используя либо активный, либо активный пассивный подход. Мне кажется, что мне нужно будет это построить, и я хочу убедиться, что я не создаю что-то, что уже сделано и готово для использования в Akka, что ускользнуло от моего уведомления. – Unoti

3

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

+0

Спасибо за подсказку! – Unoti

+0

Есть ссылки на некоторые интересные статьи на сайте dimdwrf. – Bessi

2

2 цента ..

«как разделить состояние между несколькими машинами так, что если один из них выходит из строя вещи продолжают работать»

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

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

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

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

Все самое лучшее, Энди