Java--缓存热点数据,最近最少使用算法
1、最近最少使用算法LRU (Least recently used,最近最少使用)
【实现】:最常见的是使用一个链表保存缓存数据

1、新数据插入到链表头部;
2、每当缓存命中(即缓存数据被访问),将数据移动到链表头部;
3、当链表满的时候将链表尾部的数据丢弃;
【代价】
命中时需要遍历链表,找到命中的数据块索引,然后需要将数据移到头部。
【改变】
基于以上代价,我们将维护的链表改为一个双向链表(即每个节点都有个prev和next),另外需要再多维护一个map,将缓存对象的引用放入map中;
1、新数据插入链表头部,并且放入map中
2、每当需要使用缓存时,首先通过key到map中查找,命中缓存后将数据移动到链表头部(这个移动就非常好移动了,只需要把该节点的prev节点的next属性赋值为该节点的next节点,同时把该节点的next节点的prev属性赋值为该节点的prev节点,并且将该节点放入链表头部就可以了)。
3、当链表满的时候将链表尾部的数据丢弃,并且删除map中对应的数据。
【结果】
基于以上改变的LRU算法,完全去除了命中缓存需要遍历链表这个缺点,性能得到了大的提升。
2、使用redis缓存数据,保证热点数据的缓存用法与原理
说一点:只要限制了redis占用的内存,redis会根据自身数据淘汰策略,加载热数据到内存。
【实现】:
通过redis本身的设置过期时间来实现缓存热点数据

1、缓存每命中一次,就重新给该数据设置过期时间
2、那么经常命中的缓存始终不会过期,不会被删除,而非热点数据过期时间一到那么就会被删除掉,保证了redis中始终存在的是热点数据。
【原理】
1、原理其实就是Java中延时阻塞队列DelayQueue的原理
2、当对redis中缓存数据设置过期时间,相当于将缓存数据放入redis中维护的延时阻塞队列DelayQueue。
3、DelayQueue会对放入的缓存数据根据过期时间进行排序,时间短的在前面,时间长的在队列后面。
4、会使用一个或者多个线程循环查询DelayQueue,一旦能从DelayQueue获取元素了就说明该缓存数据到期了,就可以取出来并且删除掉了。
5、当有多个线程都同时查询DelayQueue的时候,只有一个线程能够争取到头元素,其它线程将被阻塞。当头元素被取走以后,会唤醒所有阻塞线程,线程竞争头元素,竞争到头元素的线程会查询头元素的剩余delay时间,并且标记头元素已经被该线程占有,再根据delay时间wait自己,最后获取头元素后唤醒其它阻塞线程。
Java--缓存热点数据,最近最少使用算法的更多相关文章
- 在这个应用中,我使用了 MQ 来处理异步流程、Redis 缓存热点数据、MySQL 持久化数据,还有就是在系统中调用另外一个业务系统的接口,对我的应用来说这些都是属于 RPC 调用,而 MQ、MySQL 持久化的数据也会存在于一个分布式文件系统中,他们之间的调用也是需要用 RPC 来完成数据交互的。
在这个应用中,我使用了 MQ 来处理异步流程.Redis 缓存热点数据.MySQL 持久化数据,还有就是在系统中调用另外一个业务系统的接口,对我的应用来说这些都是属于 RPC 调用,而 MQ.MySQ ...
- 缓存雪崩、穿透如何解决,如何确保Redis只缓存热点数据?
缓存雪崩如何解决? 缓存穿透如何解决? 如何确保Redis缓存的都是热点数据? 如何更新缓存数据? 如何处理请求倾斜? 实际业务场景下,如何选择缓存数据结构 缓存雪崩 缓存雪崩简单说就是所有请求都从缓 ...
- 使用guava cache在本地缓存热点数据
某些热点数据在短时间内可能会被成千上万次访问,所以除了放在redis之外,还可以放在本地内存,也就是JVM的内存中. 我们可以使用google的guava cache组件实现本地缓存,之所以选择gua ...
- java缓存算法【转】
http://my.oschina.net/u/866190/blog/188712 提到缓存,不得不提就是缓存算法(淘汰算法),常见算法有LRU.LFU和FIFO等算法,每种算法各有各的优势和缺点及 ...
- LeetCode之LRU Cache 最近最少使用算法 缓存设计
设计并实现最近最久未使用(Least Recently Used)缓存. 题目描述: Design and implement a data structure for Least Recently ...
- java之ibatis数据缓存
使用IBatis作数据缓存 1.SqlMapConfig.xml中<settingscacheModelsEnabled="true" //设置为trueenhancemen ...
- 简单的java缓存实现
扫扫关注"茶爸爸"微信公众号 坚持最初的执着,从不曾有半点懈怠,为优秀而努力,为证明自己而活. 提到缓存,不得不提就是缓存算法(淘汰算法),常见算法有LRU.LFU和FIFO等算法 ...
- 【转】简单的java缓存实现
本文转自 http://my.oschina.net/u/866190/blog/188712 提到缓存,不得不提就是缓存算法(淘汰算法),常见算法有LRU.LFU和FIFO等算法,每种算法各有各的优 ...
- 面试题之java缓存总结,从单机缓存到分布式缓存架构
1.缓存定义 高速数据存储层,提高程序性能 2.为什么要用缓存(读多写少,高并发) 1.提高读取吞吐量 2.提升应用程序性能 3.降低数据库成本 4.减少后端负载 5.消除数据库热点 6.可预测的性能 ...
随机推荐
- 《Entity Framework 6 Recipes》中文翻译系列 (29) ------ 第五章 加载实体和导航属性之过滤预先加载的实体集合和修改外键关联
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-13 过滤预先加载的实体集合 问题 你想过滤预先加载的实体集合,另外,你想使用 ...
- kindeditor 去掉网络图片上传功能
kindeditor是一款开源的富文本编辑器,其内容设置均为可配置,使用比较灵活. 去掉网络图片的页面:allowImageRemote: false, 修改上传的图片的name:filePostNa ...
- 【原】Telerik radwindow 在IE10下偶尔报 unable to get value of the property 'toLowerCase' 的解决办法
笔者正在开发的新项目在升级了最新版本的Telerik Control和决定支持IE10后,遇到了一个很棘手的问题,偶尔会在打开Radwindow的时候报JS error :unable to get ...
- hbase 1.1.7在centor6.5安装过程
1.自己安装的最新版一直没成功,换成了1.1.7稳定版的.中间遇到的问题记录下 1) jdk 用的1.7版本的,安装过程省略. 2)下载hbase zip包:https://mirrors.tuna ...
- 当GitHub把我当成DDos攻击者拉进了黑名单中。。。
Github黑名单自救+快速稳定FQ 异常处理汇总-开发工具 http://www.cnblogs.com/dunitian/p/4522988.html 原因:项目冲突,没有先更新后提交,他自行更 ...
- Mac SVN 设置代理(Proxy)并 Checkout 代码
1. 设置代理 Finder 菜单里面 -> 前往 -> 前往文件夹 -> /Users/username/.subversion -> 编辑文件 servers 在文件的 [ ...
- C# 获取当前月第一天和最后一天 计算两个日期差多少天
获取当前月的第一天和最后一天 DateTime now = DateTime.Now; DateTime firstDay = ); DateTime lastDay = firstDay.AddMo ...
- ASP.NET MVC5 网站开发实践(二) Member区域 - 用户部分(3)修改资料、修改密码
在上一篇博客中实现了用户的注销和登录,其实代码里落了点东西,就是用户登录要更新最后一次登录时间和登录IP,这次补上.今天做修改资料和修改密码,TryUpdateModel是新用到的东西. 目录: AS ...
- scikit-learn 线性回归算法库小结
scikit-learn对于线性回归提供了比较多的类库,这些类库都可以用来做线性回归分析,本文就对这些类库的使用做一个总结,重点讲述这些线性回归算法库的不同和各自的使用场景. 线性回归的目的是要得到输 ...
- T-Sql(二)事务(Transaction)
今天讲下T-Sql语法中事务的用法,事务在项目中一般用的很少,主要用于转账,或是一些多表操作,第一步完成不了滚回,不执行接下的步骤.要么都不完成要么都完成,这是事务的特征. 语法很简单,示例代码如下: ...