在多处理环境中读取文件的最快方法? C#

时间:2016-12-21 23:08:40

标签: c# multithreading caching ravendb

我有以下挑战:

我有一个包含许多实例的Azure云工作者角色。每一分钟,每个实例都会旋转大约20-30个线程。在每个线程中,它需要读取一些有关如何处理来自3个对象的线程的元数据。对象/数据驻留在远程RavenDb中,即使RavenDb通过HTTP检索对象的速度非常快,但是仍有30多名工作人员负担相当大的负载,每分钟每个线程击中3次(约45个请求/秒) )。大多数时候(如99.999%)RavenDb中的数据不会改变。

我决定实施本地存储缓存。首先,我读了一条小记录,表明元数据是否已经改变(它很少变化),然后我从本地文件存储而不是RavenDb读取,如果本地存储有缓存的对象。我正在使用File.ReadAllText()

这种方法似乎会使机器停滞不前,处理速度会大大降低。我猜测“小”工作者角色的磁盘速度不够快。

无论如何,我可以让操作系统帮助我并缓存这些文件吗?也许有一种替代缓存这些数据的方法吗?

我正在查看每个云角色实例上存储的大约1000个不同大小的文件,大小从100k到10mb不等

1 个答案:

答案 0 :(得分:5)

不是直接的答案,而是三种可能的选择:

使用内置的RavenDB缓存机制

我最初的猜测是你的缓存机制实际上会损害性能。 RavenDB客户端内置了缓存(请参阅此处了解如何对其进行微调:https://ravendb.net/docs/article-page/3.5/csharp/client-api/how-to/setup-aggressive-caching

您遇到的问题是缓存是每台服务器的本地缓存。如果服务器A之前下载了一个文件,如果服务器B下次碰巧处理该文件,它仍然需要获取它。

您可以实施的一个可能选项是划分工作量。例如:

  • 服务器A =>获取以A-D
  • 开头的文件
  • 服务器B =>获取以E-H
  • 开头的文件
  • 服务器C => ...

这将确保您优化每台服务器上的缓存。

获取更大的机器

如果您仍想使用自己的缓存机制,我认为有两件事可能成为瓶颈:

  • 磁盘访问
  • JSON的反序列化

对于这些问题,我唯一能想到的就是获得更大的资源:

  • 如果是磁盘,请使用带有SSD的高级存储。
  • 如果是反序列化,请使用更大的CPU获取VM

缓存RAM中的文件

或者,不是将文件写入磁盘,而是将它们存储在内存中,并获得具有更多RAM的VM。你不应该需要那么多RAM,因为1000个文件* 10MB仍然只有1 GB。这样做可以消除磁盘访问和反序列化。

但最终,最好先测量瓶颈在哪里,看看是否可以通过使用RavenDB的内置缓存机制来缓解它。