|
|
51CTO旗下网站
|
|
移动端

2.3.6.4 状态管理器

《Microsoft Azure 管理与开发(下册)平台服务PaaS》本书由世纪互联蓝云Microsoft Azure 开发技术支持团队的资深工程师们编写,主要阐述MicrosoftAzure PaaS 服务的开发应用,涉及计算服务、集成认证服务、数据存储服务、大数据服务等方面的内容。本节为大家介绍状态管理器。

作者:世纪互联蓝云公司来源:电子工业出版社|2018-07-12 18:04

2.3.6.4 状态管理器

有状态Reliable Service 会将状态数据存储于状态管理器的Reliable Collections 里面。Reliable Collections 包含两种数据结构Reliable Dictionary 和Reliable Queue。Reliable Actors的状态管理器只能使用Reliable Dictionary,也就是说Reliable Actors 只能够向状态管理器中存储键值对。与Reliable Service 相同,Reliable Actors 的状态管理器也拥有持久化和复制机制来可靠地维护状态。这样,在发生故障之后,在内存回收重新激活Actor 或者Actor在群集中进行节点迁移时,也不会丢失状态数据。

1. 状态持久化

区别于Reliable Service 的持久化,Reliable Actors 可以设置Actor 的持久化方式。通过设置不同的持久化级别,来适应不同的持久化需求。以下是Reliable Actors 支持的持久化类型。

1) 持久化状态(Persisted),状态会被持久化到磁盘中,并复制到其他副本中。这是最持久的存储选项,即使群集出现中断也不会丢失状态数据。

2) 易状性状态(Volatile),状态仅会被存储到内存中,但也会被复制到其他副本中。当发生节点故障,Actor 故障,以及升级或者资源平衡过程中,可以使用该状态副本来复原Actor、但当所有副本发生故障时,状态数据也会丢失。

3) 非持久化状态(None),状态不复制,也不会写到磁盘中。此级别适合不需要可靠维护状态的Actor。

选择何种持久化类型,取决于Actor 服务程序是否需要维护可靠的状态。如果Actor仅作为计算使用,计算结束后,将结果存储于外部存储系统,如Storage 或者SQL Database,那就无需维护可靠的状态。持久化类型设置示例代码如下:

  1. [StatePersistence(StatePersistence.Persisted)]  
  2. class MyActor : Actor, IMyActor  
  3. {  

StatePersistence 决定Actor 状态的持久化类型,Persisted 代表持久化,Volatile 代表易失性,None 代表非持久化。当设置了StatePersistence 后,在该Actor 启动之后,就会根据配置自动启动对应的状态管理器。

副本数量会在ApplicationManifest.xml 中设置,类似于Reliable Service 有状态服务。可以设置目标副本数量和最小副本数量,配置代码如下,其中TargetReplicaSetSize 和MinReplicaSetSize 分别对应目标副本数量和最小副本数量。在服务运行时,Service Fabric会根据此设置来判断服务是否正常运行,如果当前可用副本数量低于最小副本数量时,就会报安全警报。

  1. <Service Name="MyActorService"  
  2. GeneratedIdRef="77d965dc-85fb-488c-bd06-c6c1fe29d593|Persisted"> 
  3. <StatefulService ServiceTypeName="MyActorServiceType"  
  4. TargetReplicaSetSize="[MyActorService_TargetReplicaSetSize]"  
  5. MinReplicaSetSize="[MyActorService_MinReplicaSetSize]"> 
  6. <UniformInt64Partition PartitionCount="[MyActorService_PartitionCount]"  
  7. LowKey="-9223372036854775808" HighKey="9223372036854775807" /> 
  8. </StatefulService> 
  9. </Service> 

2. 状态管理器API

在Actor 对象中,可以借助状态管理器接口来访问和存储状态数据。因为具有持久化状态的Actor 会把数据存储到磁盘上,首次访问需要磁盘I/O。为了提高性能,所以状态管理器接口方法都是异步的。状态管理器并不是每次都会从磁盘中读取数据,只有首次访问数据时,会将磁盘中的数据缓存到内存中,之后的重复访问会直接从内存中获取数据,减少磁盘I/O 和异步上下文切换带来的开销。缓存到内存的数据也并不是一直存放在内存中,在以下情况下,是会删除内存数据的。

(1) 从状态管理器中检索状态数据时,发生未知的异常。

(2) Actor 停用或者发生故障后重新激活。

(3) 当Actor 选择持久化状态的持久化类型时,状态持久化程序会定期将内存中的状态分页同步到磁盘中。

使用状态管理器检索状态数据,因为Actor 的状态管理器只能存储键值对,随意检索时,只需要使用key 值进行检索。状态管理器提供两种检索方法:GetStateAsync()和TryGetStateAsync()。两者的区别是,前者如果没有检索到状态数据时,会触发抛出异常KeyNotFoundException;后者则不会报异常,而是会在返回的结果中表示有没有值存在。可以根据业务需要来选择这两种方式。使用GetStateAysnc()获取状态数据代码示例如下:

  1. [StatePersistence(StatePersistence.Persisted)]  
  2. class MyActor : Actor, IMyActor  
  3. {  
  4. public MyActor(ActorService actorService, ActorId actorId)  
  5. : base(actorService, actorId)  
  6. {  
  7. }  
  8. public Task<int> GetCountAsync()  
  9. {  
  10. return this.StateManager.GetStateAsync<int>("MyState");  
  11. }  

使用TryGetStateAsync()获取状态数据代码示例如下:

  1. [StatePersistence(StatePersistence.Persisted)]  
  2. class MyActor : Actor, IMyActor  
  3. {  
  4. public MyActor(ActorService actorService, ActorId actorId)  
  5. : base(actorService, actorId)  
  6. {  
  7. }  
  8. public Task<int> GetCountAsync()  
  9. {  
  10. return this.StateManager.GetStateAsync<int>("MyState");  
  11. }  

使用检索方法获取的状态数据对象只是本地内存中的对象引用,如果修改该值,只会修改本地内存的数据对象,并不会被持久化到状体管理器中,必须将修改后状态数据重新插入到状态管理器才能够永久保存。可以使用状态管理的SetStateAsync 或者AddStateAsync方法来将数据插入到状态管理器中,其中AddStateAsync 是插入状态数据,当状态管理存在相同key 的值时,就会报异常信息InvalidOperationException。相应的状态管理也有TryAddStateAsync 方法,此方法与AddStateAsync 功能一样,不同之处是不会触发异常,而且在已存在相同key 值的情况下,将不插入操作。使用AddStateAsync 插入状态数据代码示例如下:

  1. this.StateManager.AddStateAsync<int>("MyState", value); 

使用TryAddStateAsync 插入状态数据代码示例如下,返回结果为是否插入成功。

  1. bool result = this.StateManager.TryAddStateAsync<int>("MyState", value); 

当完成Actor 服务方法后,状态管理器会自动将方法中所有对状态数据的插入和修改内容提交保存。这时所有的修改将会被持久化,并将会被同步到其他副本,未修改的值将不会被持久化和同步。如果保存出现错误的话,将回滚本次的所有修改操作,并恢复至修改之前的状态。另外,状态管理器也提供了手动保存的方法,可以调用SaveStateAsync 方法,来灵活控制状态数据的保存。

状态管理器也提供删除状态数据的方法,可以使用删除方法永久删除状态数据。当删除并保存状态成功后,所有的副本都将永久清除被删除数据,而且无法被恢复。同样,删除也提供了两种方式,一种是RemoveStateAsync,删除时,如果key 值不存在,将会抛出异常KeyNotFoundException;另外一种是TryRemoveStateAsync,作用与Remove 一样,只是不会报异常,而是返回删除成功的状态。


喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书频道活动讨论群:365934973

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

Cisco网络技术教程(第2版)

本书作为思科认证体系中的入门级教材,主要讲述了网络的基本知识和思科设备的基本命令,以及路由、交换等深层次网络知识的入门知识,其体系...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊