作者:咖啡拿铁来源:https://www.jianshu.com/p/98a387bd92d81、背景本文是上周去技术沙龙听了一下爱奇艺的JAVA缓存之路有感写出来的 。先简单介绍一下爱奇艺的java缓存道路的发展吧 。
文章插图
可以看见图中分为几个阶段:
- 第一阶段:数据同步加redis
- 第二、三阶段:JavaMap到Guava cache
- 第四阶段: Guava Cache刷新
- 第五阶段: 外部缓存异步刷新
文章插图
这里简单介绍一下爱奇艺缓存发展的五个阶段,当然还有一些其他的优化,比如GC调优,缓存穿透,缓存覆盖的一些优化等等 。有兴趣的同学可以关注公众号,联系我进行交流 。
2、原始社会 - 查库上面说的是爱奇艺的一个进化线路,但是在大家的一般开发过程中,第一步一般都没有redis,而是直接查库 。
在流量不大的时候,查数据库或者读取文件是最为方便,也能完全满足我们的业务要求 。
3、古代社会 - HashMap当我们应用有一定流量之后或者查询数据库特别频繁,这个时候就可以祭出我们的java中自带的HashMap或者ConcurrentHashMap 。我们可以在代码中这么写:
文章插图
但是这样做就有个问题HashMap无法进行数据淘汰,内存会无限制的增长,所以hashMap很快也被淘汰了 。当然并不是说他完全就没用,就像我们古代社会也不是所有的东西都是过时的,比如我们中华名族的传统美德是永不过时的,就像这个hashMap一样的可以在某些场景下作为缓存,当不需要淘汰机制的时候,比如我们利用反射,如果我们每次都通过反射去搜索Method,field,性能必定低效,这时我们用HashMap将其缓存起来,性能能提升很多 。
4、近代社会 - LRUHashMap在古代社会中难住我们的问题无法进行数据淘汰,这样会导致我们内存无限膨胀,显然我们是不可以接受的 。有人就说我把一些数据给淘汰掉呗,这样不就对了,但是怎么淘汰呢?随机淘汰吗?当然不行,试想一下你刚把A装载进缓存,下一次要访问的时候就被淘汰了,那又会访问我们的数据库了,那我们要缓存干嘛呢?
所以聪明的人们就发明了几种淘汰算法,下面列举下常见的三种FIFO,LRU,LFU(还有一些ARC,MRU感兴趣的可以自行搜索):
- FIFO:先进先出,在这种淘汰算法中,先进入缓存的会先被淘汰 。这种可谓是最简单的了,但是会导致我们命中率很低 。试想一下我们如果有个访问频率很高的数据是所有数据第一个访问的,而那些不是很高的是后面再访问的,那这样就会把我们的首个数据但是他的访问频率很高给挤出 。
- LRU:最近最少使用算法 。在这种算法中避免了上面的问题,每次访问数据都会将其放在我们的队尾,如果需要淘汰数据,就只需要淘汰队首即可 。但是这个依然有个问题,如果有个数据在1个小时的前59分钟访问了1万次(可见这是个热点数据),再后一分钟没有访问这个数据,但是有其他的数据访问,就导致了我们这个热点数据被淘汰 。
- LFU:最近最少频率使用 。在这种算法中又对上面进行了优化,利用额外的空间记录每个数据的使用频率,然后选出频率最低进行淘汰 。这样就避免了LRU不能处理时间段的问题 。
推荐阅读
- 快收藏! 30 分钟包你学会 AWK
- 5款茶有效助你减掉腹部脂肪
- 律师|疫情之下,你知道赚钱的职业还有哪些吗?
- 一 鐘乳酒的功效与作用
- 豬膽酒的功效与作用
- 衰老|不化妆出门是一种什么感觉?
- 冬季饮食的五大误区,你中招了吗?
- 8款保健茶助你轻松下火治溃疡
- 汽车打不着火怎么办?除了花钱救援,老司机告诉你几个小妙招
- 5大养生花草茶助你春季驱寒邪