模块信息
要应用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持久性(事件源)