Actor集群分片实体Actor中最多一次消息传递

问题描述 投票:0回答:1

Actor集群分片中有没有办法实现AT-MOST一次消息传递。

我正在将 Actor 集群分片用于一个用例,其中我有一组集群节点和一组代理节点。
从代理节点,我会将一些消息转发到在 Actor 集群节点中创建的 EntityActor。
为此代理节点将通过 ShardRegion 代理加入到 Actor 集群中。
我必须将消息从代理发送到实体参与者,而不会丢失数据或重复(最多一次)传递。

什么时候会发生数据丢失或重复?

当我发送数据时,我使用 Futures 从实体 Actor 获取确认。未来的对象将最多等待 5 秒(配置)进行确认。在空闲情况下,数据最多将发送一次。

当节点加入/离开/重启时,Shard Region 中的 Shard 将会重新平衡。届时 Shard 不承担任何责任。
如果我们从分片区域代理发送数据,它将保存在缓冲区中。
那时如果我的代理服务器重新启动那么数据就会丢失。(DataLoss)。
如果我在 5 秒后没有得到回复并且我重试,如果缓冲消息在重新平衡后到达,这将是重复。

为此,我通过使用 Exact EntityActor 路径调用 ActorSelection 来检查每条消息是否可用。
如果分片正在重新平衡,那么我会将其插入另一个存储层,当 Actor 在 preStart 中重新平衡时,我将获取这些数据并进行处理,而不会丢失数据。

但是这个 ActorSelection 在高数据速率下需要更多时间。
在没有 ActorSelection 的情况下如何改进这一点以避免数据丢失和数据重复。

还有其他方法可以确保从 ShardRegion 代理到 EntityActor 的最多一次传递吗?

akka actor akka-cluster akka-remote-actor remote-actors
1个回答
0
投票

“没有数据丢失或重复”是“恰好一次”交付(即至少一次和最多一次)。

一般来说,在分布式系统中,一次性交付是不可能的。

最接近的是“有效一次”,这基本上意味着结合重新发送,直到发送者确定消息已经传递,并以这样的方式实现接收者,以便能够识别何时收到的消息是它已经处理了,在这种情况下它会发回确认(希望发送者最终停止重新发送消息),但会忽略该消息。在发送的消息中包含相关 ID 和序列号等技术通常用于帮助接收者确定消息正在被第二次处理。

请注意,一次性交付通常没有用:真正需要的是一次性处理,并且只能由应用程序定义。 Akka 确实提供了对“可靠交付”的支持,但需要注意的是,它确实会造成巨大的吞吐量损失(发送方和接收方都必须是持久的,并且发送的每条消息都需要对数据存储进行四次写入):支持的基础设施将保证您至少硬一次(假设有一个持久队列),接收消息的持久实体 Actor 可以使用接收到的消息中的 seqNr 来识别重复项。

    

© www.soinside.com 2019 - 2024. All rights reserved.