【发布时间】:2016-10-12 20:07:07
【问题描述】:
我正在尝试消化 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 的服务客户端查询该数据?
【问题讨论】:
-
a) 不是专家,但我认为分区(在这种情况下)与如何在同一分区中的实例(技术上称为副本)之间共享数据(通过 IReliableStateManager)有关。每个分区可以有两个副本,因此副本 A_1(在节点 1 上)和副本 A_2(在节点 2 上)可以在彼此之间共享数据。但是 A_1 无法与 B_1 共享数据 b) 我认为您的问题可能有太多问题 :)