服务结构 - 是每个分区的有状态服务单个实例
service fabric - is stateful service single instance per partition
我正在尝试消化 Service fabric 架构模式及其最佳实践。
用例:
我定义了一个有 26 个分区的有状态服务,在每个分区中我都存储了首字母相同的单词。
- 1) 这是否意味着我实际上有 26 个有状态服务实例?
- 2) 在有状态服务之外,即在调用者中 - 我正在为我的服务结构客户端构建一个 URI,指定我希望客户端操作的分区 ID。这是否意味着一旦我处于有状态服务的上下文中(即服务客户端实例化并调用有状态服务)- 我就无法引用其他分区?
3) 有状态服务是需要知道在哪个分区上操作的工作单元,而且不能自己做决定?这里我指的是有状态服务的 RunAsync 方法中的许多示例,其中有对底层可靠存储的调用,例如,代码采取 from this post:
protected override async Task RunAsync(CancellationToken cancelServicePartitionReplica)
{
var myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<string, int>> ("myDictionary");
var partition = base.ServicePartition.PartitionInfo.Id;
byte append = partition.ToByteArray()[0];
while (!cancelServicePartitionReplica.IsCancellationRequested)
{
// Create a transaction to perform operations on data within this partition's replica.
using (var tx = this.StateManager.CreateTransaction())
{
var result = await myDictionary.TryGetValueAsync(tx, "A");
await myDictionary.AddOrUpdateAsync(tx, "A", 0, (k, v) => v + append);
ServiceEventSource.Current.ServiceMessage(this,
$"Append {append}: {(result.HasValue ? result.Value : -1)}");
await tx.CommitAsync();
}
// Pause for 1 second before continue processing.
await Task.Delay(TimeSpan.FromSeconds(3), cancelServicePartitionReplica);
}
}
所以,我的陈述 3) 可能是错误的 - 有状态服务可能会在没有人(服务客户端)调用它的外部并为确切分区提供信息的情况下调用其内部存储。 但是,上面的代码如何决定将其数据放入哪个分区?最重要的是,稍后如何通过应提供准确分区 ID 的服务客户端查询该数据?
有状态服务 'instances' 实际上是副本。您可以为每个分区配置多少个副本(用于性能、扩展、高可用性和灾难恢复)。只有一个副本(主要)进行写入。所有副本(次要副本和主要副本)都可用于读取。副本包含数据集的一个分片。
分区 1 中的数据不与分区 2 共享。
调用有状态服务的客户端需要自行决定要与哪个分区进行通信。服务只能 read/write 在自己的分区中(直接)。
更多信息here。
我正在尝试消化 Service fabric 架构模式及其最佳实践。
用例:
我定义了一个有 26 个分区的有状态服务,在每个分区中我都存储了首字母相同的单词。
- 1) 这是否意味着我实际上有 26 个有状态服务实例?
- 2) 在有状态服务之外,即在调用者中 - 我正在为我的服务结构客户端构建一个 URI,指定我希望客户端操作的分区 ID。这是否意味着一旦我处于有状态服务的上下文中(即服务客户端实例化并调用有状态服务)- 我就无法引用其他分区?
3) 有状态服务是需要知道在哪个分区上操作的工作单元,而且不能自己做决定?这里我指的是有状态服务的 RunAsync 方法中的许多示例,其中有对底层可靠存储的调用,例如,代码采取 from this post:
protected override async Task RunAsync(CancellationToken cancelServicePartitionReplica) { var myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<string, int>> ("myDictionary"); var partition = base.ServicePartition.PartitionInfo.Id; byte append = partition.ToByteArray()[0]; while (!cancelServicePartitionReplica.IsCancellationRequested) { // Create a transaction to perform operations on data within this partition's replica. using (var tx = this.StateManager.CreateTransaction()) { var result = await myDictionary.TryGetValueAsync(tx, "A"); await myDictionary.AddOrUpdateAsync(tx, "A", 0, (k, v) => v + append); ServiceEventSource.Current.ServiceMessage(this, $"Append {append}: {(result.HasValue ? result.Value : -1)}"); await tx.CommitAsync(); } // Pause for 1 second before continue processing. await Task.Delay(TimeSpan.FromSeconds(3), cancelServicePartitionReplica); } }
所以,我的陈述 3) 可能是错误的 - 有状态服务可能会在没有人(服务客户端)调用它的外部并为确切分区提供信息的情况下调用其内部存储。 但是,上面的代码如何决定将其数据放入哪个分区?最重要的是,稍后如何通过应提供准确分区 ID 的服务客户端查询该数据?
有状态服务 'instances' 实际上是副本。您可以为每个分区配置多少个副本(用于性能、扩展、高可用性和灾难恢复)。只有一个副本(主要)进行写入。所有副本(次要副本和主要副本)都可用于读取。副本包含数据集的一个分片。 分区 1 中的数据不与分区 2 共享。
调用有状态服务的客户端需要自行决定要与哪个分区进行通信。服务只能 read/write 在自己的分区中(直接)。
更多信息here。