0

我正在构建一个解决方案,我们将在其中将(服务结构)无状态服务部署到 K 个实例。该服务的任务是处理一些工作负载(如查询),我想尽可能平均地分配它们之间的工作负载 - 我想让它成为一个动态解决方案,这意味着如果我决定明天从 K 个实例转到 N 个实例,我希望工作负载拆分以一种现在自动将负载分配到 N 个实例的方式进行。我没有为此服务指定任何分区。

举个例子 -

假设我想查询数据库以检索特定的记录块。我有 5 个节点。我希望这 5 个节点检索不同 1/5 的记录集。这可以通过一些查询逻辑来实现,例如 (row_id % N == K) 其中 N 是实例总数, K 是唯一的instance_number

我希望利用FabricRuntime.GetNodeContext().NodeId- 但这会返回一个不太有用的 guid。

我正在寻找一种方法,我可以确定地说它是 N 中的实例编号 M(我需要能够通过 1..N 命名实例) - 所以我可以根据这个设置我的查询逻辑。其中一个要求是,如果该实例出现故障/崩溃等...当 SF 自动重新启动它时,它仍应标识为相同的实例 ID - 以便 2 个或更多节点不会查询同一组结果。

解决这个问题的最佳方法是什么?ApplicationManifest.xml有没有通过or涉及纯配置的解决方案ServiceManifest.xml

4

1 回答 1

0

您的问题没有开箱即用的解决方案,但可以通过多种不同的方式轻松完成。

最简单的方法是将基于队列的负载均衡模式竞争消费者模式结合使用。它包括创建一个队列,将工作添加到队列中,每个实例获取一条消息来处理此工作,如果一个实例宕机并且消息未处理,它会返回队列,另一个实例将其接收。

这样您就不必担心正在运行的实例数量、故障等。

关于放入队列的工作,取决于您是要进行批处理还是逐项处理。

逐项,您为每个正在处理的项目在队列中放置一条消息,这是一种处理工作的简单方法,每个实例一次处理一条消息,或并行处理多条消息。

在批处理中,您可以放置​​一条消息,表示要处理的项目列表以及每个实例处理该批处理直到完成,这有点棘手,因为您可能必须处理正在完成的工作的进度,以防失败,下次你可以从它停止的地方继续。

队列方法是一种反应式设计,在这种情况下,需要将工作放入队列中以触发处理,如果您想要一种主动方法并且需要跟踪哪些工作交给了谁,您可能会更好地使用其他一些方法,例如Leasing 机制,其中每个实例获取属于该实例的租约,直到它释放租约,当您使用分区数据或其他可以轻松拆分负载的机制时,这将更合适。

关于 ID 的问题,一个选项是您所在副本的InstanceId,您可以通过 访问StatelessService.Context.InstanceId,它不是顺序 ID,而是一个随机数。它比使用节点 id 更好,因为您可能在同一个节点上有多个分区,并且 id 会相互冲突。如果您决定使用命名分区,则可以在分区名称中使用 order,因此每个分区都有一个顺序名称。

值得一提的是,服务结构有一个限制,它不允许服务在同一个节点上有多个副本,由于这个限制,您可能必须在设计服务时考虑到这一点,否则一旦达到极限。此外,同一个线程对处理多个分布式项目的方法进行了一些讨论,这可能会给您一些想法。

于 2018-12-19T15:56:32.777 回答