我有一个现有的Akka Typed应用程序,并且正在考虑使用Durable State
特性添加对持久参与者的支持。我目前没有使用集群分片,但计划在将来的某个时候实现它(在实现持久状态之后)。
我已经阅读了the documentation关于如何实现持久状态以持久化参与者的状态的内容,这一切都是有意义的。但是,在该文档中似乎没有任何关于如何/何时恢复参与者状态的信息,而且我也不太清楚当整个服务重新启动时,我需要做什么来恢复持久化的参与者。
我目前的架构由一个HTTP服务(使用AkkaHTTP)、一个“dispatcher”参与者(它是ActorSystem的守护参与者,目前是一个单例)和N个“worker”参与者(它们是dispatcher的子参与者)组成。
分派器执行元的状态包含requestId-〉ActorRef的Map。当新作业请求从HTTP服务传入时,分派器执行元将创建一个工作执行元,并将其引用存储在Map中。分派器会将相同requestId的未来请求(即状态和结果查询)转发给相应的工作执行元。
目前,如果重新启动整个服务,则会将分派程序执行元重新建立为空白板,并具有空白的工作者对应。工作者执行元不再存在,且无法再撷取其状态/结果。
当服务重新启动时,我想要完成的是重新创建调度程序,并使用其最后持久化的状态。所有在调度程序的工作者Map中的工作者参与者也应该恢复为它们最后持久化的状态。我不确定这有多少是自动的,只是通过使用持久状态将参与者重构为持久化参与者,以及我需要显式地做什么。
问题:
1.在重新启动时,如果我用相同的名称创建调度器(守护者)参与者,这是否足以让Akka知道恢复其持久化状态,或者我需要做一些更明确的事情来告诉它这样做?
1.由于持久性参与者要求状态是可序列化的,因此这是否适用于调度程序的工作者Map通过ActorRef引用工作者的情况?这些工作者是可序列化的吗?还是需要将其切换为通过名称引用它们?
1.如果我将对工作者参与者的引用保留为ActorRefs,并且重新启动服务,那么这些ActorRefs(作为调度程序的持久化状态的一部分恢复的)是否会继续工作,并且工作者参与者的持久化状态是否会自动恢复?或者,同样,我是否需要执行一些明确的操作来告诉它恢复这些参与者并恢复它们的状态。
1.目前,由于所有的worker参与者都不是持久化的,所以我假设它们的状态都保存在内存中。(这是其状态的一部分)。但是,我担心服务器上的内存不足,我希望工作人员完成的工作能够只保存到磁盘上,有点像“让他们进入睡眠状态,”以便将来可以检索他们的工作结果,而不会占用几天或几周后的内存。我希望能够控制参与者何时“在内存中”,何时“仅在磁盘上”。这种持久状态持久性是否可以作为一种机制来实现这一点?如果可以,我是否可以杀死一个参与者,然后在需要时根据需要使其复活(并恢复其状态)?
1条答案
按热度按时间zi8p0yeb1#
持久状态由一个
akka.persistence.typed.PersistenceId
来存储,参与者的名字和它的持久性ID之间没有必要的关系。ActorRef
是可序列化的(所包含的Jackson序列化(CBOR或JSON)可以立即实现;如果使用自定义的序列化程序,则需要使用ActorRefResolver
),尽管在持久化的情况下,这并不一定有用:不能保证ref指向的执行元仍然在那里(例如,假设承载该执行元系统的JVM在保存状态和回读状态之间停止了)。非持久性参与者(假设他们自己不直接与某个持久性数据存储交互:没有什么可以阻止你让一个参与者在启动时从其他地方读取状态(可能会隐藏传入的命令,直到读取完成),并写入状态更改......这基本上是所有持久状态的基础),将它们所有的状态保存在内存中,直到它们被停止。停止一个参与者的机制通常被称为“钝化”:在typed中,通常在参与者的协议中有一个
Passivate
命令。将其恢复通常被称为“再水化”。事件源持久性和持久状态持久性对于实现这一点都非常有用。请注意,运行单节点Akka集群并进行分片是完全可能的。分片带来了“实体”的概念,它有一个字符串名称,在概念上是不朽/永恒的(不像参与者,它有一个定义的从出生到死亡的生命周期)。分片使给定的实体在集群中的任何给定时间最多由一个参与者体现(我忽略了多数据中心的情况:如果有多个数据中心在使用中,您可能需要事件源持久性)。一旦您有了来自sharding的
EntityRef
,EntityRef
将引用任何当前的示例:如果一个消息被发送到EntityRef
,并且没有活动的化身,则会产生一个新的化身。如果提供给分片的那个TypeKey
的行为是持久行为,则会恢复持久状态。分片还可以直接实现钝化(支持一些开箱即用的策略)。您可以自己实现类似的功能(对于调度程序的子进程不多的情况,可以在调度程序中使用简单的Map和询问/观察)。
The Akka Platform Guide tutorial是一个使用集群分片和持久性的示例(在本例中,它是事件源,但持久状态API基本相同,特别是在忽略CQRS位的情况下)。