我正在学习缓存,并对缓存的并发性提出了一个问题。
如我所知,LRU缓存是用双链接list + hashtable实现的。那么LRU缓存如何处理高频率并发呢?注从缓存中获取数据和将数据放到缓存中都会更新链接列表和哈希表,这样缓存就会一直被修改。
如果我们将互斥锁用于线程安全,那么如果大量的人访问缓存,速度不是会减慢吗?如果我们不使用锁,那么我们使用了哪些技术?提前谢谢。
发布于 2013-09-24 03:13:57
由于硬件的限制,传统的LRU缓存不是为高并发性而设计的,而且命中代价远小于漏取惩罚(例如数据库查找)。对于大多数应用程序来说,如果缓存仅用于更新底层结构(而不是计算错过的值),那么锁定缓存是可以接受的。像分割LRU策略这样的简单技术通常在锁被竞争时就足够好了。
实现LRU缓存规模的方法是避免在每次访问时更新策略。需要注意的是,缓存的用户并不关心当前的LRU排序是什么。调用方唯一关心的是缓存保持了阈值大小和较高的命中率。这为优化打开了大门,避免在每次读取时更改LRU策略。
memcached采用的方法是在时间窗口(例如1秒)内放弃后续读取。缓存预计将非常大,所以有一个很低的机会驱逐一个可怜的候选人通过这个简单的LRU。
ConcurrentLinkedHashMap (CLHM)和随后的Guava's Cache采用的方法是在缓冲区中记录访问。这个缓冲区是在LRU的锁下耗尽的,并且通过使用try-lock
,不需要阻止任何其他操作。CLHM使用多个环缓冲区,如果缓存无法跟上,这些缓冲区是有损耗的,因为丢失事件比降低性能更好。
Ehcache和redis采用的方法是概率LRU策略。read更新条目的时间戳,写迭代缓存以获得随机示例。最古老的条目是从样本中逐出的。如果示例的构造速度很快,并且缓存很大,则被逐出的条目可能是一个很好的候选项。
可能还有其他技术,当然还有伪LRU策略(如时钟),它们以较低的命中率提供更好的并发性。
https://stackoverflow.com/questions/18968981
复制相似问题