从分区ID确定分区键(名称或号码范围)

时间:2017-02-08 16:37:02

标签: azure-service-fabric

对于有状态服务,副本是否可以通过其分区ID(GUID值)确定分区键(字符串或数字/数字范围)?查看.NET API,只能从ServicePartitionKey获取副本ID,而不是相反。

2 个答案:

答案 0 :(得分:5)

不,你无法直接从分区ID(guid)获取它。根据您使用的分区类型(Singleton,Int64Range或Named)以及如何设置,可能派生,但无法直接从服务中执行此操作。

这是有道理的,考虑这样一种情况,即您拥有一个带有low key = 0high key = 9和2个分区的Int64分区方案的服务。从0到4的任何分区键最终都会在分区号上结束。分区号为1和键5-9。 2.但是,由于任何使用0到4键的调用最终都会在该服务的同一实例上结束,因此该键实际上是每次调用,而不是每个服务,所以从服务的角度来看,它如何知道它的分区对应哪个密钥,除非这是客户端对服务的调用中的内容,你可以说“对于这个分区XXX的调用关键是123“。目前没有这样的信息烘焙到结构传输通信中,分区在客户端解析,从未传递给服务。

你可以做的是找出分区ID所在的范围。对于Singleton分区方案,你在“分区”上,在那里讨论的不多。对于Named和Int64,您可以使用FabricClient.QueryManager枚举分区:

var fabricClient = new FabricClient();
var partitionList = await fabricClient.QueryManager.GetPartitionListAsync(serviceName);

foreach (var partition in partitionList)
{
    // Partition Guid
    var partitionId = partition.PartitionInformation.Id;

    // Int 64 Range
    var int64PartitionInfo = partition.PartitionInformation as Int64RangePartitionInformation;
    var lowKey = int64PartitionInfo?.LowKey;
    var highKey = int64PartitionInfo?.HighKey;

    // Named Range
    var namedPartitionInfo = partition.PartitionInformation as NamedPartitionInformation;
    var name = namedPartitionInfo.Name;
}

对于命名范围,如果实际上确实为您提供了分区键,因为它是一对一映射,但对于Int64范围,您将只获得该分区的整数范围。

上面的代码也是您每次想要查找分区键时可能不想运行的代码,因为FabricClient.QueryManager相对较慢。

您拥有的另一个选项,如果您能够知道每个服务调用中的分区键很重要,只需将其作为消息参数或消息头添加到您对客户端的调用中(类似于此Passing user and auditing information in calls to Reliable Services in Service Fabric transport

答案 1 :(得分:0)

yoape答案确实很好,应该从客户端需要从服务外部了解分区信息的情况下考虑。但这表明不可能从服务本身内部进行。

问题是,它要求从服务本身中获取此信息,并且有可能获得如下所示的分区信息。

假设您有一个像这样的StatefulService:

class WorkerService : StatelessService {}

在服务中,您可以获取如下分区信息:

switch (this.Partition.PartitionInfo.Kind)
{
    case ServicePartitionKind.Int64Range:
        var rangePartition = this.Partition.PartitionInfo as Int64RangePartitionInformation;
        var lowKey = rangePartition.LowKey;
        var highKey = rangePartition.HighKey;
        break;
    case ServicePartitionKind.Named:
        var namedPartition = this.Partition.PartitionInfo as NamedPartitionInformation;
        var name = namedPartition.Name;
        break;
    case ServicePartitionKind.Singleton:
        var singleton = this.Partition.PartitionInfo as SingletonPartitionInformation;
        var PartitionId = singleton.Id;
        break; 
    default:
        var PartitionId2 = this.Partition.PartitionInfo.Id;
        break;
}

Singleton与默认值相同,两者都使用分区的ID。