关于akka:Cluster-Sharding

72次阅读

共计 3502 个字符,预计需要花费 9 分钟才能阅读完成。

模块信息

要应用 Akka 群集分片,必须在我的项目中增加以下依赖项:

介绍

当您须要在群集中的多个节点之间散布 actors, 并心愿可能应用其逻辑标识符与 actors 进行交互,而又不用关怀 actors 在群集中的物理地位(随工夫变动)时,群集分片将十分有用。

例如,它能够是代表畛域驱动设计术语中的聚合根的 actors。在这里,咱们称这些 actors 为“实体”。这些 actors 通常具备长久(长久)状态,然而此性能并不限于具备长久状态的 actors。

Akka Cluster Sharding 简介视频是学习 Cluster Sharding 的一个很好的终点。

当您有许多有状态的 actors 一起耗费超过一台机器能够提供的资源(例如内存)时,通常应用集群分片。如果只有几个有状态的 actors,则在“群集单例”节点上运行它们可能会更容易。

在这种状况下,分片意味着具备标识符(称为实体)的 actors 能够主动散布在集群中的多个节点上。每个实体 actor 仅在一个中央运行,并且能够将音讯发送到实体,发送方无需晓得指标 actor 的地位。这是通过扩大提供的 ShardRegion actor 发送音讯来实现的,该 actor 晓得如何将带有实体 ID 的音讯路由到最终目的地。

如果启用了该性能,则群集分片将不会在状态为 WeaklyUp 的成员上处于活动状态。

正告
请确保不要应用“群集敞开”策略,免得在网络呈现问题或零碎过载(长时间的 GC 暂停)时将群集拆分为几个独自的群集,因为这将导致启动多个分片和实体,每个独自的群集中都有一个!请参阅 Downing。

根本例子
通过 ClusterSharding 扩大拜访分片:

分片常与持久性一起应用,然而任何行为都能够与分片一起应用,例如 根本计数器:

每个实体类型都有一个 key,该 key 用于检索给定实体标识符的 EntityRef。请留神,在示例的 Counter.create 函数中,未调用 entityId 参数,它是用来演示如何将其传递给实体的。另一种执行此操作的办法是,如果须要,将 entityId 作为音讯的一部分发送。

而后,通过 EntityRef 将音讯发送到特定实体。也能够将办法包装在 ShardingEnvelope 中或定义提取器性能,并将音讯间接发送到 shard 区域。

应在每种实体类型的每个节点上调用群集分片初始化。能够应用角色来管制创立实体 actors 的节点。init 办法将依据节点的角色是否与实体的角色相匹配来创立 ShardRegion 或代理。

指定角色:

长久化示例

应用分片时,能够将实体移至群集中的不同节点。持久性可用于在 actor 挪动后复原其状态。

Akka Persistence 基于单写程序原理,对于特定的 PersistenceId,仅一个持久性 actor 实例处于活动状态。如果多个实例要同时保留事件,则事件将交织并且在重播时可能无奈正确解释。群集分片通常与持久性一起应用,以确保每个 PersistenceId(entityId)只有一个流动实体。

这是用作分片实体的持久性 actor 的示例:

初始化和应用实体:

请留神,如何从 Behavior 的工厂函数中的 EntityTypeKey 和 EntityContext 提供的 EntityId 结构惟一的 PersistenceId。这是定义 PersistenceId 的一种典型办法,然而其余格局也是可能的,如 PersistenceId section 所述。

向持久性实体发送音讯与该实体不是持久性实体雷同。惟一的区别是,当挪动实体时,状态将被复原。在下面的示例中,应用 ask,但能够应用 tell 或其余任何交互模式。

无关更多详细信息,请参见 persistence。

分片调配

分片是一起治理的一组实体。分组通常是由 entityId 的哈希函数定义的。对于特定的实体标识符,分片标识符必须始终雷同。否则,实体 actor 可能会意外地同时在多个中央启动。

默认状况下,分片标识符是实体标识符的 hashCode 的绝对值,以分片总数取模。分片的数量通过以下形式配置:

依据教训,分片的数量应比打算的最大群集节点数量大十倍。不肯定要确切。分片少于节点数会导致某些节点不会托管任何分片。分片过多会导致分片的管理效率升高,例如从新均衡开销,并减少了提早,因为每个分片的第一条音讯的路由中都蕴含了协调器。

集群中所有节点的 number-of-shards 配置值必须雷同,并在退出时通过配置查看进行验证。更改值须要进行集群中的所有节点。

分片被调配给集群中的节点。由分片调配策略决定在何处调配分片。默认实现 ShardCoordinator.LeastShardAllocationStrategy 将新的分片调配给 ShardRegion(节点),并且之前调配的分片数量起码。此策略能够由应用程序指定的实现形式代替。

外局部片调配

另一种调配策略是 ExternalShardAllocationStrategy,它容许通过 ExternalShardAllocation 扩大来显式管制分片在何处调配。例如,这能够用于将 Kafka 分区生产与分片地位相匹配。

要应用它,将其设置为您实体上的调配策略:

对于尚未调配的任何 shardId,它将调配给申请节点。进行明确调配:

任何新的或挪动的分片调配都将在下一次从新均衡时挪动。

从客户端到分片调配策略的通信是通过分布式数据进行的。它应用单个 LWWMap,能够反对成千上万的分片。更高版本能够应用多个 keys 来反对更多的分片。

内部调配策略的示例我的项目

Kafka to Cluster Sharding 是一个示例我的项目,能够下载并带有如何运行的阐明,该示例演示了如何应用外局部片将 Kafka 分区生产对接分片。

自定义分片调配

初始化实体类型或显式应用 withAllocationStrategy 函数时,能够将可选的自定义分片调配策略传递到可选参数中。无关如何实现自定义 ShardAllocationStrategy 的详细信息,请参见 akka.cluster.sharding.AbstractShardAllocationStrategy 的 API 文档。

运行原理

请参阅 Cluster Sharding concepts。

钝化

如果实体的状态是持久性的,则能够进行不用于缩小内存耗费的实体。这是通过实体 actors 的特定于应用程序的实现来实现的,例如,通过定义接管超时(context.setReceiveTimeout)。如果邮件在本身进行时曾经入队,则该邮箱中的排队音讯将被抛弃。为了反对优雅的钝化而不失落此类音讯,实体 actor 能够发送 ClusterSharding.Passivate 到创立实体时传递给工厂办法的 ActorRef <ShardCommand>。可选的 stopMessage 音讯将发送回该实体,而后该实体应自行进行,否则它将主动进行。在接管钝化和实体终止之间,分片将缓冲传入的音讯。尔后,将这些缓冲的消息传递到实体的新化身。

初始化如下:

请留神,在下面的示例中,将 stopMessage 指定为 GoodByeCounter。该音讯会因从新均衡或钝化而自行进行发送给实体。如果未定义 stopMessage,它将主动进行而不接管特定音讯。如果实体须要在进行之前执行一些异步革除或交互,则定义自定义进行音讯可能会很有用。

主动钝化

如果实体在 akka.cluster.sharding.passivate-idle-entity-after 中配置的持续时间内未收到音讯,或者通过将 ClusterShardingSettings 上的 passivateIdleEntityAfter 标记显式设置为适合的工夫以使 actor 放弃活动状态,则这些实体将被主动钝化。请留神,仅对通过分片发送的音讯进行计数,因而在此流动中不计入间接发送给 ActorRef 的音讯或 actor 发送给本身的音讯。能够通过设置 akka.cluster.sharding.passivate-idle-entity-after = off 来禁用钝化。如果启用了“记住实体”,它将主动禁用。

分片状态

有两种类型的状态治理:

  • ShardCoordinator State- 分片地位。这存储在状态存储中。
  • 记住实体 - 流动分片和每个分片中的实体,这是可选的,默认状况下处于禁用状态。这存储在“记住实体存储”中。

状态存储

状态存储对于分片是必不可少的,它蕴含分片的地位。ShardCoordinator 在节点之间挪动后须要加载此状态。

状态存储有两个选项:

  • 分布式数据模式 - 应用 Akka 分布式数据(CRDT)(默认)
  • 持久性模式 -(不倡议应用)应用 Akka 持久性(事件源)
正文完
 0