我正在从数据库中读取时间序列数据,但这些数据点是不同位置的分区。因此,例如,如果存在1 Hz数据,则每3600个数据点(一小时)存储在不同的分区中。当我读取这些数据点时,我必须以正确的逻辑顺序将它们返回给用户。因此,我必须返回3600个数据点,时间为00:00,然后是3600个数据点,时间为01:00,...直到23:00。当然,数据库查询会有延迟。假设每个查询都是10毫秒。这意味着如果我做concat,它会有24 * 10 ms = 240 ms的延迟。我需要的是一个具有许多并行性的热连接。我无法按顺序执行所有这些查询,然后执行常规连接,因为用户可能需要1年的数据。 目前,我所拥有的是这样的:
public IObservable<int> ReadSensorPartitions( /* Guid sensorId*/)
{
return Observable.Create<int>(async o =>
{
try
{
await Task.Delay(10).ConfigureAwait(false);
Observable.Range(1, 1000).Subscribe(o);
}
catch (Exception e)
{
o.OnError(e);
}
});
}
public IObservable<int> ReadSensorData(int partitionNum)
{
return Observable.Create<int>(async o =>
{
try
{
await Task.Delay(10).ConfigureAwait(false);
Observable.Range(partitionNum*1000, 999).Subscribe(o);
}
catch (Exception e)
{
o.OnError(e);
}
});
}
public IObservable<int> ConcatObservables(IObservable<IObservable<int>> observables)
{
return ReadSensorPartitions().Select(partitionNum => ReadSensorData(partitionNum)).Concat();
}
public async Task TestConcatObservables()
{
var taskCompletionSource = new TaskCompletionSource<bool>();
long count = 0;
var sw = Stopwatch.StartNew();
ConcatObservables(ReadSensorPartitions().Select(partitionNum => ReadSensorData(partitionNum)))
.Subscribe(x =>
{
count++;
}, ex =>
{
}, () =>
{
taskCompletionSource.SetResult(true);
});
await taskCompletionSource.Task.ConfigureAwait(false);
sw.Stop();
Console.WriteLine("TestConcatObservables Duration for {0} datapoint(s) is {1} ms", count, sw.Elapsed.TotalMilliseconds);
}
对于1年的数据,这将至少需要87.6秒。我需要这样的东西
public IObservable<int> HotConcatObservables(IObservable<IObservable<int>> observables, int parallelism)
{
}
例如,如果将并行性设置为24,则前24个读取立即全部预热并缓冲。我们返回分区1,然后是2,...直到24,一旦分区1完成流式传输,我们立即预热分区25.一旦分区2完成流式传输,我们就预热分区26等等。所有这些数据点都必须返回按照正确的逻辑顺序。
我花了很多时间来做这件事,但我做的最好(使用IConnectableObservable)比Merge慢5倍(即使并行性是相同数量的分区)。无论如何还有。这可以有效地完成吗?我真的非常感谢你提供任何帮助。