Reliable Actors 状态管理Reliable Actors state management

Reliable Actors 是可封装逻辑与状态的单线程对象。Reliable Actors are single-threaded objects that can encapsulate both logic and state. 由于执行组件在 Reliable Services 上运行,因此,它们可以使用相同的持久性和复制机制可靠地维护状态。Because actors run on Reliable Services, they can maintain state reliably by using the same persistence and replication mechanisms. 这样,执行组件就不会在发生故障之后、在内存回收后重新激活时或者由于资源均衡和升级的原因而在群集中的节点之间移动时丢失其状态。This way, actors don't lose their state after failures, upon reactivation after garbage collection, or when they are moved around between nodes in a cluster due to resource balancing or upgrades.

状态持久性和复制State persistence and replication

所有 Reliable Actors 被视为 有状态 的原因在于,每个执行组件实例都会映射到唯一的 ID。All Reliable Actors are considered stateful because each actor instance maps to a unique ID. 这意味着,对同一个执行组件 ID 所做的重复调用会路由到同一个执行组件实例。This means that repeated calls to the same actor ID are routed to the same actor instance. 与此相反,在无状态系统中,客户端调用不一定每次都路由到同一台服务器。In a stateless system, by contrast, client calls are not guaranteed to be routed to the same server every time. 出于此原因,执行组件服务永远都是有状态服务。For this reason, actor services are always stateful services.

即使执行组件被视为有状态,也并不表示它们必须以可靠的方式存储状态。Even though actors are considered stateful, that does not mean they must store state reliably. 执行组件可以根据其数据存储要求来选择状态持久性和复制的级别:Actors can choose the level of state persistence and replication based on their data storage requirements:

  • 持久化状态:状态将持久保存到磁盘中,并复制到 3 个或更多个副本。Persisted state: State is persisted to disk and is replicated to three or more replicas. 持久化状态是最持久的状态存储选项,在完全群集中断期间其状态也能持久保留。Persisted state is the most durable state storage option, where state can persist through complete cluster outage.
  • 易失性状态:状态将复制到 3 个或更多个副本,且仅保留在内存中。Volatile state: State is replicated to three or more replicas and only kept in memory. 易失性状态可针对节点故障、执行组件故障,以及在升级和资源均衡过程中提供复原能力。Volatile state provides resilience against node failure and actor failure, and during upgrades and resource balancing. 但是,状态不会保留在磁盘中。However, state is not persisted to disk. 因此,如果同时丢失所有副本,状态也会丢失。So if all replicas are lost at once, the state is lost as well.
  • 非持久化状态:状态不会复制或写入到磁盘,仅用于不需要可靠地维护状态的执行组件。No persisted state: State is not replicated or written to disk, only use for actors that don't need to maintain state reliably.

每个级别的持久性只是服务的不同状态提供程序和复制配置。 Each level of persistence is simply a different state provider and replication configuration of your service. 是否要将状态写入磁盘取决于状态提供程序(可靠服务中存储状态的组件)。Whether or not state is written to disk depends on the state provider--the component in a reliable service that stores state. 复制取决于要使用多少个副本来部署服务。Replication depends on how many replicas a service is deployed with. 如同 Reliable Services,你可以轻松地手动设置状态提供程序和副本计数。As with Reliable Services, both the state provider and replica count can easily be set manually. 执行组件框架提供一个属性,对执行组件使用时,该属性会自动选择默认的状态提供程序,并自动生成副本计数的设置,以实现这三种持久性设置中的一个。The actor framework provides an attribute that, when used on an actor, automatically selects a default state provider and automatically generates settings for replica count to achieve one of these three persistence settings. StatePersistence 属性不由派生类继承,每个执行组件类型必须提供其 StatePersistence 级别。The StatePersistence attribute is not inherited by derived class, each Actor type must provide its StatePersistence level.

持久化状态Persisted state

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

此设置使用一个状态提供程序,该提供程序可在磁盘上存储数据,并自动将服务副本计数设置为 3。This setting uses a state provider that stores data on disk and automatically sets the service replica count to 3.

易失性状态Volatile state

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

此设置使用仅在内存中的状态提供程序,并将副本计数设置为 3。This setting uses an in-memory-only state provider and sets the replica count to 3.

非持久化状态No persisted state

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

此设置使用仅在内存中的状态提供程序,并将副本计数设置为 1。This setting uses an in-memory-only state provider and sets the replica count to 1.

默认值和生成的设置Defaults and generated settings

如果使用 StatePersistence 属性,在执行组件服务启动时,系统会在运行时自动为你选择状态提供程序。When you're using the StatePersistence attribute, a state provider is automatically selected for you at runtime when the actor service starts. 但是,副本计数会在编译时由 Visual Studio 执行组件构建工具设置。The replica count, however, is set at compile time by the Visual Studio actor build tools. 生成工具在 ApplicationManifest.xml 中自动为执行组件服务生成 默认服务The build tools automatically generate a default service for the actor service in ApplicationManifest.xml. 参数是针对副本集大小下限目标副本集大小创建的。Parameters are created for min replica set size and target replica set size.

可手动更改这些参数。You can change these parameters manually. 但是,每当 StatePersistence 属性更改时,参数将设置为所选 StatePersistence 属性的默认副本集大小值,并覆盖所有旧值。But each time the StatePersistence attribute is changed, the parameters are set to the default replica set size values for the selected StatePersistence attribute, overriding any previous values. 换言之,更改 StatePersistence 属性值时,在 ServiceManifest.xml 中设置的值将仅 在生成时被覆盖。In other words, the values that you set in ServiceManifest.xml are only overridden at build time when you change the StatePersistence attribute value.

<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>

状态管理器State manager

每个执行组件实例都有其自身的状态管理器:一种类似于字典的数据结构,能够可靠地存储密钥-值对。Every actor instance has its own state manager: a dictionary-like data structure that reliably stores key/value pairs. 状态管理器是围绕状态提供程序的包装。The state manager is a wrapper around a state provider. 无论使用哪个持久性设置,都可以使用它来存储数据。You can use it to store data regardless of which persistence setting is used. 它不保证运行中的执行组件服务可在保留数据的同时,以通过滚动升级从易失性(仅在内存中)状态设置更改保存的状态设置。It does not provide any guarantees that a running actor service can be changed from a volatile (in-memory-only) state setting to a persisted state setting through a rolling upgrade while preserving data. 但是,针对运行中的服务更改副本计数是可行的。However, it is possible to change replica count for a running service.

状态管理器密钥必须为字符串。State manager keys must be strings. 值是泛型的,可以是任何类型(包括自定义类型)。Values are generic and can be any type, including custom types. 存储在状态管理器中的值必须可进行数据协定序列化的,因为根据执行组件的状态持久性设置,它们可能在复制期间通过网络传输到其他节点,并且可能写入磁盘。Values stored in the state manager must be data contract serializable because they might be transmitted over the network to other nodes during replication and might be written to disk, depending on an actor's state persistence setting.

状态管理器公开通用字典方法来管理状态,类似于在可靠字典中找到的项目。The state manager exposes common dictionary methods for managing state, similar to those found in Reliable Dictionary.

有关管理执行组件状态的示例,请阅读访问、保存并删除 Reliable Actors 状态For examples of managing actor state, read Access, save, and remove Reliable Actors state.

最佳实践Best practices

对于管理执行组件状态,下面是一些建议的做法和故障排除技巧。Here are some suggested practices and troubleshooting tips for managing your actor state.

使执行组件状态尽可能细粒度Make the actor state as granular as possible

这对于应用程序的性能和资源使用情况是至关重要的。This is critical for performance and resource usage of your application. 只要对执行组件的“命名状态”有任何写入/更新操作,与该“命名状态”相对应的整个值就会进行序列化,并通过网络发送到次要副本。Whenever there is any write/update to the "named state" of an actor, the whole value corresponding to that "named state" is serialized and sent over the network to the secondary replicas. 次要副本将它写入到本地磁盘并答复主要副本。The secondaries write it to local disk and reply back to the primary replica. 当主要副本收到来自次要副本仲裁的确认时,它会将该状态写入到其本地磁盘。When the primary receives acknowledgements from a quorum of secondary replicas, it writes the state to its local disk. 例如,假设该值是一个具有 20 个成员的类,其大小为 1 MB。For example, suppose the value is a class which has 20 members and a size of 1 MB. 即使只修改了其中一个类成员(大小为 1 KB),最终也得支付全部 1 MB 的序列化、网络和磁盘写入的成本。Even if you only modified one of the class members which is of size 1 KB, you end up paying the cost of serialization and network and disk writes for the full 1 MB. 同样,如果该值为一个集合(如列表、数组或字典),即使修改其中一个成员,也得支付整个集合的成本。Similarly, if the value is a collection (such as a list, array, or dictionary), you pay the cost for the complete collection even if you modify one of it's members. actor 类的 StateManager 接口类似于字典。The StateManager interface of the actor class is like a dictionary. 你始终应为此字典之上表示执行组件状态的数据结构建模。You should always model the data structure representing actor state on top of this dictionary.

正确管理执行组件的生命周期Correctly manage the actor's life-cycle

你应制定明确的策略来管理每个分区中执行组件服务状态的大小。You should have clear policy about managing the size of state in each partition of an actor service. 执行组件服务应具有固定数目的执行组件,并尽可能多地重复使用它们。Your actor service should have a fixed number of actors and reuse them as much as possible. 如果不断地创建新的执行组件,则必须在这些执行组件完成其工作后删除它们。If you continuously create new actors, you must delete them once they are done with their work. 执行组件框架存储有关存在的每个执行组件的一些元数据。The actor framework stores some metadata about each actor that exists. 删除某个执行组件的所有状态不会删除有关该执行组件的元数据。Deleting all the state of an actor does not remove metadata about that actor. 必须删除执行组件(请参阅删除执行组件及其状态),才能删除系统中存储的有关它的所有信息。You must delete the actor (see deleting actors and their state) to remove all the information about it stored in the system. 作为额外的检查,应偶尔查询执行组件服务一次(请参阅枚举执行组件)以确保执行组件数在预期范围内。As an extra check, you should query the actor service (see enumerating actors) once in a while to make sure the number of actors are within the expected range.

如果看到执行组件服务的数据库文件大小不断增加到超出预期大小,请确保你是按照前面的指南进行操作的。If you ever see that database file size of an Actor Service is increasing beyond the expected size, make sure that you are following the preceding guidelines. 如果你是按照这些指南操作的,但仍存在数据库文件大小问题,应通过产品团队开具支持票证以获取帮助。If you are following these guidelines and are still database file size issues, you should open a support ticket with the product team to get help.

后续步骤Next steps

存储在 Reliable Actors 中的状态必须进行序列化,然后才能将其写入到磁盘并进行复制以实现高可用性。State that's stored in Reliable Actors must be serialized before its written to disk and replicated for high availability. 详细了解执行组件类型序列化Learn more about Actor type serialization.

接下来,详细了解执行组件诊断和性能监视Next, learn more about Actor diagnostics and performance monitoring.