用Java写一个分布式缓存——缓存淘汰算法
1|0前言
之前也用过一些缓存中间件,框架,也想着自己是不是也能用Java写一个出来,于是就有了这个想法,打算在写的过程中同步进行总结。
源码:weloe/Java-Distributed-Cache (github.com)
本篇代码:
我们可以想想几个问题,什么是缓存?为什么需要缓存?
什么是缓存?将之前请求的数据暂存,遇到同样的请求/状况直接返回,这就是缓存。
为什么需要?同样的情况下,直接返回数据,无需其他操作,能加快服务器反应速度,减轻服务器压力。
那么缓存怎么存?简单的缓存为键值对,可以用Map存储。这就完了吗?如果我们一直往Map中存储数据,占用的内存会越来越大,这时候怎么办?
这就是本篇需要解决的问题。
要使用缓存,就必然会面临到缓存使用空间达到上限的问题,这个时候就需要从已有的缓存数据中淘汰一部分去维持缓存的可用性。
2|0LRU
力扣上的相关题 https://leetcode.cn/problems/lru-cache/
LRU,缓存淘汰算法,最近最少使用(Least Recently Used),就是一种选择淘汰数据的策略
原理:为最近被访问的数据进行缓存,淘汰不常被访问的数据。
也就是说我们认为最近使用过的数据应该是有用的,很久都没用过的数据应该是无用的,内存满了就优先删那些很久没用过的数据。
举一个我们最常见的例子,手机可用把软件放到后台运行,比如我们先后打开了日历,设置,闹钟。后台的顺序是 日历->设置->闹钟,如果这台手机只能打开三个应用,再打开 应用商城 ,后台的顺序会变成 应用商城->日历->设置。
从这个案例可以知道LRU的主要两个操作的具体思路,一个数据结构存值,一个数据结构存储后台顺序。
缓存一般以key,value形式存储,因此选择map存储,而存储顺序的数据结构由于要不断改动节点顺序,选择双向链表
2|1put(key,value)
如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。
2|2get(key)
如果关键字 key
存在于缓存中,则返回关键字的值,否则返回 -1
弊端,容易出现缓存污染问题
(k1,v1) (k2,v2),(k3,v3),(k4,v4)
(k2,v2),(k4,v4),(k1,v1),(k3,v3)
3|0LRU-K
LRU-K算法是对LRU算法的改进,将原先进入缓存队列的评判标准从访问一次改为访问K次。
LRU-K算法有两个队列,一个是缓存队列,一个是数据访问历史队列。当访问一个数据时,首先先在访问历史队列中累加访问次数,当历史访问记录超过K次后,才将数据缓存至缓存队列,从而避免缓存队列被污染。同时访问历史队列中的数据可以按照LRU的规则进行淘汰。具体如下:
LRU-K能降低缓存污染发生的概率,但是需要额外记录对象访问次数,内存消耗较大。
4|0测试
__EOF__

本文链接:https://www.cnblogs.com/weloe/p/17050512.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)