我正在学习 akka 的碎片化模块。关于碎片化,我有一点不太明白。让我们想象一下,你想对一个演员进行碎片化:你有许多来自同一参与者的实体分布在许多节点上。2每个实体都有自己的状态,状态可能与其他实体不同。一个客户端正在向您的shard actor发出请求(发送一条消息)以取回其状态值。此消息将由一个实体处理并返回其值作为结果。但如果它由另一个实体处理,结果将是不同的。但它应该是相同的,因为所有实体都派生自同一个actor,不是吗?
sdnqo3pr1#
你似乎误解了Akka集群分片的概念,让我用一个例子来解释。假设您的服务负责使用用户配置文件响应请求,为了获得极低的延迟,您决定使用Akka actor将用户配置文件缓存在内存中,而不是必须为每个请求查询DB。如果你的网站只有10个用户,每个用户档案只有几个KB,你可以把10个用户档案放在一个演员的内存中,而且你肯定不需要聚类分片。但是,如果你有1000万用户,1000万用户档案可能无法放入一个演员的内存中,而且如果演员倒下了,成本也会很高。因为这意味着您需要一个大型的DB查询来从持久化中获取这些数据。在这个场景中,集群分片是一个很好的选择。你将有1000万个Akka参与者,分布在你的集群中,每个参与者只存储一个用户配置文件。所以GetUserProfile(userProfileId = 123)不会给予你不同的响应--它总是被路由到保存用户123的用户配置文件的参与者,因此响应总是相同的。路由是如何工作的?在doc中选中extractShardId和extractEntityId
GetUserProfile(userProfileId = 123)
extractShardId
extractEntityId
7cwmlq892#
不,每个参与者都有自己的状态,代表着不同的东西。如果你有一个Customer类,你就不会期望每个Customer对象都有相同的数据。每个Customer对象都有自己的名字,id等等。对于参与者也是如此。参与者有自己的状态,代表某种域实体。如果您向参与者发送GetCustomerName消息,您将期望每个参与者为您提供不同的名称。对于集群分片来说尤其如此。集群分片的目的是使您可以扩展到单个节点之外:无论是为了可伸缩性、弹性还是恢复力。但它们仍然是Actor,每个Actor都有自己的状态。发送GetCustomerName将(也应该)从每个不同的Actor给予不同的响应。分片只是让您能够将这些Actor分布在多台机器上,并使Actor的位置对发送者透明。
GetCustomerName
pengsaosao3#
在Akka集群分片中,每个参与者应该有一个唯一的名称(通常是实体id),并且代表一个唯一的实体。当一个参与者启动/重新启动时,实体加载(通常从数据库)到参与者状态中。如果执行元接收到更新实体的消息,则执行元应更新数据库和执行元状态,如果执行元接收到读取实体的消息,则执行元应仅从执行元状态读取实体(保证与数据库中的相同,因为所有更新操作仅由一个执行元处理)。如果任何节点发生故障或者在集群缩放的情况下,则可以在另一个节点、碎片区域上重新创建与所请求的实体相对应的actor。
3条答案
按热度按时间sdnqo3pr1#
你似乎误解了Akka集群分片的概念,让我用一个例子来解释。
假设您的服务负责使用用户配置文件响应请求,为了获得极低的延迟,您决定使用Akka actor将用户配置文件缓存在内存中,而不是必须为每个请求查询DB。
如果你的网站只有10个用户,每个用户档案只有几个KB,你可以把10个用户档案放在一个演员的内存中,而且你肯定不需要聚类分片。但是,如果你有1000万用户,1000万用户档案可能无法放入一个演员的内存中,而且如果演员倒下了,成本也会很高。因为这意味着您需要一个大型的DB查询来从持久化中获取这些数据。
在这个场景中,集群分片是一个很好的选择。你将有1000万个Akka参与者,分布在你的集群中,每个参与者只存储一个用户配置文件。所以
GetUserProfile(userProfileId = 123)
不会给予你不同的响应--它总是被路由到保存用户123的用户配置文件的参与者,因此响应总是相同的。路由是如何工作的?在doc中选中
extractShardId
和extractEntityId
7cwmlq892#
不,每个参与者都有自己的状态,代表着不同的东西。如果你有一个Customer类,你就不会期望每个Customer对象都有相同的数据。每个Customer对象都有自己的名字,id等等。
对于参与者也是如此。参与者有自己的状态,代表某种域实体。如果您向参与者发送
GetCustomerName
消息,您将期望每个参与者为您提供不同的名称。对于集群分片来说尤其如此。集群分片的目的是使您可以扩展到单个节点之外:无论是为了可伸缩性、弹性还是恢复力。但它们仍然是Actor,每个Actor都有自己的状态。发送
GetCustomerName
将(也应该)从每个不同的Actor给予不同的响应。分片只是让您能够将这些Actor分布在多台机器上,并使Actor的位置对发送者透明。pengsaosao3#
在Akka集群分片中,每个参与者应该有一个唯一的名称(通常是实体id),并且代表一个唯一的实体。当一个参与者启动/重新启动时,实体加载(通常从数据库)到参与者状态中。
如果执行元接收到更新实体的消息,则执行元应更新数据库和执行元状态,如果执行元接收到读取实体的消息,则执行元应仅从执行元状态读取实体(保证与数据库中的相同,因为所有更新操作仅由一个执行元处理)。
如果任何节点发生故障或者在集群缩放的情况下,则可以在另一个节点、碎片区域上重新创建与所请求的实体相对应的actor。