我们正在使用Enterprise Library 5和它在我们的Web应用程序中提供的CacheManager。一切似乎工作正常,直到我们开始对应用程序进行重负载测试。
我们使用基于ID的密钥从数据库缓存记录。我们不是一直从缓存中请求一个项目,有时我们需要从缓存中获取项目列表。为此,我们有一个LINQ查询,它生成一个Select(e => CacheManager.GetData(id_from_list))并返回缓存中的项目列表。大多数情况下,这种方法很好但在重负载下,由于缓存管理器在缓存的读写操作中执行锁定,因此GetData方法成为瓶颈。基本上只有一个线程可以一次从缓存中读取数据。我们确实根据项目的类型创建了几个缓存管理器 - 这允许多个线程从不同的缓存管理器获取数据,但是当重负载到达应用程序时(每个缓存管理器一个瓶颈)仍然存在问题 - 当然它确实改进了应用到某一点但不够。
其他人是否遇到了同样的问题,您是否找到了解决此问题的方法?
注意:我们尝试实际缓存项目列表,并从列表中项目的ID组成密钥。这实际上解决了这个问题,并且cachemanager.getdata不再是一个瓶颈......但是......显然这不是一个好的解决方案,因为我们可以在很多列表中将每个项目放在缓存中数千次。
答案 0 :(得分:1)
您可以考虑调整CacheManager以使用读/写锁(我认为更适合这种情况)而不是它现在使用的独占锁定。
http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx
基本上,当多个读取器线程需要同时访问数据时,读/写锁定是合适的,只有发生写入才会导致传入读取器阻塞。
这些在加载时会有其他问题,例如写入饥饿。根据读/写锁实现,写操作将始终等待所有读操作首先完成 - 使用恒定的读取流,写操作将永远不会发生。