【问题标题】:Finding partition key for stateful service in Azure Service Fabric在 Azure Service Fabric 中查找有状态服务的分区键
【发布时间】:2017-05-24 07:42:59
【问题描述】:

我已按照此处的步骤在 Azure 中的资源组上创建反向代理。 https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reverseproxy

我相信反向代理正在工作,因为我曾经收到 404 错误,现在我收到 400 Bad Request。

错误代码是 FABRIC_E_INVALID_PARTITION_KEY

这种说法是有道理的,因为在文档中,它说对于不使用单例分区的服务,您必须指定分区键和分区类型,如下所示:

http://mycluster.eastus.cloudapp.azure.com:19008/MyApp/MyService?PartitionKey=3&PartitionKind=Int64Range

我的问题是,我如何获得该分区键?文档明确指出它不是资源管理器中生成的 GUID,所以我不能使用它。我正在从结构之外的外部应用程序联系这个有状态的服务。

【问题讨论】:

    标签: azure azure-service-fabric


    【解决方案1】:

    您在服务资源管理器中看到的PartitionId 是您的服务请求最终所在的分区的唯一 ID。 PartitionKeyPartitionId 不同,它是进入分区哈希的键,并基于该键计算请求最终所在的分区。

    在 Application 项目的 ApplicationManifest.xml 中,新创建的服务的分区键如下所示:

    <Service Name="MyService">
      <StatefulService ServiceTypeName="MyServiceType" 
                       TargetReplicaSetSize="[MyService_TargetReplicaSetSize]"
                       MinReplicaSetSize="[MyService_MinReplicaSetSize]">
        <UniformInt64Partition PartitionCount="[MyService_PartitionCount]"
                               LowKey="-9223372036854775808"
                               HighKey="9223372036854775807" />
      </StatefulService>
    </Service>
    

    这里的UniformInt64Partition 表示使用的是Int64RangeLowKeyHighKey 给出了可接受的 PartitionKey 的范围。 PartitionCount 给出了运行此服务的分区数。在统一范围内,分区从低键统一映射到高键。您可能应该将范围更改为对您的特定服务更有意义的范围。例如:

      <Parameters>
          ...
          <Parameter Name="MyService_PartitionCount" DefaultValue="2" />
          ...
      </Parameters>
      ...
    <Service Name="MyService">
      <StatefulService ServiceTypeName="MyServiceType" 
                       TargetReplicaSetSize="[MyService_TargetReplicaSetSize]"
                       MinReplicaSetSize="[MyService_MinReplicaSetSize]">
        <UniformInt64Partition PartitionCount="[MyService_PartitionCount]"
                               LowKey="0"
                               HighKey="11" />
      </StatefulService>
    </Service>
    

    这将为我们提供 2 个映射的分区:

    • 0 - 5:分区 0
    • 6 - 11:分区 1

    拥有大于分区数量的分区范围对于允许我们稍后进行横向扩展而无需更改分区键是不可或缺的。如果我们在上面的示例中将分区数量(横向扩展)加倍为 4 个分区,那么映射将变为:

    • 0 - 2:分区 0
    • 3 - 5:分区 1
    • 6 - 8:分区 2
    • 9 - 11:分区 3

    我们使用的分区键不会改变,这意味着服务的客户端不受影响。类似的推理也适用于命名方案。另一种可能的方案是 Singleton,通常用于无状态服务。

    可以在此处找到 Microsoft 关于服务分区的文档: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-concepts-partitioning

    回到您的问题,您的分区键可以是您在清单中指定的 LowKey 和 HighKey 范围内的任何整数(如果您使用 UniformInt64Partition)。您收到FABRIC_E_INVALID_PARTITION_KEY 错误表明提供的密钥不是有效的整数。如果它超出了可接受的范围,您可能会收到 FABRIC_E_KEY_NOT_FOUND 作为错误。

    【讨论】:

    • 有没有办法在运行时获取这些信息? ——例如我们可以进行的调用将返回给我们分区元数据,然后我们可以检查以发现分区 0 的范围确实是 0 - 2,分区 1 的范围是 3 - 5,等等? -- 我不想硬编码这样的东西。
    • 是的,您可以使用FabricClient.QueryManager查询特定服务的分区。根据分区方案(int64、命名或单例),您将获得 ServicePartitionInformation 的结果,该结果将为您提供每个分区的跨度(低键 - 高键)或值。这个gist 展示了如何从 SF 服务中检索它。
    • 分区数在运行时不能改变。如果要更改分区数,则需要重新部署,但在这种情况下,所有状态都会丢失。
    • 是的,更改服务的分区是一项复杂的操作,SF 服务不明确支持。您需要手动重新分区和移动您的状态。正如 James 所说,您无法在运行时更改它,但我仍然发现将代码与服务的实际分区稍微分离是一种很好的做法,因为它在不同的环境中可能会非常不同(例如测试与产品)
    【解决方案2】:

    这取决于您选择的分区类型。

    • 对于命名分区,您只需提供名称。
    • 对于 Int64RangePartitions,您提供的 Int64 介于 目标分区的 Higkey 和 Lowkey 值。 (含)

    要找到它:

    在 SF 资源管理器中,导航到有状态服务,然后选择一个分区。在“基本”选项卡上,它显示分区类型和密钥。

    使用内置反向代理的缺点正是您所处的这种情况。调用者需要详细了解服务分区。这就是为什么我选择使用自定义无状态服务作为代理,并自己根据上下文路由调用。 (例如,租户/用户 ID 的哈希值可能导致 int64 分区键)

    【讨论】:

    • 正是我的问题。我创建了一个无状态服务,如果我尝试访问它 ...com:19008/MyApp/MyService 我会收到 FABRIC_E_INVALID_ADDRESS 400 响应。
    • 这是一个不同的错误。但是从你的新问题来看,你似乎已经解决了? (可能缺少控制器操作的路径)stackoverflow.com/questions/41580204/…
    • 好的,我现在可以看到这些疯狂的分区范围——但有些东西告诉我这些是动态的。 -- 有没有办法以编程方式枚举分区,并找出它们的范围?
    • 它们绝对不是动态的。每个分区都包含一个数据分片。该分片需要具有明确定义的范围。以下是列出分区的方法:stackoverflow.com/a/38562986/5946937
    猜你喜欢
    • 2017-06-22
    • 2016-08-03
    • 2017-11-11
    • 2018-10-23
    • 1970-01-01
    • 2016-08-07
    • 2020-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多