五分钟学后端技术:如何学习Redis、memcache等经常使用缓存技术

原创声明

本文做者:黄小斜git

转载请务必在文章开头注明出处和做者。程序员

本文思惟导图

在这里插入图片描述

什么是缓存

计算机中的缓存

作后端开发的同窗,想必对缓存都不会陌生了,平时咱们可能会使用Redis,MemCache这类缓存组件,或者是本地缓存,来实现一些后端的应用。github

那么,严格来讲,到底什么才是缓存呢,先来看看百度百科的定义。面试

缓存(cache),原始意义是指访问速度比通常随机存取存储器(RAM)快的一种高速存储器,一般它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。缓存的设置是全部现代计算机系统发挥高性能的重要因素之一。redis

最先,“缓存”一词是用来指代计算机硬件中的高速缓存,由于CPU和内存的运算速度差距过大,若是CPU直接和内存交互的话,会浪费掉CPU的大量运算时间,因而有了高速缓存,来为这两个速度差距甚远的组件作中介。数据库

具体的工做原理是,CPU要取数据的时候,先找高速缓存要,因为它们俩的速度差距并不大,因此CPU不会损失掉太多性能,若是数据就在缓存中,那么就直接在缓存里取,不然则到内存去取,取完以后还要留在高速缓存中,以便于下次CPU要使用时无需再到内存中去取。后端

其实,高速缓存还能够分为一级缓存,二级缓存和三级缓存等,每往下一级,速度也就越慢,价格也越低,毕竟,成本是咱们不得不考虑的因素,要否则一切硬件都上顶配,就不须要讨论软件的优化了。数组

除了高速缓存外,其实还有硬盘缓存、网络缓存等操做系统自身实现的缓存,目的也是为了在两个运算速度不一样的组件之间创建一个桥梁,而且,缓存中的数据每每都是局部数据,又称热点数据,这部分数据常常被使用,所以更具备被缓存的价值缓存

软件开发中的缓存

上面讲了一些关于计算机中已有的缓存,那么,咱们平时在代码开发中用的缓存又是什么东西呢?好像不太同样啊。安全

相信你们都听过Redis,这是业界最流行的缓存组件之一,不妨看看它是如何被定义的。

redis是一个key-value存储系统。和Memcached相似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操做,并且这些操做都是原子性的。

在此基础上,redis支持各类不一样方式的排序。与memcached同样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操做写入追加的记录文件,而且在此基础上实现了master-slave(主从)同步。

根据上文的描述,咱们能够看出,Redis是一个K/V的存储系统,而且它是把数据缓存在内存中的,你们都知道,内存比硬盘的速度要快得多,而咱们平时常用的数据库,本质上仍是基于硬盘IO来工做的,每次读写数据库都要通过硬盘的IO操做。

因此,读写数据库的耗时要比读内存要慢得多,刚刚咱们说了,CPU读写内存和高速缓存的速度差别也很大,因此,这里Redis和高速缓存扮演了同一个角色,只不过一个是硬件,一个是软件,一个链接的是内存和CPU,另外一个链接的是磁盘和内存。

除了Redis之外,还有不少缓存组件好比memcache也是基于这种方式来实现的,经过缓存数据库的热点数据,来提升应用的访问速率,在后端开发中是很是常见的一种技术应用。

如何学习缓存技术

做为一个后端开发工程师,不懂缓存是不行的,即便你每天作的是CRUD,至少也要会使用本地缓存吧。

另外,面试的时候常常也会有缓存方面的问题,简单点的,可能就让你说一说Redis的基础和实现原理,复杂点的,会结合场景,问你缓存可能引起的一些问题,又或者,分布式场景下的缓存如何设计。

从会使用到了解原理,再到学习进阶的用法,学习缓存和学习其余技术同样,须要先易后难,如今就让咱们一块儿来看看,如何搞定缓存这个难缠的小妖精吧。

本地缓存chm

第一次接触缓存,实际上是我在学习hashmap的时候,hashmap自己就是一个KV的键值对对象,和我们刚刚说的Redis彷佛有点像,那么,如何让hashmap真正变成一个缓存呢,其实也不难。

实际上,不少本地缓存就是直接用concurrenthashmap来实现的,注意,这里用的是支持并发的concurrenthashmap,这由于啊,缓存对象是能够支持多个线程同时访问的,若是出现同时put好的状况,就有可能出现异常,因而,使用concurrenthashmap就能够避免这种问题。

为了方便起见,后面对于concurrenthashmap简称chm。chm不只能够保证对其访问是线程安全的,并且比直接用synchronized等关键字要更加高效灵活。

那么,chm实现缓存的原理是什么呢?首先,在应用中,缓存的本质就是把一些常常出现的数据存在内存中,而Java的内存又能够分为堆内存和栈内存,缓存对象天然是要放在堆内存中了。

因此它是一个类里的一个成员变量,好比这样。

private Map<String, CacheObj> CACHE_OBJECT_MAP = new ConcurrentHashMap<>();

可是这样使用缓存有一个问题,这个成员变量属于实例,若是实例没有初始化或者是被回收,那么这个缓存对象也就跟着消失了,那确定是不行的,毕竟缓存的生命周期应该和应用自己同样长,另外,这个缓存对象还可能被修改,好比我能够在代码里随便操做一下,让它 = null,或者是从新初始化一下,那同样也是不被容许的。

因此,标准的chm本地缓存应该是这样被初始化的。

private static final Map<String, CacheObj> CACHE_OBJECT_MAP = new ConcurrentHashMap<>();

静态变量保证它一直存在于堆内存中,而final关键字修饰可让它不会被从新初始化或者指向其余对象。

接下来的事情就简单了,你只要使用get和put方法就能够了。
固然,这只是最基础的本地缓存实现,还能够实现成LRU缓存,搞各类骚操做,这里咱们再也不具体讨论,网上有不少demo,能够自行去参考。

经常使用缓存组件实战

除了本地缓存以外,咱们还应该去了解一些经常使用的缓存技术,好比Redis、memcache这类缓存组件,还有相似Ecache这类的Java缓存框架。

这类成熟的缓存技术,更加值得咱们学习和使用,它们通常都能提供各个场景下的先进解决方案,好比如何处理热点数据,如何进行分布式部署,实现高可用,如何进行数据同步,主从复制,以及实现分布式锁、分布式ID生成器等各个场景的应用。

有一个面试题相信你们都遇到过,那就是问你redis和memcache的区别,咱们不妨经过这个面试题来了解一下,到底它们都有些什么特色。

Redis不只支持简单的k/v类型的数据,同时还支持list、set、zset(sorted set)、hash等数据结构的存储,使得它拥有更广阔的应用场景。

而Memcached惟一支持的数据类型是字符串string,很是适合缓存只读数据,由于字符串不须要额外的处理。

Redis最大的亮点是支持数据持久化,它在运行的时候能够将数据备份在磁盘中,断电或重启后,缓存数据能够再次加载到内存中,只要Redis配置的合理,基本上不会丢失数据。

这一点很要命,memcache不持久话数据,万一断电了就裂开。

Memcache在并发场景下,能用cas保证一致性,而Redis事务支持比较弱,只能保证事务中的每一个操做连续执行。

虽然Redis支持事务而memcache不支持,可是memcache对并不是的支持不亚于Redis。

性能方面,Redis在读操做和写操做上是略领先Memcached的。
Memcached的内存管理不像Redis那么复杂,元数据metadata更小,相对来讲额外开销就不多。

对于制度数据来讲,即便没有数据备份也没什么关系,可是若是存在读写,那么显然memcache是不合适的,总体来看,Redis仍是略胜一筹。

Redis这类缓存组件实际上是经过C/S方式部署服务的,而另外一种缓存组件ecache,则是直接集成,缓存的数据就放在JVM里,有点相似于咱们的本地缓存,其实ecache还应用在hibernate中,因此不少时候咱们都是在不知情的状况下就已经使用了cache。

固然了,ecache这类缓存的数据放在JVM,要共享起来的话就比较麻烦了,特别是须要应用在分布式场景的时候,实现起来是比较复杂的。

缓存的实现原理

相信你在看了本地缓存那一部分的时候,会以为缓存实现起来也没什么难度啊,一个hashmap就搞定了。

实际上,缓存的实现要考虑的问题还不少,就拿Redis来讲,使用什么样的数据结构来存储数据就是很重要的一个问题,咱们固然但愿用尽可能小的空间来存尽可能多的数据,同时还要提高缓存CRUD的效率。

Redis中支持多种数据结构,好比字符串、数组、字典(map)以及列表、set、有序set等,别看这些数据结构很简单,可是做者实现起来都花了很多功夫。

每每一个结构有多种底层实现,目的就是为了压缩空间,提升效率。有兴趣的朋友能够看下这篇文章
Redis数据结构的底层实现https://blog.csdn.net/Future_LL/article/details/88525004

除了数据结构以外,Redis自己的实现也回味无穷,好比,Redis的服务端和客户端是怎么设计的,另外,Redis是单线程工做的,为何要这么设计,还有Redis的事务是如何实现的,这些内容都值得咱们一一去学习了解。

另外还有一些进阶的内容,好比Redis的部署方案,一般包括主从部署、集群方案、HA方案等等,Redis官方也有Redis-cluster的高可用集群方案。Redis也经常用于分布式锁,分布式ID生成器,而这些技术的背后,其实都有不少值得咱们深挖的点。

时间关系,咱们今天就讲到这里,对于缓存和Redis的学习,就从这篇文章开始吧。

博客

Java技术仓库《Java程序员复习指南》

https://github.com/h2pl/Java-Tutorial

整合全网优质Java学习内容,帮助你从基础到进阶系统化复习Java

面试指南

全网最热的Java面试指南,共200多页,很是实用,无论是用于复习仍是准备面试都是不错的。
在公众号【Java技术江湖】回复“PDF”便可免费领取。

写在最后

若是以为本文对你有帮助的话,请你也不要吝啬你的“好看”哈,转发朋友圈就是对我最大的支持啦,大家的支持是对我最大的鼓励。

对本系列文章有什么建议和意见,也欢迎留言告诉我,期待你的回馈。

相关文章
相关标签/搜索