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--缓存热点数据,最近最少使用算法的更多相关文章

  1. 在这个应用中,我使用了 MQ 来处理异步流程、Redis 缓存热点数据、MySQL 持久化数据,还有就是在系统中调用另外一个业务系统的接口,对我的应用来说这些都是属于 RPC 调用,而 MQ、MySQL 持久化的数据也会存在于一个分布式文件系统中,他们之间的调用也是需要用 RPC 来完成数据交互的。

    在这个应用中,我使用了 MQ 来处理异步流程.Redis 缓存热点数据.MySQL 持久化数据,还有就是在系统中调用另外一个业务系统的接口,对我的应用来说这些都是属于 RPC 调用,而 MQ.MySQ ...

  2. 缓存雪崩、穿透如何解决,如何确保Redis只缓存热点数据?

    缓存雪崩如何解决? 缓存穿透如何解决? 如何确保Redis缓存的都是热点数据? 如何更新缓存数据? 如何处理请求倾斜? 实际业务场景下,如何选择缓存数据结构 缓存雪崩 缓存雪崩简单说就是所有请求都从缓 ...

  3. 使用guava cache在本地缓存热点数据

    某些热点数据在短时间内可能会被成千上万次访问,所以除了放在redis之外,还可以放在本地内存,也就是JVM的内存中. 我们可以使用google的guava cache组件实现本地缓存,之所以选择gua ...

  4. java缓存算法【转】

    http://my.oschina.net/u/866190/blog/188712 提到缓存,不得不提就是缓存算法(淘汰算法),常见算法有LRU.LFU和FIFO等算法,每种算法各有各的优势和缺点及 ...

  5. LeetCode之LRU Cache 最近最少使用算法 缓存设计

    设计并实现最近最久未使用(Least Recently Used)缓存. 题目描述: Design and implement a data structure for Least Recently ...

  6. java之ibatis数据缓存

    使用IBatis作数据缓存 1.SqlMapConfig.xml中<settingscacheModelsEnabled="true" //设置为trueenhancemen ...

  7. 简单的java缓存实现

    扫扫关注"茶爸爸"微信公众号 坚持最初的执着,从不曾有半点懈怠,为优秀而努力,为证明自己而活. 提到缓存,不得不提就是缓存算法(淘汰算法),常见算法有LRU.LFU和FIFO等算法 ...

  8. 【转】简单的java缓存实现

    本文转自 http://my.oschina.net/u/866190/blog/188712 提到缓存,不得不提就是缓存算法(淘汰算法),常见算法有LRU.LFU和FIFO等算法,每种算法各有各的优 ...

  9. 面试题之java缓存总结,从单机缓存到分布式缓存架构

    1.缓存定义 高速数据存储层,提高程序性能 2.为什么要用缓存(读多写少,高并发) 1.提高读取吞吐量 2.提升应用程序性能 3.降低数据库成本 4.减少后端负载 5.消除数据库热点 6.可预测的性能 ...

随机推荐

  1. 《Entity Framework 6 Recipes》中文翻译系列 (29) ------ 第五章 加载实体和导航属性之过滤预先加载的实体集合和修改外键关联

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-13  过滤预先加载的实体集合 问题 你想过滤预先加载的实体集合,另外,你想使用 ...

  2. kindeditor 去掉网络图片上传功能

    kindeditor是一款开源的富文本编辑器,其内容设置均为可配置,使用比较灵活. 去掉网络图片的页面:allowImageRemote: false, 修改上传的图片的name:filePostNa ...

  3. 【原】Telerik radwindow 在IE10下偶尔报 unable to get value of the property 'toLowerCase' 的解决办法

    笔者正在开发的新项目在升级了最新版本的Telerik Control和决定支持IE10后,遇到了一个很棘手的问题,偶尔会在打开Radwindow的时候报JS error :unable to get ...

  4. hbase 1.1.7在centor6.5安装过程

    1.自己安装的最新版一直没成功,换成了1.1.7稳定版的.中间遇到的问题记录下 1) jdk 用的1.7版本的,安装过程省略. 2)下载hbase  zip包:https://mirrors.tuna ...

  5. 当GitHub把我当成DDos攻击者拉进了黑名单中。。。

    Github黑名单自救+快速稳定FQ 异常处理汇总-开发工具  http://www.cnblogs.com/dunitian/p/4522988.html 原因:项目冲突,没有先更新后提交,他自行更 ...

  6. Mac SVN 设置代理(Proxy)并 Checkout 代码

    1. 设置代理 Finder 菜单里面 -> 前往 -> 前往文件夹 -> /Users/username/.subversion -> 编辑文件 servers 在文件的 [ ...

  7. C# 获取当前月第一天和最后一天 计算两个日期差多少天

    获取当前月的第一天和最后一天 DateTime now = DateTime.Now; DateTime firstDay = ); DateTime lastDay = firstDay.AddMo ...

  8. ASP.NET MVC5 网站开发实践(二) Member区域 - 用户部分(3)修改资料、修改密码

    在上一篇博客中实现了用户的注销和登录,其实代码里落了点东西,就是用户登录要更新最后一次登录时间和登录IP,这次补上.今天做修改资料和修改密码,TryUpdateModel是新用到的东西. 目录: AS ...

  9. scikit-learn 线性回归算法库小结

    scikit-learn对于线性回归提供了比较多的类库,这些类库都可以用来做线性回归分析,本文就对这些类库的使用做一个总结,重点讲述这些线性回归算法库的不同和各自的使用场景. 线性回归的目的是要得到输 ...

  10. T-Sql(二)事务(Transaction)

    今天讲下T-Sql语法中事务的用法,事务在项目中一般用的很少,主要用于转账,或是一些多表操作,第一步完成不了滚回,不执行接下的步骤.要么都不完成要么都完成,这是事务的特征. 语法很简单,示例代码如下: ...