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

Igo*_*rek 6 c# multithreading caching ravendb

我有以下挑战:

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

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

这种方法似乎使机器停滞不前,处理速度大大减慢.我猜测"小"工作者角色的磁盘不够快.

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

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

Ken*_*eth 5

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

使用内置的RavenDB缓存机制

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

您遇到的问题是缓存是每个服务器的本地缓存.如果服务器A之前下载了文件,则服务器B仍然必须在下次处理该文件时获取它.

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

  • 服务器A =>获取以AD开头的文件
  • 服务器B =>获取以EH开头的文件
  • 服务器C => ...

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

获得更大的机器

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

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

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

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

缓存RAM中的文件

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

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