微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

用于协调本地和网络集群的最佳 .Net Actor/Process 框架

如何解决用于协调本地和网络集群的最佳 .Net Actor/Process 框架

我们有一个过程,涉及加载一大块数据,对其应用一些转换,然后输出更改的内容。我们目前运行的网络应用在同一个 CLR 实例中处理这些大数据块的多个实例,这会导致垃圾收集抖动和 OOM 错误

我们已经证明,在更长的运行过程中托管一些跟踪状态可以完美地解决我们的主要问题。我们现在面临的问题是,作为一个有状态系统,我们需要托管它并管理与系统其他部分(还有更改跟踪实例)的协调。

我目前正在评估 Service Fabric 和 Akka 中的 Actor,还有许多其他选择,但在我继续之前,我希望人们对这种方法有以下考虑:

  • 我们的系统中有一个自然的分区点(权威),这意味着我们可以轻松地划分我们的顶级数据集。每个分区将由一个顶级实例表示,该实例需要在自己的本地集群中组织一些子actor,但我们希望单个主机能够运行多个集群。

  • 理想情况下,每个授权参与者集群都应托管在一台机器上,以从本地通信和共享本地资源的一些使用中受益,以绕过消息大小的限制。

  • actor 本身应该是同一个盒子上的独立进程(Akka 似乎在同一个 CLR 实例中运行本地 Actor,这会导致 OOM 上的所有内容崩溃 - 这是真的吗?),这将使我能够启动一个进程,通过它运行转换,发出结果并在不影响其他实例内存/GC 的情况下将其拆除。我明白硬件资源争用仍然是一个问题,但我预计这会比 cpu 密集型内存更多,因此需要一个 RAM 重的盒子。

  • 因为数据模型非常大,而且消息可以包含模型片段或模型片段的更改,所以很难处理不变性。我们不想将每个消息负载克隆到内部状态并将其应用于模型,因此理想情况下,任何使用的 actor 解决方案都将使我们能够使用原始消息负载。这可能会导致恢复 Actor 状态的问题,因为它希望在唤醒时保存和重放这些状态,但由于我们在内部进行状态跟踪,因此我们可以在睡眠时存储此结果的输出

  • 我们需要一个协调器来启动权威集群的实例。在虚拟机/机器的数量和托管在它们上的权限集群的数量方面需要有一定的弹性,并且需要一些东西来处理这些的创建和销毁。

  • 我们有 lot 的 .NET 代码,我们所有的模型、转换和验证都在其中定义,需要大量重复使用。任何需要支持 .Net 的解决方

我的问题是:

虽然这感觉很适合演员,但我有保留,想知道是否有更合适的东西?我尝试过的一切都回到了某种托管流程。

如果演员是正确的方法,考虑到上述问题,哪个技术堆栈会让我最接近我想要实现的目标?

解决方法

IMO(从 JVM Akka 的角度来看,因此我将 akka 标签更改为 akka.net;我对 CLR 方面的知识不太了解),似乎之间的不匹配

我们不想将每个消息负载克隆到内部状态并将其应用到模型中,因此理想情况下使用的任何参与者解决方案都可以使我们能够使用原始消息负载。

actor 本身应该是同一个盒子上的独立进程(Akka 似乎在同一个 CLR 实例中运行本地 Actor,这会导致 OOM 上的所有内容崩溃 - 这是真的吗?)

假设您在谈论相同的操作系统进程,那么它们几乎肯定是相互不兼容的:交换消息强烈建议序列化,因此与复制操作同构。在操作系统进程之间使用共享内存的东西可能会起作用,但您可能必须选择哪个更重要。

同样,“传统”(Erlang/Akka)风格的actor模型中的父/子关系简单地为您提供了本地actor集群(因为它们运行在同一个操作系统进程中,因此允许Akka优化非复制消息直到跨越操作系统进程边界),而在 Service Fabric 或 Orleans(或者,我认为 Cloudstate 或 Lagom)中发现的“虚拟参与者”实现基本上假设分布。

在语义上,虚拟演员模型隐含地假设演员是永恒的(尽管他们的永恒本质可能并不总是化身)。对于您的用例,情况似乎不一定如此。

我认为一组 Akka.Net 实例与分片 Authority actor 生成寿命较短的子 actor 最合适,假设您在尝试同时处理多个大型数据块时遇到了 OOM 问题。您必须自己实现实例扩展/缩减逻辑。

,

我没有与 Akka.net 合作,所以我根本无法谈论这个,但我很乐意在 Service Fabric 上下文中谈论您所谈论的内容。

  • Service Fabric 对运行多个集群的概念没有异议。在它的术语中,您的整个系统将被称为一个应用程序,并且在部署到 SF 集群时会有一个版本。如果您想为其创建多个实例,您需要做的就是选择您想要调用的已部署应用实例,它会为您提供配置。

  • SF 有一个 placement constraints,metric balancing and custom rules 的概念,如果您认为可以比其自动平衡更好地平衡各种资源(或者您需要用于网络 DMZ 目的),则可以使用它。虽然我从来没有亲自将事物归为一台机器,但我经常将服务的访问限制为单个 VM 规模集(我们托管在 Azure 中)。

  • 到最后一点,您仍然会有消息大小限制,但您也可以在某种程度上override。在包含服务接口的项目中,只需在命名空间上方设置以下属性: [assembly:FabricTransportRemotingSettings(MaxMessageSize=<(long)new size in bytes>)] 一切顺利。

  • 服务可以配置为使用共享或独占 process model 运行。

  • 关于您的状态要求,我不一定清楚您要做什么,但我认为您是说您的演员存储任何状态并不重要因为它们可以从一些集中提供的模型中工作。

然后您可能会查看 volatile state persistence ,因为这意味着状态会为演员保存在内存中,但是如果您丢失了副本,则不会将任何内容写入磁盘,因此所有内容都丢失了。或者,如果您不关心并且可以将模型发送给演员进行任何工作,您可以将它们配置为无状态。

  • 另一方面,如果您仍然希望在 actor 中保留状态并且只是关心不变性,请放心,actor 状态不是一成不变的,并且可以简单地更新。您需要记住一些简单的操作顺序问题(例如,如果您检索状态,进行更改,保存它,1)您必须提交事务以使其接受以及 2)如果您修改状态但不t 保存它,它显然不会持续存在 - 在新事务中为任何修改提取一个新副本)。有一大堆指南here

  • 假设您的协调器旨在保存某种状态,我是否可以推荐一个单例状态服务。据推测,它没有收到过多的使用量,因此单个实​​例就足够了,并且可以轻松保存状态(无需担心识别哪个状态在哪个分区上)。至于启动服务,我在第一项中介绍了这一点,但使用内置 FabricClient 上的 ApplicationManager 来设置新应用程序,并使用 ServiceManager 在每个应用程序中创建必要服务的实例。

Service Fabric 从最新的 8.0 release 支持 .NET Core 3.1 到 .NET 5,但请注意 a minor serialization 问题与 .NET 5 的简单解决方法。

如果您有 Azure 支持订阅,我鼓励您在开发问题下写信给团队并分享您的疑虑。或者,在每个月的第三个星期四太平洋标准时间上午 10 点,他们还会在 Teams 上进行社区电话会议,告知您您是 welcome to join,并且您可以找到过去的电话 here

同样,我无法确定这是否比 Akka.NET 更适合,但我们的堆栈构建在 Service Fabric 之上。虽然它有一些缺点(什么框架没有?)但它是分布式软件开发的绝佳平台。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。