深刻了解redis(二)——redis的前世此生

为何要使用分布式缓存?

1. 高性能

当有一个查询接口,请求的时候可能要花费1s钟的时间,那么若是咱们把这个接口请求的数据放到redis中,那么咱们可能请求这个接口的时间只须要20ms,那么咱们为何不用redis缓存呢?node

2. 高并发

单机mysql的QPS顶天了也就2000左右,再多可能就要报警了,那么若是一个系统,它的高峰期一秒钟过来的请求数是几万条,那一个mysql单机绝对会挂掉。固然咱们能够选择将msql扩容作主从复制等等。可是若是这些请求里面,大部分都是查询请求,那么咱们为何不把这些查询的数据放到redis里面呢,这样的话请求都是请求redis了,对mysql的压力就会很小了。mysql

Redus的线程模型是什么,为何redis是单线程的可是却能支撑高并发呢?

Redis其实是一个单线程工做模型。redis

Redis内部与使用文件事件处理器file event handler,这个文件事件处理器是单线程的,因此redis才叫作单线程的模型。它采用的io多路复用机制(netty也采用这个机制)监听多个socket,将产生事件的socket压入到内存队列中,事件分派器根据socket上的时间类型来选择对应的事件处理器进行处理。sql

文件事件处理器的结构包含四个部分:缓存

1.多个socket
    2.Io多路复用机制
    3.文件事件分派器
    4.事件处理器(链接应答处理器,命令请求处理器,命令回复处理器)
复制代码

事实上,多个socket可能会并发产生不一样的操做,每一个操做对应不一样的文件事件,可是io多路复用程序会监听多个socket,会将产生事件的socket放入到队列中排队,事件分派器每次从队列中取出一个socket,根据socket的时间类型交给对用的时间处理器进行处理。多线程

说白了,所谓的单线程模型,指的就是io多路复用机制,由于io多路复用程序会监听全部的socket,可是io多路复用程序倒是单线程的。并发

那么,为何io多路复用程序是单线程的,可是redis的性能仍然是如此的好呢?app

1.由于redis是纯内存操做的
    2.Io多路复用机制虽然是单线程的,可是它是非阻塞的。
    3.Redis是c语言实现的。
    4.单线程的io多路复用机制,避免了多线程的频繁切换上下文的问题,也预防了多线程可能产生的竞争问题。
复制代码

Redis的过时策略是什么?

Redis的过时策略是:按期删除+惰性删除dom

按期删除,指的是redis默认每隔100ms就会随机抽取一些设置了过时时间的key,检查其是否过时,若是过时就会删除。确定不会去抽取全部的过时时间的key,由于redis上存储的数据太大了,若是每个设置了过时时间的key都会去抽取,那么确定会对redis的性能形成了巨大的影响的。异步

惰性删除,指的是咱们在实际上使用redis的时候,当咱们经过一个key去查询redis的时候,redis会先判断这个key是否过时了,若是过时了就会删除。

可是,若是存在这么一部分数据,它既没有被redis抽取的时候抽取到,也没有被业务使用到,可是它又过时了,那么是否是它就会永远的存储在了redis里面呢,越存越多,最后致使了redis的内存块耗尽了?

这个时候,可能就须要redis另一个机制了,内存淘汰机制。

内存淘汰机制

redis 内存淘汰机制有如下几个:

noeviction: 当内存不足以容纳新写入数据时,新写入操做会报错,这个通常没人用吧,实在是太恶心了。

allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最经常使用的)。

allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key,这个通常没人用吧,为啥要随机,确定是把最近最少使用的 key 给干掉啊。

volatile-lru:当内存不足以容纳新写入数据时,在设置了过时时间的键空间中,移除最近最少使用的 key(这个通常不太合适)。

volatile-random:当内存不足以容纳新写入数据时,在设置了过时时间的键空间中,随机移除某个 key。

volatile-ttl:当内存不足以容纳新写入数据时,在设置了过时时间的键空间中,有更早过时时间的 key 优先移除。

如何保证 redis 的高并发和高可用?

高并发:一主多从,读写分离,主负责写入,从负责读取。 redis 采用异步方式复制数据到 slave 节点,不过 redis2.8 开始,slave node 会周期性地确认本身每次复制的数据量;

一个 master node(主节点) 是能够配置多个 slave node (从节点)的;
    slave node (从节点)也能够链接其余的 slave node(从节点);
    slave node (从节点)作复制的时候,不会 block master node 的正常工做;
    slave node(从节点) 在作复制的时候,也不会 block 对本身的查询操做,它会用旧的数据集来提供服务;
    可是复制完成的时候,须要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了;
    slave node (从节点)主要用来进行横向扩容,作读写分离,扩容的 slave node 能够提升读的吞吐量。
复制代码

由于开启了主从复制,那么咱们必须开启redis的持久化策略。

Redis的持久化

Redis的持久化有两种,RDB和AOF。

RDB

是对redis中的数据执行周期化的持久化。 RDB会生成多个数据文件,每一个数据文件都表明了某一个时刻中的redis的数据,这个多个数据文件的方式,很是适合作冷备份。

RDB对redis进行的持久化的文件,健壮性是很是强的,简单来讲,它就是简单粗暴的给redis建立了一个有一个的快照。所以若是redis宕机了,用RDB来还原数据,会很简单。

RDB的持久化,redis中默认是5分钟一次,也就是说,若是只用RDB作持久化,那么redis最多有可能丢失5分钟的数据,这点仍是很恐怖的,

AOF

AOF机制是对redis的每一条写入命令做为日志,以“append-only”的模式写入一个日志文件中,在redis重启的时候,会回放AOF日志中的写入指令来从新构建整个数据集。

AOF通常都是一秒一次,也就是AOF最多会丢失一秒钟的数据。

相关文章
相关标签/搜索