Понимание того, когда использовать службы с сохранением состояния и когда полагаться на внешнее сохранение в Azure Service Fabric - программирование
Подтвердить что ты не робот

Понимание того, когда использовать службы с сохранением состояния и когда полагаться на внешнее сохранение в Azure Service Fabric

Я проводил вечера, оценивая Azure Service Fabric в качестве замены нашего текущего стека WebApps/CloudServices и чувствую себя немного неуверенным в том, как решать, когда сервисы/актеры с состоянием должны быть субъектами с точки зрения состояния, и когда они должны быть безъядерных участников с внешним сохраняющимся состоянием (Azure SQL, Azure Storage и DocumentDB). Я знаю, что это довольно новый продукт (по крайней мере, для широкой публики), поэтому, вероятно, не так много передового опыта в отношении этого, но я прочитал большую часть documentation, предоставленный Microsoft, не нашедший для этого определенного ответа.

Текущая проблемная область, к которой я приближаюсь, - это наш магазин событий; части наших приложений основаны на поиске событий и CQRS, и я оцениваю, как перенести это хранилище событий на платформу Service Fabric. Хранилище событий будет содержать много временных рядов данных, и поскольку это наш единственный источник истины для сохраняемых там данных, он должен быть последовательным, реплицироваться и храниться в какой-то форме длительного хранения.

Один из способов, который я рассматривал, заключается в том, что он имеет статус "EventStream". каждый экземпляр агрегата с использованием источника событий хранит его события в изолированном потоке. Это означает, что актер, занимающийся состоянием, может отслеживать все события для собственного потока, и я бы выполнил мои требования относительно того, как данные хранятся (транзакционные, реплицированные и долговечные). Тем не менее, некоторые потоки могут расти очень большими (сотни тысяч, если не миллионы) событий, и именно здесь я начинаю сомневаться. Я думаю, что наличие актера с большим количеством состояний повлияет на производительность системы, когда эти большие модели данных должны быть сериализованы или десериализованы с диска.

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

В принципе, когда количество состояний для актера/услуги "слишком много", и вы должны начать рассмотрение других способов обработки состояния?

Кроме того, этот раздел в Дизайнере шаблонов услуг Fabric Actors: некоторые анти-шаблоны оставляют меня немного озадаченным:

Относитесь к роликам Azure Service Fabric как к транзакционной системе. Azure Service Fabric Actors не является двухфазной системой фиксации, предлагающей ACID. Если мы не реализуем необязательное постоянство, и машина, на которой работает актер, умирает, текущее состояние будет идти с ней. Актер будет продвигаться на другом node очень быстро, но, если мы не выполним упорство поддержки, состояние исчезнет. Тем не менее, между попытками повторного использования, дублированием фильтрации и/или идемпотентной конструкцией вы можете достичь высокого уровня надежности и согласованности.

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

4b9b3361

Ответ 1

Один из вариантов, который у вас есть, - сохранить "некоторые" состояния в актере (скажем, что можно считать горячими данными, которые должны быть быстро доступны) и хранить все остальное в "традиционной" инфраструктуре хранения, например как SQL Azure, DocDB,.... Трудно иметь общее правило о слишком большом местном состоянии, но, может быть, оно помогает думать о горячих и холодных данных. Надежные актеры также предлагают возможность настраивать StateProvider, поэтому вы также можете рассмотреть возможность внедрения настраиваемого StateProvider (путем внедрения IActorStateProvider) с конкретными политиками, которые необходимо повысить с учетом требований, которые вы имеете в отношении количества данных, задержки, надежность и т.д. (примечание: документация по-прежнему очень минимальна в интерфейсе StateProvider, но мы можем опубликовать некоторый пример кода, если это то, что вы хотите продолжить).

Об анти-шаблонах: примечание больше об осуществлении транзакций между несколькими участниками. Надежные актеры обеспечивают полную гарантию надежности данных в границах актера. Из-за распределенного и слабо связанного характера модели Actor реализация транзакций, в которых задействованы несколько участников, не является тривиальной задачей. Если "распределенные" транзакции являются сильным требованием, вероятно, лучше всего подходит модель программирования "Надежные службы".

Ответ 2

Я знаю, что на это был дан ответ, но недавно оказался в том же затруднительном положении с системой CQRS/ES и вот, как я это сделал

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

Ответ 3

Чтобы ответить на вопрос @Trond sedcondary, который есть, " Что означает" если мы не реализуем необязательное упорство "здесь?"

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

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

Полное обсуждение темы можно найти в документации Microsoft