Управление состоянием субъектов Reliable Actors

Субъекты Reliable Actors — это однопотоковые объекты для инкапсуляции логики и состояния. Так как субъекты выполняются в службах Reliable Services, они могут поддерживать состояние, используя те же механизмы сохранения и репликации. При этом субъекты не теряют свое состояние после сбоев, повторной активации после сборки мусора или перемещения между узлами в кластере из-за балансировки ресурсов или обновления.

Сохранение состояния и репликация

Все субъекты Reliable Actors отслеживают состояние , так как каждый экземпляр субъекта сопоставляется с уникальным идентификатором. Это означает, что повторные вызовы одного идентификатора субъекта направляются в один и тот же экземпляр субъекта. Это отличается от системы без отслеживания состояния, в которой не гарантируется, что клиентские вызовы будут каждый раз направляться на один и тот же сервер. Поэтому службы субъектов всегда отслеживают состояние.

Несмотря на то что субъекты отслеживают состояние, это не означает, что они надежно хранят состояние. Субъекты могут выбрать уровень сохранения и репликации состояния на основе их требований к хранению данных:

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

Каждый уровень сохраняемости — это просто другая конфигурация поставщика состояний и репликации службы. Записывается ли состояние на диск, зависит от поставщика состояний — компонента Reliable Service, который хранит состояние. А репликация зависит от того, на скольких репликах развертывается служба. Как и в случае со службами Reliable Services, поставщик состояний и число реплик можно легко настроить вручную. Платформа субъектов предоставляет атрибут, который при использовании с субъектом автоматически выбирает поставщик состояний по умолчанию и создает параметры числа реплик для достижения одного из этих трех параметров сохраняемости. Производный класс не наследует атрибут StatePersistence, каждый тип субъекта должен предоставлять собственный уровень StatePersistence.

Сохраненное состояние

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl  extends FabricActor implements MyActor
{
}

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

Непостоянное состояние

[StatePersistence(StatePersistence.Volatile)]
class MyActor : Actor, IMyActor
{
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Volatile)
class MyActorImpl extends FabricActor implements MyActor
{
}

Этот параметр использует поставщик состояний только в памяти и настраивает 3 реплики.

Несохраняемое состояние

[StatePersistence(StatePersistence.None)]
class MyActor : Actor, IMyActor
{
}
@StatePersistenceAttribute(statePersistence = StatePersistence.None)
class MyActorImpl extends FabricActor implements MyActor
{
}

Этот параметр использует поставщик состояний только в памяти и настраивает 1 реплику.

Значения по умолчанию и созданные параметры

При использовании атрибута StatePersistence поставщик состояний автоматически выбирается во время выполнения при запуске службы субъекта. Однако число реплик задается средствами построения субъекта Visual Studio во время компиляции. Средства построения автоматически создают службу по умолчанию для службы субъекта в ApplicationManifest.xml. Параметры создаются для минимального размера набора реплик и целевого размера набора реплик.

Вы можете изменить эти параметры вручную. Однако при каждом изменении атрибута StatePersistence параметрам будут присвоены значения размера набора реплик по умолчанию для выбранного атрибута StatePersistence, а все предыдущие значения будут переопределены. Другими словами, указанные в файле ServiceManifest.xml значения будут переопределены только во время сборки при изменении значения атрибута StatePersistence.

<ApplicationManifest xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="Application12Type" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
   <Parameters>
      <Parameter Name="MyActorService_PartitionCount" DefaultValue="10" />
      <Parameter Name="MyActorService_MinReplicaSetSize" DefaultValue="3" />
      <Parameter Name="MyActorService_TargetReplicaSetSize" DefaultValue="3" />
   </Parameters>
   <ServiceManifestImport>
      <ServiceManifestRef ServiceManifestName="MyActorPkg" ServiceManifestVersion="1.0.0" />
   </ServiceManifestImport>
   <DefaultServices>
      <Service Name="MyActorService" GeneratedIdRef="77d965dc-85fb-488c-bd06-c6c1fe29d593|Persisted">
         <StatefulService ServiceTypeName="MyActorServiceType" TargetReplicaSetSize="[MyActorService_TargetReplicaSetSize]" MinReplicaSetSize="[MyActorService_MinReplicaSetSize]">
            <UniformInt64Partition PartitionCount="[MyActorService_PartitionCount]" LowKey="-9223372036854775808" HighKey="9223372036854775807" />
         </StatefulService>
      </Service>
   </DefaultServices>
</ApplicationManifest>

Диспетчер состояний:

У каждого экземпляра субъекта есть собственный диспетчер состояний: структура данных, подобная словарю, которая надежно хранит пары "ключ — значение". Диспетчер состояний — это оболочка вокруг поставщика состояний. Его можно использовать для хранения данных независимо от того, какой параметр сохраняемости применяется, но он не предоставляет никаких гарантий, что для работающей службы субъекта можно изменить параметр непостоянного состояния (только в памяти) на сохраняемое состояние с помощью последовательного обновления при сохранении данных. Тем не менее, можно изменить количество реплик для запущенной службы.

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

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

Примеры управления состоянием субъекта см. в статье Доступ к состоянию Reliable Actors, а также его сохранение и удаление.

Рекомендации

Ниже приведены некоторые рекомендации и советы по устранению неполадок для управления состоянием субъекта.

Состояние субъекта должно быть максимально детализировано

Это важно с точки зрения производительности и потребления ресурсов приложения. При каждом выполнении записи или обновления "именованного состояния" субъекта все значение, соответствующее этому состоянию, сериализуется и отправляется по сети на вторичные реплики. Вторичные реплики записывают это значение на локальный диск и отправляют ответ на первичную реплику. Когда первичная реплика получает подтверждения от кворума вторичных реплик, она записывает это состояние на локальный диск. Например, предположим, что значение — класс из 20 элементов, размер которого составляет 1 МБ. Даже если вы изменили только одного элемента класса, размер которого составляет 1 КБ, вы оплачиваете сериализацию, сохранение в сети и запись на диск как за 1 МБ. Аналогичным образом, если значением является коллекция (например, список, массив или словарь), вы оплачиваете стоимость всей коллекции даже при изменении одного из ее элементов. Интерфейс StateManager класса субъекта подобен словарю. Необходимо всегда моделировать структуру данных, представляющую состояние субъекта, на основе этого словаря.

Надлежащее управление жизненным циклом субъекта

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

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

Дальнейшие действия

Состояние, которое хранится в Reliable Actors, должно быть сериализовано перед записью на диск и реплицировано для обеспечения высокого уровня доступности. Узнайте больше о сериализации типа субъекта.

Затем ознакомьтесь с диагностикой и мониторингом производительности субъекта.