it-swarm.com.ru

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

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

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

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

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

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

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

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

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

58
Trond Nordheim

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

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

24
clca

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

  1. Каждый Агрегат был актером, в котором хранилось только текущее состояние.
  2. По команде агрегат будет влиять на изменение состояния и вызывать событие.
  3. Сами события были сохранены в DocDb.
  4. При активации экземпляры AggregateActor читают события из DocDb, если они доступны, чтобы воссоздать его состояние. Очевидно, это выполняется только один раз за активацию актера. Это позаботилось о случае, когда экземпляр субъекта переносится с одного узла на другой.
5
Raghu

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

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

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

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

2
Phillip Ngan