【问题标题】:Does service fabric create singleton instance for each stateful partition?服务结构是否为每个有状态分区创建单例实例?
【发布时间】:2018-11-28 09:07:45
【问题描述】:

假设我在一个 5 节点集群上创建了一个有 5 个分区的有状态服务结构服务。我看到每个节点每个节点都有 1 个分区。当我在 VS 中调试服务时,我注意到服务结构正在所有 5 个分区中创建 5 个有状态服务的实例 [基本上每个分区 1 个静态实例]。无论客户端进行多少次调用,只有 5 个此类的实例可以提供请求。 以下说法正确吗?

  • 有状态服务中的任何类级别成员变量本质上都是静态的 [因为它解析为该分区上的单例实例],因此在更新时需要“锁定”语义?

  • 由于客户端始终为给定分区解析为类的“相同”实例,因此客户端可以重复使用“代理”实例吗?

  • 当大量客户端每秒调用同一个服务实例数百次时,这种有状态服务创建的“单例”模型如何影响性能和可伸缩性。 [重载下] 我了解到在配置 V2 远程监听器时有一个设置,我们可以通过“FabricTransportRemotingListenerSettings”指定“MaxConcurrentCalls”。

【问题讨论】:

  • 嗨@teeboy。你能澄清一下每个分区有多少个副本吗?每个分区有一个副本吗?
  • 我刚刚意识到我将本地集群更改为 1 个节点。服务结构是否忽略 1 个节点集群的“副本”计数?但是,我在 local.1Node.xml 中的副本数确实为 1。
  • Service Fabric 不会忽略 1 个节点群集上的“副本计数” - 一个节点的单个分区中的“副本”不能超过一个。回到您的问题 - Service Fabric 为每个副本创建一个 StatefulService 类的实例。在副本关闭之前,此实例将处于活动状态。要获得更多信息,我建议您查看service lifecycle
  • 感谢您的链接。我只是重读了一遍。如果结构运行时为每个客户端调用创建多个实例或为每个分区创建一个单例实例,它没有提及任何地方。
  • Service Fabric 为每个客户端请求创建 StatefuleService 类的新实例,而不是为每个副本创建一个实例。要尝试它,您应该创建 5 个节点集群并将 TargetReplicaSetSizeMinReplicaSetSize 指定为 5(那么您总共将拥有 5x5=25 个副本)。另请注意,默认情况下辅助副本不做任何工作,即监听端点(您应该明确指定),默认情况下所有客户端类将始终联系 primary 副本。

标签: azure-service-fabric service-fabric-stateful


【解决方案1】:

这里有一些误解:

实例不同于进程,当你说你可以在 Visual Studio 上看到实例时,你实际看到的是进程。在某些情况下,您可以在一个进程中拥有多个实例,Visual Studio 只会向您显示一个,但实际上有 5 个(在您的情况下)。这是由SF Hosting Model 配置定义的,您可以在其中定义它的行为方式,我已经回答了相关问题here #1here #2

另一个是,无状态服务有实例,有状态服务有分区和副本。基于此,您看到的不是实例,它们是主副本(如果您定义复制> 1,则可能是辅助副本)。在文档中查看更多详细信息here

鉴于前面的详细信息,当您对服务进行分区时,根据您使用的托管模型,它可以在同一个进程或每个进程上创建多个副本。

所有这一切只有一个问题,同一分区的副本数限制为每个节点 1 个,要了解更多信息,请查看 this issue on github

关于您的问题:

无论客户端调用多少次,只有 5 个实例 这个类的服务请求。是否有以下陈述 真的吗?

不!

如果您正在谈论对 ASP.NET 端点的请求或远程调用,这不会影响实例计数,实例由 SF 配置定义,客户端请求不会影响它,它将在可用实例之间拆分取决于您如何平衡这些请求。这些请求会影响实例计数的唯一方式是您在服务中定义自动缩放。

当您的 Stateless\Stateful 服务的新实例\副本启动(在同一进程之内或之外)时,将创建一个新对象。对这些服务的调用可能总是会转到同一个对象,但情况并非总是如此,因为 SF 可能会重新平衡您的服务并杀死这些实例以在其他地方创建新实例,或者在发生故障时。

还有状态服务的情况,调用只转到主副本,除非您指定读取到辅助副本。如果将辅助节点提升为主节点,则新调用不会重定向到以前的主副本。很常见的情况或集群维护和应用程序更新。

有状态服务中的任何类级别成员变量本质上都是静态的 [因为它解析为该服务上的单例实例 partition],因此在更新时需要“锁定”语义?

如果您使用共享托管模型,所有静态对象都将与同一进程中的任何实例共享。

由于客户端总是解析为类的“相同”实例 对于给定的分区,客户端始终可以重复使用“代理” 实例?

根据之前的答案,是的,任何单例类都将被共享。 .

这种有状态服务创建的“单例”模型如何影响 大量客户端调用相同服务时的性能和可扩展性 实例每秒数百次。 【重负荷下】我明白了 配置V2远程监听器时有一个设置 我们可以通过以下方式指定“MaxConcurrentCalls” "FabricTransportRemotingListenerSettings"。

我没有正确理解这里的问题,也许以前的答案可能会为您解决,如果没有,请在下面留下 cmets,我会更新它。

【讨论】:

  • 我的问题与服务结构运行时创建的对象实例特别相关。当我在 Visual Studio 中调试应用程序并在有状态服务上执行“this.GetHashCode()”时,它总是为特定分区返回相同的哈希码。这就是我所指的。我不是在谈论“复制品”。副本可能会有自己的对象实例。
  • 我在答案中添加了更多信息。不应使用GetHashCode() 来识别实例是否相同,因为两个相似的对象可以生成相同的哈希码。
  • @DiegoMendes Service Fabric 基类不会覆盖GetHashCode(),因此它们使用将为每个对象返回不同值的默认实现。
【解决方案2】:

来自微软的确认。服务结构确实为每个分区创建了 1 个“可靠服务”实例。这个“单例”实例将为所有客户端远程处理/http 调用提供服务。如果副本发生故障转移,则会创建一个新实例。

【讨论】:

    猜你喜欢
    • 2016-10-12
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    • 2018-05-31
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多