繁体   English   中英

了解 Akka 集群分片

[英]Understanding Akka cluster sharding

我正在学习 Akka 分片模块。 关于分片,我有一些不明白的地方。 假设你想对一个actor进行分片:你有许多来自同一个actor的实体分布在许多节点上。 每个实体都可以有自己的 state,这可能与另一个实体不同。

客户端正在向您的分片 Actor 发出请求(发送消息)以获取其状态值。 这是消息将由实体处理并返回其值作为结果。 但如果它被另一个实体处理,结果会有所不同。 但它应该是相同的,因为所有实体都来自同一个参与者,不是吗?

看来你误解了Akka集群分片的概念,我举个例子解释一下。

假设您的服务负责使用用户配置文件响应请求。 为了获得极低的延迟,您决定使用 Akka 演员来缓存 memory 中的用户配置文件,而不必根据请求查询数据库。

如果您的网站只有 10 个用户并且每个用户配置文件只有几 KB,那么您可以毫无问题地将所有 10 个用户配置文件保存在一个参与者中,并且您肯定不需要集群分片。 但是,如果您有 1000 万用户,那么这 1000 万用户配置文件可能不适合单个参与者的 memory,如果参与者出现故障也会很昂贵,因为这意味着您需要一个大型数据库查询来获取这些数据来自坚持。

在这种情况下,集群分片是合适的。 您将拥有 1000 万个 Akka 参与者,分布在您的集群中,每个参与者仅存储 1 个用户配置文件。 所以GetUserProfile(userProfileId = 123)不会给你不同的响应 - 它总是会被路由到持有用户 123 的用户配置文件的演员,因此响应总是相同的。

路由如何工作? 检查文档中的extractShardIdextractEntityId

但是 [消息响应] 应该是相同的,因为所有实体都来自同一个参与者,不是吗?

不,每个演员都有自己的 state 并代表不同的东西。 如果您有一个客户 class,您不会期望每个客户 object 具有相同的数据。 每个客户 object 都会有自己的姓名、ID 等。

演员也是如此。 演员有自己的 state 并代表某种领域实体。 如果您向一个演员发送GetCustomerName消息,您会希望每个演员给您一个不同的名字。

对于集群分片尤其如此。 集群分片的意义在于,您可以超越单个节点:无论是可扩展性、弹性还是弹性。 但它们仍然是每个都有自己的 state 的 Actor。 发送GetCustomerName将(并且应该)为您提供来自每个不同参与者的不同响应。 分片只是让您能够将这些参与者分布在多台机器上,并使参与者的位置对发送者透明。

在 Akka 集群分片中,每个参与者都应该有一个唯一的名称(通常是实体 ID)并代表一个唯一的实体。 当一个actor启动/重启实体(通常从数据库)加载到actor state中时。

如果参与者接收到更新实体的消息,那么参与者应该更新数据库和参与者 state,如果参与者接收到读取实体的消息,那么参与者应该仅从参与者 state 读取实体(保证与数据库中的所有更新操作仅由一个参与者处理)。

如果任何节点发生故障或在集群扩展的情况下,则可以在另一个节点(分片区域)上重新创建与请求的实体相对应的参与者。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM