了解Akka群集分片

0lvr5msh  于 2022-11-06  发布在  其他
关注(0)|答案(3)|浏览(185)

我正在学习 akka 的碎片化模块。关于碎片化,我有一点不太明白。让我们想象一下,你想对一个演员进行碎片化:你有许多来自同一参与者的实体分布在许多节点上。2每个实体都有自己的状态,状态可能与其他实体不同。
一个客户端正在向您的shard actor发出请求(发送一条消息)以取回其状态值。此消息将由一个实体处理并返回其值作为结果。但如果它由另一个实体处理,结果将是不同的。但它应该是相同的,因为所有实体都派生自同一个actor,不是吗?

sdnqo3pr

sdnqo3pr1#

你似乎误解了Akka集群分片的概念,让我用一个例子来解释。
假设您的服务负责使用用户配置文件响应请求,为了获得极低的延迟,您决定使用Akka actor将用户配置文件缓存在内存中,而不是必须为每个请求查询DB。
如果你的网站只有10个用户,每个用户档案只有几个KB,你可以把10个用户档案放在一个演员的内存中,而且你肯定不需要聚类分片。但是,如果你有1000万用户,1000万用户档案可能无法放入一个演员的内存中,而且如果演员倒下了,成本也会很高。因为这意味着您需要一个大型的DB查询来从持久化中获取这些数据。
在这个场景中,集群分片是一个很好的选择。你将有1000万个Akka参与者,分布在你的集群中,每个参与者只存储一个用户配置文件。所以GetUserProfile(userProfileId = 123)不会给予你不同的响应--它总是被路由到保存用户123的用户配置文件的参与者,因此响应总是相同的。
路由是如何工作的?在doc中选中extractShardIdextractEntityId

7cwmlq89

7cwmlq892#

  • 但是[消息响应]应该是相同的,因为所有的实体都是从同一个参与者派生的,是不是?*

不,每个参与者都有自己的状态,代表着不同的东西。如果你有一个Customer类,你就不会期望每个Customer对象都有相同的数据。每个Customer对象都有自己的名字,id等等。
对于参与者也是如此。参与者有自己的状态,代表某种域实体。如果您向参与者发送GetCustomerName消息,您将期望每个参与者为您提供不同的名称。
对于集群分片来说尤其如此。集群分片的目的是使您可以扩展到单个节点之外:无论是为了可伸缩性、弹性还是恢复力。但它们仍然是Actor,每个Actor都有自己的状态。发送GetCustomerName将(也应该)从每个不同的Actor给予不同的响应。分片只是让您能够将这些Actor分布在多台机器上,并使Actor的位置对发送者透明。

pengsaosao

pengsaosao3#

在Akka集群分片中,每个参与者应该有一个唯一的名称(通常是实体id),并且代表一个唯一的实体。当一个参与者启动/重新启动时,实体加载(通常从数据库)到参与者状态中。
如果执行元接收到更新实体的消息,则执行元应更新数据库和执行元状态,如果执行元接收到读取实体的消息,则执行元应仅从执行元状态读取实体(保证与数据库中的相同,因为所有更新操作仅由一个执行元处理)。
如果任何节点发生故障或者在集群缩放的情况下,则可以在另一个节点、碎片区域上重新创建与所请求的实体相对应的actor。

相关问题