假设我有以下两个Actors
每个商店都可以有多个产品,我希望在多台机器上以高流量动态将商店拆分为StoreA和StoreB。分割Store还会在StoreA和StoreB之间平均分割产品。
我的问题是:在拆分后知道将所有未来BuyProduct
请求发送到(StoreA或StoreB)的最佳做法是什么?我问这个的原因是因为如果收到购买ProductA的请求,我想将它发送到已经具有该产品状态的正确商店。
解决方案:我能想到的唯一解决方案是,每次创建新产品时,每个产品Map[productId:Long, storePath:String]
的路径都存储在ProductsPathActor中,每个BuyProduct
请求我将查询ProductPathActor,它将返回正确的Store路径,然后将BuyProduct
请求发送到该商店?
在Akka中有另一种方法可以解决这个问题吗?或者我的解决方案是否正确?
答案 0 :(得分:2)
执行此操作的一个好方法是使用Akka Cluster Sharding。来自文档:
当您需要分配actor时,群集分片非常有用 集群中的几个节点,希望能够与它们进行交互 使用他们的逻辑标识符,但不必关心他们的 群集中的物理位置,也可能随时间而变化。
有一个激活器模板,用于演示here。
对于您的问题,StoreA
和StoreB
的概念均为ShardRegion
,并与您的群集节点进行1:1的映射。 ShardCoordinator
管理这些节点之间的分配,并充当区域之间的管道。
就其本身而言,您的请求处理程序与ShardRegion
进行通信,如果需要,可以与协调器一起路由消息。据推测,每个请求处理程序都有一个JVM本地ShardRegion
可以与之通信,但没有理由说它不能成为远程actor。
当节点数发生变化时,ShardCoordinator
需要移动分片(即由ShardRegion
管理的实体的集合),这些分片将在一个被调用的进程中关闭“再平衡”。在此期间,这些分片中的实体不可用,但是这些实体的消息将被缓冲,直到它们再次可用。为此,“可用”意味着新的ShardRegion
响应该实体的定向消息。
由您决定在新节点上恢复生命。 Akka Persistence使这很简单,但要求您在此过程中使用Event Sourcing模式。这不是一件坏事,因为它可以更容易地导致网络规模的表现。当使用的数据库类似Apache Cassandra时,尤其如此。您将看到节点被“钝化”,这实际上只是缓存到磁盘,因此它们可以根据请求进行恢复,而Akka Persistence可以使用该钝化来透明地恢复在新ShardRegion
控制下的节点 - 本质上是一个“移动”。