文章目录

  • redis作用
  • 为什么redis访问速度快
  • redis常用场景
  • Redis基本数据类型
  • Redis的持久化
  • Redis持久化提供两种方式:
  • redis通信协议(RESP)
  • Redis有那些架构模式
  • 单机版:
  • 主从复制
  • 哨兵模式
  • 集群类型(高可用架构)
  • redis分布式锁
  • 工作使用场景
  • 如何保证redis中都是热点数据?回收策略
  • 什么是缓存穿透?缓存击穿?缓存雪崩?如何避免?
  • 常见IO三种模型



redis作用

缓存就是内存中存储的数据备份。可以使用持久化把数据存储到硬盘。
放到内存读写速度非常快。可以设置最大内存。

  1. 性能 :在服务器与数据库之间加个redis,我们避免直接频繁的在数据库中增删该查操作,而去缓存中读取。大大增加了速度。
  2. 并发: 在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。而加个redis,先去访问redis. 而且redis采用单线程,避免了不必要的上下文切换和竞争条件,类似于Linux 使用非阻塞IO多路复用。速度非常快。
  3. 可以作为分布式锁使用。

为什么redis访问速度快

  1. 纯内存(RAM)操作而不是硬盘
  2. 单线程操作,避免上下文切换
  3. io多路复用

redis常用场景

session记录
token保持
热点数据
网页缓存

Redis基本数据类型

String 基本类型:可以包含任何数据,比如图片或者序列化的对象。
Hash: 类似于Map,特别适合存储对象
List:列表 ,按照插入顺序存储,可以添加元素到头部或者尾部
Set:无序集合,通过hash表实现,不允许重复,存储和插入顺序无关
Zset:有序集合,不允许重复。double型分数进行从小到大排列。

Redis的持久化

redis是内存数据库,数据都放在内存里,如果做了持久化就是把数据存储到硬盘。防止服务器司机或关机数据丢失。

Redis持久化提供两种方式:

RDB和AOF:
RDB:(redis database) 把数据存储到硬盘中,以RDB的文件格式。称为快照的方式,每隔一段时间就备份一次,类似于mac中的时间机器。也可以手动。当需要恢复时,就恢复。
缺点:可能数据丢失,因为如果我设置五分钟备份一次,那么过了三分钟死机,则这三分钟的数据就都没了。

AOF:记录每次服务器写数据操作。有效的防止数据丢失。
但是会造成AOF文件体积过大,这时我们可以执行一次重写。

恢复数据只需要重启redis,会首先加载AOF文件。

redis通信协议(RESP)

redis客户端和服务器之间通信使用的协议。基于TCP。
特点:简单,快速,可读性好

Redis有那些架构模式

单机版:

redis缓存深度面试题 redis缓存机制面试题_redis缓存深度面试题


内存有限,无法高可用

主从复制

redis缓存深度面试题 redis缓存机制面试题_redis缓存深度面试题_02

多个master的复制品,备份数据。主从服务器同步数据完全相同

特点:降低master读取压力,但没有解决写的压力。

哨兵模式

类似于主从类型但是设置哨兵监控
监控主数据库,如果主数据库出现故障则自动切换,让一个从redis变为主数据库。
增加可用性。稳定性。

集群类型(高可用架构)

之前的架构每个redis中都存储了所有的数据,浪费空间。

可以使用redis集群,也就是分布式存储,把整个数据分为不同的部分存储到不同的redis中

redis缓存深度面试题 redis缓存机制面试题_redis缓存深度面试题_03


多个redis去中心化。类似P2P,每个节点一部分数据和整个集群状态,节点之间可以通信。节点为奇数个,至少三主三从,从节点作为备份保证可用性。读写都是master。节点之间可以交换信息。

可扩展性非常好。

高可用:部分节点不可用时,有备份节点。

redis分布式锁

由于分布式不同服务器操作共享变量的时候就可能出现安全问题,所以也要加锁。
对于单进程多线程的场景,我们可以使用语言和类库提供的锁,而对于分布式场景,我们可以使用分布式锁。

实现:
加锁:用Set NX给Key键设置一个值,并给定一个过期时间超时自动释放锁。
解锁:删除Key键

工作使用场景

一个用户一个userId发送消息给我们服务器。如果我们服务器中没有该用户的咨询,则需要创建咨询。而当新用户首次发送多个微信图片时,我们会几乎同时收到多个图片消息。

因为时新用户,所以要创建咨询,创建咨询过程大概0.4秒。而如果最开始创建咨询之前同时发送多个图片,我们则会几乎同时接到很多条消息。这时就会产生并发问题,创建多个相同咨询。所以我们就要加一个redis锁,锁住userId,当有一个userId创建咨询的时候,相同userId等待。

为什么不使用java多线程锁?
因为是相当于多个客户端发送多个请求,我们不能使用java内部提供的java多线程锁锁住userId,因为多个客户端请求,每次来都创建一个新的userId变量。
而使用Redis分布式锁,则多个客户端使用的是同一个userID,我们锁住userId其他客户端则等待。

如何保证redis中都是热点数据?回收策略

redis中数据集上升到一定大小就会使用淘汰机制,淘汰一定的数据。

  1. 淘汰最近少使用到数据
  2. 淘汰要过期的数据
  3. 淘汰任意数据

什么是缓存穿透?缓存击穿?缓存雪崩?如何避免?

  1. 缓存穿透:缓存和数据库中都没有数据,而用户不断发起请求。若id=-1则为恶意请求。造成服务器压力。 解决方法:拦截id<0的,
  2. 缓存击穿:缓存中无数据而数据库中有数据,并发用户过多,同时读取同一条数据,造成数据库压力过大。 解决方法:设置热点数据不过期。
  3. 缓存雪崩:缓存中大量数据在某一时间段失效,这时取数据都从数据库中取,造成压力。解决:缓存失效后,通过加锁或者消息队列来控制读取数据库线程数量。

常见IO三种模型

  1. 阻塞IO:去买票,一直排队等着拿票,非常慢
  2. 非阻塞IO:去买票,然后过一段时间就去询问一次,有票的时候问到了,但是要自己去问。
  3. 非阻塞IO多路复用:有个黄牛作为委托。select/epoll,找黄牛买,然后过一段时间询问黄牛一次,等黄牛有票了,拿到。 epoll模型:找黄牛,回家等着,黄牛拿到票了打电话告诉我,我去拿。非常省事。redis就使用这种。