使用流程与线程进行Azure表编写

时间:2019-03-22 01:48:42

标签: c# parallel-processing task

我正在从C#中的控制台应用程序向Azure表写入大量数据。这将执行以下操作

  1. 打开与现有表的连接。
  2. 使用StreamReader读取文件
  3. 一次收集100个查询,并批量写入表中。

单个进程的写入速度约为500-700 / s,而没有并行化,要写入10亿个条目,大约需要30天才能完成。我做了以下优化:

  1. 创建了20个执行上述exe的进程,该进程并行运行而没有任何问题,从而将写入时间减少至1.5天。 [由于代码库的限制,我无法完成理想的情况]

6核/ 12逻辑处理器:

+----------+---------------------------------+--------+------------------------------------ | #process | Time per process per 10k writes | W/s | Total time in hours (1.3b queries) | +----------+---------------------------------+--------+------------------------------------+ | 2 | 14.2s/10k | 1408/s | 256h | | 4 | 14.5s/10k | 2758/s | 130h | | 6 | 14.6s/10k | 4109/s | 87h | | 8 | 15s/10k | 5333/s | 65h | | 12 | 16.1s/10k | 7453/s | 48h | | 16 | 17.9s/10K | 8888/s | 42h | | 18 | 19s/10k | 9473/s | 38h | | 20 | 21.37s/10k | 9358/s | 39h | +----------+---------------------------------+--------+------------------------------------

  1. 核心/ 1逻辑处理器花费了几乎相同的时间。如所观察到的,写入时间随进程数量线性增加,并且与内核和逻辑处理器的数量无关地奇怪。 Azure表的最大IOPS约为每秒20K。

  2. 在控制台应用程序中创建一组20个任务。这不是最佳选择,并且随着内核数减少或线程数增加,性能会下降。对于2个任务,观察到最佳性能。我尝试更改threadPool中的最小限制,但没有任何改变。ThreadPool.SetMinThreads(20, 20);

代码:

foreach (var index in processIndex)
{
    Task t = Task.Run(() => 
    {
        //gets the appropriate file to read and write to table
        string currentFile = string.Format(outFileFormat, index);
        Service service = new Service(currentFile);
        service.JustReadFile();
    });
    tasks.Add(t);
}
tasks.WaitAll();

性能:

+--------+--------+------------------------------------+
| #tasks |  W/s   | Total time in hours (1.3b queries) |
+--------+--------+------------------------------------+
|      2 | 1408/s | 256h                               |
|     16 | ~800/s | ~488h                              |
|     18 | ~800/s | ~488h                              |
|     20 | ~800/s | ~488h                              |
+--------+--------+------------------------------------+

在上面的代码中,我正在做的是读取相应任务的文件。每个任务都有其预分配的文件可读取。这里没有写入天蓝色表,并且它本身在增加任务数量方面具有有害的性能。我认为也许任务正在争夺资源,或者上下文切换的开销太大。由于每个任务都有其自己的Service对象,因此我认为可能并非如此。我也确实认为读取文件和创建对象是一项I / O密集型任务,但是如果20个进程可以处理它,那么20个任务也可以吗?

这是怎么回事,我该如何使用线程/任务解决此问题?

谢谢!

0 个答案:

没有答案