我正在从C#中的控制台应用程序向Azure表写入大量数据。这将执行以下操作
单个进程的写入速度约为500-700 / s,而没有并行化,要写入10亿个条目,大约需要30天才能完成。我做了以下优化:
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逻辑处理器花费了几乎相同的时间。如所观察到的,写入时间随进程数量线性增加,并且与内核和逻辑处理器的数量无关地奇怪。 Azure表的最大IOPS约为每秒20K。
在控制台应用程序中创建一组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个任务也可以吗?
这是怎么回事,我该如何使用线程/任务解决此问题?
谢谢!