【发布时间】:2016-10-12 06:31:17
【问题描述】:
编辑问题摘要:
- 我想公开一个端点,它能够通过一些查询参数返回部分 xml 数据。
- 我有一个全状态服务(将转换为 DTO 的 xml 数据保存到可靠的字典中)
- 我使用单个命名分区(我只是无法通过传递的查询参数来判断哪个分区保存数据,因此我无法实现一些更智能的分区策略)
- 我正在使用远程服务进行无状态 WEBAPI 服务和有状态服务之间的通信
- XML 数据可能达到 500 MB
- 当 XML 只有大约 50 MB 时一切正常
- 当数据变大时,我 Service Fabric 抱怨 MaxReplicationMessageSize
以及我下面几个问题的总结:如何将大量数据存储到可靠的字典中?
TL 博士;
显然,我错过了什么......
- 我想解析巨大的 XML 并将其加载到可靠的字典中,以便以后对其进行查询。
- 我正在使用单个命名分区。
-
我有一个 XMLData 有状态服务,它通过这种代码的和平将这个 xmls 加载到其 RunAsync 方法中的可靠字典中:
var myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<string, List<HospitalData>>>("DATA"); using (var tx = this.StateManager.CreateTransaction()) { var result = await myDictionary.TryGetValueAsync(tx, "data"); ServiceEventSource.Current.ServiceMessage(this, "data status: {0}", result.HasValue ? "loaded" : "not loaded yet, starts loading"); if (!result.HasValue) { Stopwatch timer = new Stopwatch(); timer.Start(); var converter = new DataConverter(XmlFolder); List <Data> data = converter.LoadData(); await myDictionary.AddOrUpdateAsync(tx, "data", data, (key, value) => data); timer.Stop(); ServiceEventSource.Current.ServiceMessage(this, string.Format("Loading of data finished in {0} ms", timer.ElapsedMilliseconds)); } await tx.CommitAsync(); } -
我有一个无状态的 WebApi 服务,它通过service remoting 与上述有状态的服务通信,并通过此代码查询字典:
ServiceUriBuilder builder = new ServiceUriBuilder(DataServiceName); DataService DataServiceClient = ServiceProxy.Create<IDataService>(builder.ToUri(), new Microsoft.ServiceFabric.Services.Client.ServicePartitionKey("My.single.named.partition")); try { var data = await DataServiceClient.QueryData(SomeQuery); return Ok(data); } catch (Exception ex) { ServiceEventSource.Current.Message("Web Service: Exception: {0}", ex); throw; } 当 XML 不超过 50 MB 时,它运行得非常好。
- 之后我收到如下错误:
System.Fabric.FabricReplicationOperationTooLargeException:复制操作大于配置的限制 - MaxReplicationMessageSize ---> System.Runtime.InteropServices.COMException
问题:
- 我几乎可以肯定这是关于分区策略的,我需要使用更多的分区。但是如何在有状态服务的 RunAsync 方法的上下文中引用特定的分区呢? (有状态服务,通过 WebApi 中的 RPC 调用,其中我明确指出了一个分区,因此如果使用 Ranged 分区策略,我可以轻松地在分区中进行选择 - 但是在运行时初始加载数据时如何做到这一点异步方法)
我的这些想法是否正确:有状态服务中的代码在单个分区上运行,因此大量数据的加载和该数据的分区应该发生在有状态服务之外(如在 Actor )。然后,在确定分区键后,我只需通过 RPC 调用有状态服务并将其指向这个特定分区
实际上,这根本就是一个分区问题吗?是什么(在哪里,谁)定义了复制消息的大小?即分区策略是否会影响复制消息的大小?
将加载逻辑摘录到有状态的 Actor 中是否有帮助?
对于这方面的任何帮助 - 非常感谢!
【问题讨论】:
标签: azure azure-service-fabric