Redis深入理解
Redis
Redis的三种集群方式
主从复制
原理
从服务器连接主服务器,发送sync(同步)命令
主服务器接收到sync命令后,开始执行bgsave命令生成RDB文件并使用缓存区记录此后执行的所有写命令
主服务器bgsave执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令
从服务器收到快照文件后丢弃所有旧数据,载入收到的快照
主服务器快照发送完毕后开始向从服务器发送缓存区中的写命令
从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓存区的写命令
主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令
优点
支持主从复制,主机会自动将数据同步到从机,可以进行读写分离
为了分载master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由master来完成
Slave同样可以接收其它Slave的连接和同步请求,这样可以有效的分载master的同步压力
master服务器是以非阻塞的方式为Slave提供服务,所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求
slave服务器同样是以非阻塞的方式完成数据同步,在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据
缺点
redis不具备自动容错和恢复的功能,主机从机的宕机都会导致部分读写请求失败,需要等待机器重启或者手动切换服务IP才能恢复
主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引起数据不一致的问题,降低了系统的可用性
Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得复杂
哨兵模式
原理
当主服务器中断服务后,可以将一个从服务器升级为主服务器,以便继续提供服务,但是这个过程需要人工来操作,为此,Redis2.8中提供了哨兵工具来实现自动化的系统监控和故障恢复功能
哨兵的作用就是监控Redis系统的运行情况,它的功能包括以下两个
监控主服务器和从服务器是否运转正常
主服务器出现故障时自动将从服务器转换为主服务器
工作方式
每个哨兵进程以每秒钟一次的频率向整个集群中的Master主服务器、从服务器、以及其它的哨兵发送一个PING命令
如果一个实例距离最后一次有效回复PING命令的时间超过down-after-millinseconds,则这个实例会被哨兵进程标记为主观下线
如果一个master主服务器被标记为下线,则正在监视这个master主服务器的所有哨兵进程要以每秒一次的频率确认master主服务器是否进入了主观下线状态
当有足够数量的哨兵进程在指定时间范围内确认master进入了主观下线状态,则master主服务器会被标记为客观下线
优点
哨兵模式是基于主从模式的,所有主从的有点,哨兵模式都具有
主从可以自动切换,系统更健壮,可用性更高
缺点
Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂
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文件紧凑,全量备份,非常适合用于进行备份和灾难恢复
生成rbd文件的时候,redis主进程会fork一个子进程来处理所有的保存工作,主进程不需要进行任何磁盘IO操作
rdb在恢复大数据集时比AOF的速度要快
劣势
全量备份比较耗时
服务器宕机可能会导致写操作的数据没有及时保存,造成数据丢失
AOF机制
redis会将每一个收到的写命令通过write函数追加到文件中,每当有一个写命令时,就直接保存到aof文件
文件重写原理
aof方式会导致持久化文件越来越大,为了压缩aof持久化文件,redis提供了bgrewriteaof命令,将内存中的数据以命令的方式保存到临时文件中,同时会fork出一条新进程来将文件重写
重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据用命令的方式重写了一个新的aof文件,这点和快照有点类似
aof三种触发机制
每次修改同步always: 同步持久化,每次发生数据变更会被立即记录到磁盘,性能较差但是数据完整性比较好
每秒同步everysec:异步操作,每秒记录,如果一秒内宕机,有数据丢失
不同步no: 从不同步
优点
aof可以更好的保护数据不丢失,一般aof会每隔一秒,通过一个后台线程执行一次同步操作,最多丢失一秒的数据
aof日志文件没有任何磁盘寻址的开销,写入性能高,文件不容易破损
aof日志文件过大时,会异步执行重写操作,不会影响客户端读写
aof日志文件的命令通过可读的方式进行记录,适合做误删除的紧急恢复,比如不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没发生,可以立即拷贝aof文件,将最后一条flushall命令给删掉,再通过恢复机制恢复所有数据
缺点
对于同一份数据来说,aof日志文件通常比rdb数据快照文件更大
aof开启后,支持的写QPS会比rbd支持的写QPS低
RDB和AOF如何选择
两者同时开启,如果两者都配置了优先加载aof
Redis数据结构及使用场景
String
既可以存储字符串,也可以存储数字
可作为原子计数器,比如:阅读量,查询次数,点赞个数等
hash
存储、读取、修改对象的属性
List
双向列表实现的List
实现消息队列
发布和订阅,可以设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,所
订阅它的客户端都会受到相应的消息,可以用作实时消息系统,比如:即时聊天,群聊等s
Set
非常人性化的集合,提供了求交集,并集,差集等操作,非常方便的实现如共同关注、共同喜好、可能认识的朋友等功能
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线程模型
工作原理
I/O多路复用程序负责监听多个套接字,并向文件事件分派器传送已产生事件的套接字
尽管多个文件事件会并发的出现,但I/O多路复用程序会将所有产生事件的套接字都放入一个队列里面,然后通过这个队列,以有序、同步、每次一个套接字的方式向文件事件分派器传送套接字
当上一个套接字产生的事件被处理完毕之后,I/O多路复用程序才会继续向文件事件分派器传送下一个套接字,如果一个套接字又可读又可写的话,那么服务器就先读套接字,后写
Redis深入理解的更多相关文章
- 每日笔记-redis的理解及相关应用
原文链接:常见面试题 本文大纲与之类似,在其基础上加入了自己在实际项目中对部分知识点的理解 Q1:谈谈对redis的理解 Q2:谈谈实际应用中怎么用redis的 2.1 缓存 2.2 分布式锁 2.3 ...
- Redis管道理解
Redis管道理解 简介 管道并不是Redis本身提供的功能,通常是客户端提供的功能: 管道就是打包多条无关命令批量执行,以减少多个命令分别执行消耗的网络交互时间(TCP网络交互),可以显著提升Red ...
- 【Java面试】面试遇到宽泛的问题,这么回答就稳了,谈谈你对Redis的理解
"谈谈你对Redis的理解"! 面试的时候遇到这类比较宽泛的问题,是不是很抓狂? 是不是不知道从何开始说起? 没关系,今天我用3分钟教你怎么回答. 大家好,我是Mic,一个工作了1 ...
- redis 的理解
1.Redis使用 C语言开发的.Redis 约定此版本号,为偶数的版本是稳定版(如:2.4版 2.6版),奇数版是非稳定版(如:2.5版 2.7版) 2.Redis 数据库中的所有的数据都存储在内存 ...
- 一个萌新对redis的理解
redis是用来保存一些常用的数据到内存,以加快数据读取,减少直接访问DB流量以降低DB压力.既然是放到内存的,那我们怎么样保证用户使用的时候不会出现与数据的差异呢,其实这叫“如何报证缓存数据的一致性 ...
- 【redis持久化】redis持久化理解
1.以下内容仅为个人理解和总结,仅供参考,万万不可全盘真信,内容会进行实时改进和修正 2.redis持久化: 参考链接1.https://redis.io/topics/persistence -- ...
- redis 深入理解redis 主从复制原理
redis 主从复制 master 节点提供数据,也就是写.slave 节点负责读. 不是说master 分支不能读数据,也能只是我们希望将读写进行分离. slave 是不能写数据的,只能处理读请求 ...
- 对Redis的理解
1.redis使用的场景 热点数据(经常会被查询,但是不经常被修改或者删除的数据)
- Redis 个人理解总结
一.什么是Redis ? Redis(remote dictionnary server)是一个key-value存储系统.Redis是一个开源的使用ANSI C语言编写.遵守BSD协议.支持网络.可 ...
随机推荐
- javaMail (java代码发送邮件)
第一在邮件账户设置开启以下两个 需要发送短信获取 授权码. 代码如下: package com.hjb.javaMail; import javax.mail.*; import javax.mai ...
- SecureCRT无法登陆ubuntu问题解决的方法(亲测有效)
最近在虚拟机安装了几个ubuntu系统玩耍,然后想着用SecureCRT在Windows本地连接但是怎么也连接不上!!!如下,这只是示意图,ip地址是瞎编的,但是情况完全相同,期间尝试过让linux和 ...
- 基于μcOS-II实时操作系统源码实现RMS和EDF调度(共享资源)
μcOS-II多任务实验报告(RMS.EDF调度) 目录 μcOS-II多任务实验报告(RMS.EDF调度) 一.实验概述 二.环境搭建 三.代码分析 四.实验步骤 1 给TCB块添加扩展 2 创建并 ...
- 关于KMP算法中,获取next数组算法的理解
参考:KMP入门级别算法详解--终于解决了(next数组详解) https://blog.csdn.net/lee18254290736/article/details/77278769 在这里讨论的 ...
- POJ-2236(并查集)
Wireless NetWork POJ-2236 需要注意这里的树的深度需要初始化为0. 而且,find函数需要使用路径压缩,这里的unint合并函数也使用了优化(用一开始简单的合并过不了). #i ...
- kali msf6 更新及bug处理
问题描述 Metasploit 漏洞库更新,利用msfupdate命令更新,出现已停止该命令更新,出现如下提示: 利用一句话安装更新,命令如下,安装过程中有部分警告出现 curl https://ra ...
- java 给时间增加时间得到一个新的时间(日期)
SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd") LocalDate expirationDate String exp ...
- 如何快速的插入 100W数据到数据库,使用PreparedStatement 最快实现!
有时候,我们使用数据库的时候,如何快速的添加测试数据到数据库中,做测试呢,添加100W 数据,如果使用工具的话可能很慢,这里我推荐大家使用 PreparedStatement 预编译 去进行操作:单线 ...
- H5 简单实现打砖块游戏
实现效果如图所示: 1.布局 在html中,声明 div1 作为作为带有边框的父物体,一切行为都要在 div1 中进行.创建小球ball.左右可滑动的板子bat,以及存放要销毁的砖块的父物体 bri ...
- RabbitMQ镜像队列集群搭建、与SpringBoot整合
镜像模式 集群模式非常经典的就是Mirror镜像模式,保证100%数据不丢失,在实际工作中也是用的最多的,并且实现集群比较的简单. Mirror镜像队列,目的是为了保证 RabbitMQ 数据的高可靠 ...