Redis深入理解

Redis

Redis的三种集群方式

  1. 主从复制

    原理

    1. 从服务器连接主服务器,发送sync(同步)命令

    2. 主服务器接收到sync命令后,开始执行bgsave命令生成RDB文件并使用缓存区记录此后执行的所有写命令

    3. 主服务器bgsave执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令

    4. 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照

    5. 主服务器快照发送完毕后开始向从服务器发送缓存区中的写命令

    6. 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓存区的写命令

    7. 主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令

    优点

    1. 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离

      1. 为了分载master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由master来完成

    2. Slave同样可以接收其它Slave的连接和同步请求,这样可以有效的分载master的同步压力

    3. master服务器是以非阻塞的方式为Slave提供服务,所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求

    4. slave服务器同样是以非阻塞的方式完成数据同步,在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据

    缺点

    1. redis不具备自动容错和恢复的功能,主机从机的宕机都会导致部分读写请求失败,需要等待机器重启或者手动切换服务IP才能恢复

    2. 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引起数据不一致的问题,降低了系统的可用性

    3. Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得复杂

     

     

  2. 哨兵模式

    原理

    当主服务器中断服务后,可以将一个从服务器升级为主服务器,以便继续提供服务,但是这个过程需要人工来操作,为此,Redis2.8中提供了哨兵工具来实现自动化的系统监控和故障恢复功能

    哨兵的作用就是监控Redis系统的运行情况,它的功能包括以下两个

    1. 监控主服务器和从服务器是否运转正常

    2. 主服务器出现故障时自动将从服务器转换为主服务器

    工作方式

    • 每个哨兵进程以每秒钟一次的频率向整个集群中的Master主服务器、从服务器、以及其它的哨兵发送一个PING命令

    • 如果一个实例距离最后一次有效回复PING命令的时间超过down-after-millinseconds,则这个实例会被哨兵进程标记为主观下线

    • 如果一个master主服务器被标记为下线,则正在监视这个master主服务器的所有哨兵进程要以每秒一次的频率确认master主服务器是否进入了主观下线状态

    • 当有足够数量的哨兵进程在指定时间范围内确认master进入了主观下线状态,则master主服务器会被标记为客观下线

    优点

    • 哨兵模式是基于主从模式的,所有主从的有点,哨兵模式都具有

    • 主从可以自动切换,系统更健壮,可用性更高

    缺点

    • Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂

  3. Redis-cluster集群

    原理

    redis的哨兵模式基本已经可以实现高可用,读写分离,但是这种模式下每台redis服务器都存储相同的数据,很浪费内存,所有redis3.0上加入了集群模式,实现redis的分布式存储,也就是说每台redis节点上存储不同的内容(分片保存)

    Redis-Cluster采用无中心结构,有如下特点

    • 所有redis节点彼此互联(PING-PONG机制),内容使用二进制协议优化传输速度和带宽

    • 节点的fail是通过及群众超过半数的节点检测失效时才生效

    • 客户端与redis节点直联,不需要中间代理层,客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可

    工作方式

    在redis的每一个节点上,都有两个东西,一个是插槽,它的取值范围是0-16383;还有一个就是cluster,可以理解为一个集群管理的插件,当我们存储key时,redis会根据crc16的算法得出一个结果,然后把结果对16384取余,这样每个key都会对一个编号在0-16383之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接跳转到这个对应的节点上进行存取操作

     

    为了保证高可用,redis-cluster集群引入了主从模式,一个主节点和一个或者多个从节点,当主节点宕机的时候,就会启用从节点,当其他主节点ping一个主节点A时,如果半数以上的主节点与A通信超时,那么认为主节点宕机了,如果主节点A和它的从节点A1都宕机了,那么该集群就无法再提供服务

     

Redis中穿透与雪崩的预防及解决

认识缓存穿透

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透

解决办法

  • 如果一个查询返回的数据为空,仍然对这个空结果进行缓存,并且设置超时时间

认识缓存雪崩

如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落在数据库上,造成了缓存雪崩

解决方法

  • 在缓存失效后,通过加锁或者队列控制读数据库写缓存的线程数量

  • 不同的key,设置不同的失效时间

  • 做二级缓存或者双缓存策略。A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期

 

Redis持久化的两种方式

redis提供了两种持久化的方式,分别是RDB(redis database)和 AOF(append only file)

RDB: 就是将存储的数据以快照的方式存储到磁盘上

AOF: 将redis执行过的所有写指令记录下来,通过write函数追加到aof文件的末尾,在下次redis重新启动的时候,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了

 

RDB机制

redis默认的持久化方式

RDB持久化是指在指定的时间间隔内将内存中的数据以快照的形式写入磁盘

这种方式就是将内存中的数据以快照的方式写入到二进制文件中,默认的文件名为:dump.rdb

如果redis不需要持久化,在redis配置文件中可以注释掉所有的save行来停用保存的功能

自动触发方式

可以通过配置设置自动做快照持久化的方式,我们可以配置redis在n秒内如果超过m个key被修改就自动做快照,下面是默认的快照保存配置:

save 900 1 #900秒内如果超过一个key被修改,则发起快照保存

save 300 10 #300秒内如果超过10个key被修改,则发起快照保存

save触发方式

执行save命令,会阻塞Redis服务器,执行save命令期间,Redis不能处理其它命令,执行完成时如果存在老的rdb文件,就用新的替换旧的

bgsave触发方式

执行bgsave命令,redis会在后台异步进行快照操作,快照的同时还可以响应客户端请求

具体操作:redis进程执行fork操作创建子进程,rdb持久化过程由子进程负责,完成后自动结束,阻塞只发生在fork阶段,一般时间很短,基本上redis内部所有的rdb操作都是采用bgsave命令

RDB的优势和劣势

优势
1. rbd文件紧凑,全量备份,非常适合用于进行备份和灾难恢复
  1. 生成rbd文件的时候,redis主进程会fork一个子进程来处理所有的保存工作,主进程不需要进行任何磁盘IO操作

  2. rdb在恢复大数据集时比AOF的速度要快

劣势
  1. 全量备份比较耗时

  2. 服务器宕机可能会导致写操作的数据没有及时保存,造成数据丢失

 

AOF机制

redis会将每一个收到的写命令通过write函数追加到文件中,每当有一个写命令时,就直接保存到aof文件

文件重写原理

aof方式会导致持久化文件越来越大,为了压缩aof持久化文件,redis提供了bgrewriteaof命令,将内存中的数据以命令的方式保存到临时文件中,同时会fork出一条新进程来将文件重写

重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据用命令的方式重写了一个新的aof文件,这点和快照有点类似

 

aof三种触发机制
  1. 每次修改同步always: 同步持久化,每次发生数据变更会被立即记录到磁盘,性能较差但是数据完整性比较好

  2. 每秒同步everysec:异步操作,每秒记录,如果一秒内宕机,有数据丢失

  3. 不同步no: 从不同步

 

优点
  1. aof可以更好的保护数据不丢失,一般aof会每隔一秒,通过一个后台线程执行一次同步操作,最多丢失一秒的数据

  2. aof日志文件没有任何磁盘寻址的开销,写入性能高,文件不容易破损

  3. aof日志文件过大时,会异步执行重写操作,不会影响客户端读写

  4. aof日志文件的命令通过可读的方式进行记录,适合做误删除的紧急恢复,比如不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没发生,可以立即拷贝aof文件,将最后一条flushall命令给删掉,再通过恢复机制恢复所有数据

缺点
  1. 对于同一份数据来说,aof日志文件通常比rdb数据快照文件更大

  2. aof开启后,支持的写QPS会比rbd支持的写QPS低

RDB和AOF如何选择

两者同时开启,如果两者都配置了有限加载aof

 

Redis数据结构及使用场景

  1. String

    既可以存储字符串,也可以存储数字

    可作为原子计数器,比如:阅读量,查询次数,点赞个数等

  2. hash

    存储、读取、修改对象的属性

  3. List

    双向列表实现的List

    实现消息队列

    发布和订阅,可以设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,所

    订阅它的客户端都会受到相应的消息,可以用作实时消息系统,比如:即时聊天,群聊等s

  4. Set

    非常人性化的集合,提供了求交集,并集,差集等操作,非常方便的实现如共同关注、共同喜好、可能认识的朋友等功能

  5. Sorted Set

    将set中的元素增加了一个权重参数score,使得集合中的元素能够按score进行有序排列

    可以用作奖期的排序,排名等

 

redis的过期策略以及内存淘汰机制

redis采用的是定时删除 + 惰性删除策略

定期删除,redis默认每隔100ms检查,是否有过期的key,有过期的key则删除,需要说明的是,redis不是每隔100ms将所有的key检查一遍,而是随机抽取进行检查,如果全部key进行检查,性能太低;因此只采用定期删除策略,会导致很多key到时间没有删除

于是惰性删除排上用场,也就是说:你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期,如果过期就会删除

隐藏问题:

如果定期删除没有删除key,然后也没有及时去请求key,就是说惰性删除没有生效,那么redis的内存会越来越高,此时就应该使用内存淘汰机制。

在redis.conf中有一行配置:

maxmemory-policy volatile-lru

有如下策略:

volatile-lru: 从已设置过期时间的数据集中挑选最近最少使用的数据淘汰

volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰

volatile-random: 从已设置过期时间的数据集中随机选择数据淘汰

allkeys-lru:从数据集中挑选最近最少使用的数据淘汰

allkeys-random: 从数据集中随机选择数据淘汰

no-enviction: 禁止驱逐数据,新写入操作会报错

 

redis线程模型

工作原理

  1. I/O多路复用程序负责监听多个套接字,并向文件事件分派器传送已产生事件的套接字

  2. 尽管多个文件事件会并发的出现,但I/O多路复用程序会将所有产生事件的套接字都放入一个队列里面,然后通过这个队列,以有序、同步、每次一个套接字的方式向文件事件分派器传送套接字

  3. 当上一个套接字产生的事件被处理完毕之后,I/O多路复用程序才会继续向文件事件分派器传送下一个套接字,如果一个套接字又可读又可写的话,那么服务器就先读套接字,后写

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自www.cnblogs.com/zealoter/p/12899816.html