使用Akka缓存公共资源

时间:2016-09-01 19:53:59

标签: concurrency akka

嘿伙计们我想做以下事情:

假设我有一些n个演员都是从一些叫做x的常见变量中读取的。 在后台我想安排一个演员,这个演员将每隔5-10分钟不断更新这个变量。 我不希望n个演员等待这个值更新。即使在更新x时,它们也应该获得一些价值。 那么我该如何以最佳方式处理这种情况呢?

3 个答案:

答案 0 :(得分:1)

无论玩家模型如何,解决它的两种常用方法是推送(当缓存代理向客户端发送更新通知并更新其本地缓存时)或拉取(当客户端每次都点击缓存代理时)。

在任何一种情况下都有一个"当前"缓存版本应该是不可变的(以防止并发问题)。在推送模型中,客户端在本地维护它,在拉模型上,它在缓存代理中维护。从这里,您可以有许多设计选择,这些选择由您的应用程序需求驱动,从而导致不同的权衡。

粗略地说,如果你想保持客户简单使用拉模型。您购买此简单性的代价是无法控制缓存的新鲜度并放弃更新通知的知识。这也会导致更复杂的沟通过程。

如果您想了解实际数据的最新信息并知道何时更新缓存(并可能控制更新过程),请使用推模型。在你的情况下我会考虑到这一点,因为与演员一起实现它非常简单。伪scala中可能的实现:

class Worker extends Actor {
  var cache: String
  def receive = {
    case CacheUpdate(newValue) => cache = newValue
  } 
}

class Publisher extends Actor {
  val workers = new mutable.ListBuffer[ActorRef]()
  def receive = {
    case AddWorker(actor) => 
      workers += actor
      context.watch(actor) // this is important to keep workers list current
    case Terminated(actor) => workers -= actor
    case Update(newValue) => workers.foreach(_ ! CacheUpdate(newValue))
  }
}

您可以将AddWorker消息作为生命周期的一部分发送(在这种情况下,您需要在构造函数中传递Publisher),或者您可以在外部进行协调。

答案 1 :(得分:0)

在不同的演员之间分享可变对象,以及你解释它的方式,你的变量' x'被认为是一种不好的做法。是可变的并且是共享的。

在演员之间分享信息的正确方法是通过不可变的消息。

可能的解决方案之一是:

  • 让一个演员创造你的' n'演员
  • 这个演员为自己安排一条消息
    • 关于此消息的处理,变量已更新
    • 在此之后,这个演员向其子女(“演员”)发送一条消息,其中包含变量' x'
  • 你的每一个' n'演员将收到新的价值作为信息,他们可以为您提供任何期望的信息。

答案 2 :(得分:0)

你可以通过ConsistentHashable

了解这个article 它包含caсhing的详细示例