Akka:用于在两个参与者之间同步状态的正确模式

zbdgwd5y  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(128)

在Akka中重写过时的persistentView的过程中,我有一个读取操作者需要快照其状态,并且日志事件偏移量是到目前为止已经读取的。要停止需要序列化复合数据结构的视图操作者:(状态+偏移量),我正在将快照偏移量值的责任委托给一个子参与者。然后,问题是同步这两个参与者之间的偏移量值。当前在读取参与者中,我有:

case RecoveryCompleted ⇒
  implicit val ec = context.dispatcher
  val lastSequenceNr = (sequenceSnapshotterRef ? GetLastSnapshottedSequenceNr).mapTo[QueryOffset]
  lastSequenceNr onComplete {
    case Success(QueryOffset(sequenceNr)) ⇒
      offsetForNextFetch = sequenceNr
      doSomethingBasedOnThecompositeData()
      ...

并更新子执行元的偏移值以同步快照,我将执行以下操作:

case RequestSnapshot ⇒
  implicit val ec = context.dispatcher
  val offsetUpdated = sequenceSnapshotterRef ? 
QueryViewSequenceApi.UpdateSequenceNr(offsetForNextFetch)

  offsetUpdated map {
    _ ⇒
      saveSnapshot()
      snapshotRequested = false
  } recover{
    case _ ⇒
      self ! RequestSnapshot
      log.debug("QueryViewSequenceSnapshotter not reachable. Will try again.")
  }
}

然而,这意味着如果子执行元的确认丢失,或者如果子执行元在发送消息之前终止,然后视图执行元在等待来自子执行元的offsetUpdated响应时终止,则当父执行元尝试恢复时,偏移和状态将处于非同步状态。

  • 这种情况值得担心吗?如果一个当地的儿童演员只是像我的儿童演员那样做简单的算术,他会随机死亡吗?
  • 我如何修改设计以确保可以处理这一点呢?我可以潜在地在两端引入一个确认,并在两端引入一个两阶段的同步机制,但这可能会有bug。

下面是问题的完整context

更新:阅读更多关于message delivery reliability的内容,我意识到这是一个更普遍的问题。我是否可以配置这个父代和参与者使用at-least-once交付机制,而项目的其他部分使用默认的at-most-once交付机制?这仍然不能解决子参与者在尝试将确认消息发送回父代之前死亡的问题。

2mbi3lxu

2mbi3lxu1#

我建议使用"请求持续性保证“,以及Akka的死亡守护。这仍然不是微不足道的:很多漏洞仍然存在。
Akka也有一次性保证,但一般来说,我做的是:发送请求直到确认完成。定期告诉,我在发送者中保持状态。超时由调度程序处理。
如果孩子死了,对终结者做出React,继续循环。

相关问题