文章目录
- 一、什么是Redis
- 二、Redis支持哪几种数据类型?
- 三、为什么redis需要把所有数据放到内存中?
- 四、Redis有哪几种数据淘汰策略?
- 五、Redis最适合的场景有哪些?
- 六、Redis常见的性能问题都有哪些?如何解决?
- 七、Redis集群会有写操作丢失吗?为什么?
- 八、Redis集群最大节点个数是多少?
- 九、Memcache与Redis的区别都有哪些?
- 十、Redis的优缺点
- 十一、Redis的持久化
- 十二、Redis官方为什么不提供Windows版本?
- 十三、Redis支持的Java客户端都有哪些?官方推荐用哪个?
- 十四、缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题?
- 十五、说说Redis哈希槽的概念?
- 十六、Redis 集群的主从复制模型是怎样的?
- 十七、Redis中的管道有什么用?
- 十八、Redis集群如何选择数据库?
- 十九、Redis 的内存用完了会发生什么?
- 二十、使用过 Redis 分布式锁么,它是什么回事?
- 二十一、数据的有效时间的三种状态
- 二十二、数据删除策略
- 二十三、Redis 回收进程如何工作的?
- 二十四、Redis 如何做内存优化?
- 二十五、redis集群主从复制
- 二十六、主从复制的作用
- 二十七、主从复制的工作流程(三个阶段)
- 二十八、总结主从复制的三个阶段的工作流程
- 二十九、是否使用过 Redis 集群,集群的原理是什么?
- 三十、Redis 集群如何选择数据库?
- 三十一、怎么测试 Redis 的连通性?
- 三十二、怎么理解 Redis 事务?
一、什么是Redis
redis即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、高性能“Key-Value”数据库、遵守BSD协议,并提供多种语言的API;整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘 上进行保存。
因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的 Key-Value DB。 Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存多种数据结构,此外单个value的最大限制是1GB,不像 emcached只能保存1MB的数据,因此Redis可以用来实现很多有用的功能。 比方说用他的List来做FIFO双向链表,实现一个轻量级的高性 能消息队列服务,用他的Set可以做高 性能的tag系统等等。
特点:
- 数据间没有必然的关联关系;
- 内部采用单线程机制进行工作;
- 官方提供测试数据,50个并发执行100000 个请求,读的速度是110000 次/s,写的速度是81000次;
- 多数据类型支持
二、Redis支持哪几种数据类型?
Redis数据类型(5种常用):
string、hash、list、set、sorted_set/zset(应用性较低)
string数据类型:
存储数据的格式:一个存储空间保存一个数据;
存储内容:通常使用字符串,如果字符串以整数的形式展示,可以作为数字操作使用。
数据最大存储量:512MB
redis 数值上限:9223372036854775807(java中Long型数据最大值,Long.MAX_VALUE)
redis所有的操作都是原子性的,采用单线程,命令是一个一个执行的,无需考虑并发带来的数据影响。
hash 类型:
需要的存储结构:
一个存储空间保存多个键值对数据 (一个key对应一个hash存储空间)
hash类型:底层使用哈希表结构实现数据存储;
存储是:key + hash存储空间(field + value):
如果fifield数量较少,存储结构优化为类数组结构
如果fifield数量较多,存储结构使用HashMap结构
hash类型中value:只能存储字符串,不允许存储其他数据类型,不存在嵌套现象;
hash存储空间大小:每个 hash 可以存储 2^32 - 1 个键值对 hash类型十分贴近对象的数据存储形式;
list类型:
数据存储需求:存储多个数据,并对数据进入存储空间的顺序进行区分;
需要的存储结构:一个存储空间保存多个数据,且通过数据可以体现进入顺序;
list类型:保存多个数据,底层使用双向链表存储结构实现 ;
list中保存的数据:都是string类型的,数据总容量是有限的,最多2^32 - 1 个元素(4294967295);
list使用:通常以队列的形式进行入队出队操作,或以栈的形式进行入栈出栈操作;
set类型:
新的存储需求:存储大量的数据,在查询方面提供更高的效率;
需要的存储结构:能够保存大量的数据,高效的内部存储机制,便于查询;
set类型:与hash存储结构完全相同,仅存储键(hash中的field),不存储值(全部值为nil),并且值是不允许重复的(set存储空间)。
Sorted Set类型:
和Sets相比,Sorted Sets是将 Set 中的元素增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列:
- 带有权重的元素,比如一个游戏的用户得分排行榜
- 比较复杂的数据结构,一般用到的场景不算太多
三、为什么redis需要把所有数据放到内存中?
Redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以redis具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘 I/O 速度为严重影响 redis 的性能。在内存越来越便宜的今天,redis将会越来越受欢迎。如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。
四、Redis有哪几种数据淘汰策略?
- noeviction:返回错误当内存限制达到,并且客户端尝试执行会让更多内存被使用的命令。
- allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。
- volatile-lru: 尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存 放。
- allkeys-random: 回收随机的键使得新添加的数据有空间存放。
- volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
- volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。
五、Redis最适合的场景有哪些?
- 会话缓存(Session Cache)
- 全页缓存(FPC)
- 队列
- 排行榜/计数器
- 发布/订阅
六、Redis常见的性能问题都有哪些?如何解决?
- Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。
- Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。
- Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。
- Redis 主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave 和 Master 最好在同一个局域网内。
七、Redis集群会有写操作丢失吗?为什么?
Redis并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作。
八、Redis集群最大节点个数是多少?
16384个
九、Memcache与Redis的区别都有哪些?
- 存储方式不同,Memcache是把数据全部存在内存中,数据不能超过内存的大小,断电后数据库会挂掉。Redis有部分存在硬盘上,这样能保证数据的持久性。
- 数据支持的类型不同 memcahe对数据类型支持相对简单,redis有复杂的数据类型。
- 使用底层模型不同 它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。Redis直接自己构建了VM机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
- 支持的value大小不一样 redis最大可以达到1GB,而memcache只有1MB。
十、Redis的优缺点
优点:
- 性能极高 – Redis 能支持超过 100K+ 每秒的读写频率。
- 丰富的数据类型 – Redis 支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets数据类型操作。
- 原子 – Redis 的所有操作都是原子性的,同时 Redis 还支持对几个操作全并后的原子性执行。attention 原子性定义:例如,A想要从自己的帐户中转1000块钱到B的帐户里。那个从A开始转帐,到转帐结束的这一个过程,称之为一个事务。如果在 A 的帐户已经减去了 1000 块钱的时候,忽然发生了意外,比如停电什么的,导致转帐事务意外终止了,而此时 B 的帐户里还没有增加 1000 块钱。那么,我们称这个操作失败了,要进行回滚。回滚就是回到事务开始之前的状态,也就是回到 A 的帐户还没减 1000 块的状态,B 的帐户的原来的状态。此时A的帐户仍然有3000 块,B的帐户仍然有2000块。我们把这种要么一起成功(A帐户成功减少1000,同时B帐户成功增加1000),要么一起失败(A帐户回到原来状态,B帐户也回到原来状态)的操作叫原子性操作。如果把一个事务可看作是一个程序,它要么完整的被执行,要么完全不执行,这种特性就叫原子性。
- 丰富的特性 – Redis 还支持 publish/subscribe, 通知, key 过期等等特性。
缺点:
- 由于是内存数据库,所以,单台机器,存储的数据量,跟机器本身的内存大小。虽然redis 本身有key过期策略,但是还是需要提前预估和节约内存。如果内存增长过快,需要定期删除数据。
- 如果进行完整重同步,由于需要生成 rdb 文件,并进行传输,会占用主机的 CPU,并会消耗现网的带宽。不过redis2.8版本,已经有部分重同步的功能,但是还是有可能有完整重同步的。比如,新上线的备机。
- 修改配置文件,进行重启,将硬盘中的数据加载进内存,时间比较久。在这个过程中,redis不能提供服务。
十一、Redis的持久化
RDB 持久化:该机制可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。
AOF 持久化:记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。AOF文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小 。
无持久化:让数据只在服务器运行时存在。
同时应用 AOF 和 RDB:当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。
RDB的优缺点:
优点:
RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集。 这种文件非常适合用于进行备份: 比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。 这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。RDB 非常适用于灾难恢复(disaster recovery):它只有一个文件,并且内容都非常紧凑,可以(在加密后)将它传送到别的数据中心,或者亚马逊 S3 中。RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
缺点:
如果你需要尽量避免在服务器故障时丢失数据,那么 RDB 不适合你。 虽然 Redis 允许你设置不同的保存点(save point)来控制保存 RDB 文件的频率, 但是, 因为RDB 文件需要保存整个数据集的状态, 所以它并不是一个轻松的操作。 因此你可能会至少 5 分钟才保存一次 RDB 文件。 在这种情况下, 一旦发生故障停机, 你就可能会丢失好几分钟的数据。每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 在数据集比较庞大时, fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端; 如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。
AOF的优缺点:
优点:
-
使用 AOF 持久化会让 Redis 变得非常耐久(much more durable):你可以设置不同的 fsync 策略,比如无 fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync 。 AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)。AOF 文件是一个只进行追加操作的日志文件(append only log), 因此对 AOF 文件的写入不需要进行 seek , 即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也可以轻易地修复这种问题。
-
Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
缺点:
对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。
AOF 在曾经出现过这样的 bug :
因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。 (举个例子,阻塞命令 BRPOPLPUSH 就曾经引起过这样的 bug 。) 测试套件里为这种情况添加了测试: 它们会自动生成随机的、复杂的数据集, 并通过重新载入这些数据来确保一切正常。 虽然这种 bug 在 AOF 文件中并不常见, 但是对比来说, RDB 几乎是不可能出现这种 bug 的。
十二、Redis官方为什么不提供Windows版本?
因为目前Linux版本已经相当稳定,而且用户量很大,无需开发windows版本,反而会带来兼容性等问题。
十三、Redis支持的Java客户端都有哪些?官方推荐用哪个?
Redisson、Jedis、lettuce等等,官方推荐使用Redisson。
十四、缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题?
一、缓存雪崩
我们可以简单的理解为:由于原有缓存失效,新缓存未到期间(例如:我们设置缓存时采用了相同的过期 时间,在同一时刻出现大面积的缓存过期),所有原本应该访问缓存的请求都去查询数据库了,而对数据 库CPU和内存造成巨大压力,严重的会造成数据库宕机。从而形成一系列连锁反应,造成整个系统崩溃。
解决办法:
大多数系统设计者考虑用加锁( 最多的解决方案)或者队列的方式保证来保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上。还有一个简单方案就时讲缓 存失效时间分散开。
二、缓存穿透
缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在 缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请 求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题。
解决办法:
最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存 在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗 暴的方法,如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结 果进行缓存,但它的过期时间会很短,最长不超过五分钟。通过这个直接设置的默认值存放到缓存,这 样第二次到缓冲中获取就有值了,而不会继续访问数据库,这种办法最简单粗暴。
三、缓存预热
缓存预热这个应该是一个比较常见的概念,相信很多小伙伴都应该可以很容易的理解,缓存预热就是系 统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据 库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
解决思路:
1、直接写个缓存刷新页面,上线时手工操作下;
2、数据量不大,可以在项目启动的时候自动进行加载;
3、定时刷新缓存
四、缓存更新
除了缓存服务器自带的缓存失效策略之外(Redis默认的有6中策略可供选择),我们还可以根据具体的 业务需求进行自定义的缓存淘汰,常见的策略有两种:
(1)定时去清理过期的缓存;
(2)当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数 据并更新缓存。
两者各有优劣,第一种的缺点是维护大量缓存的key是比较麻烦的,第二种的缺点就是每次用户请求过 来都要判断缓存失效,逻辑相对比较复杂!具体用哪种方案,大家可以根据自己的应用场景来权衡
五、缓存降级
当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然 需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开 关实现人工降级。
降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结 算)。
以参考日志级别设置预案:
(1)一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级;
(2)警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级, 并发送告警;
(3)错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的 最大阀值,此时可以根据情况自动降级或者人工降级;
(4)严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。服务降级的目的,是为了防 止Redis服务故障,导致数据库跟着一起发生雪崩问题。因此,对于不重要的缓存数据,可以采取服务 降级策略,例如一个比较常见的做法就是,Redis出现问题,不去数据库查询,而是直接返回默认值给用户。
十五、说说Redis哈希槽的概念?
Redis集群没有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384个哈希槽,每个key通 过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。
十六、Redis 集群的主从复制模型是怎样的?
为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有 N-1 个复制品。
十七、Redis中的管道有什么用?
一次请求/响应服务器能实现处理新的请求即使旧的请求还未被响应,这样就可以将多个命令发送到服务 器,而不用等待回复,最后在一个步骤中读取该答复。 这就是管道(pipelining),是一种几十年来广泛使用的技术。例如许多POP3协议已经实现支持这个功 能,大大加快了从服务器下载新邮件的过程。
十八、Redis集群如何选择数据库?
Redis集群目前无法做数据库选择,默认在0数据库。
十九、Redis 的内存用完了会发生什么?
如果达到设置的上限,Redis 的写命令会返回错误信息(但是读命令还可以正常返回。)或者你可以将Redis 当缓存来使用配置淘汰机制,当 Redis 达到内存上限时会冲刷掉旧的内容。
二十、使用过 Redis 分布式锁么,它是什么回事?
先拿 setnx 来争抢锁,抢到之后,再用 expire 给锁加一个过期时间防止锁忘记了释放。
这时候对方会告诉你说你回答得不错,然后接着问如果在 setnx 之后执行 expire之前进程意外 crash 或者要重启维护了,那会怎么样?
这时候你要给予惊讶的反馈:唉,是喔,这个锁就永远得不到释放了。紧接着你需要抓一抓自己得脑袋,故作思考片刻,好像接下来的结果是你主动思考出来的,然后回答:我记得 set 指令有非常复杂的参数,这个应该是可以同时把 setnx 和expire 合成一条指令来用的!对方这时会显露笑容,心里开始默念:摁,这小子还不错。
二十一、数据的有效时间的三种状态
- 正数:代表该数据在内存中还能存活的时间
- -1:永久有效的数据
- -2 :已经过期的数据 或被删除的数据 或 未定义的数据
二十二、数据删除策略
- 定时删除 :创建一个定时器,当key设置有过期时间,且过期时间到达时,由定时器任务立即执行对键的删除操作。
- 优点:节约内存,到时就删除,快速释放掉不必要的内存占用
- 缺点:CPU压力很大,无论CPU此时负载量多高,均占用CPU,会影响 redis服务器响应时间和指令吞吐量
- 总结:用处理器性能换取存储空间(拿时间换空间) - 惰性删除 :数据到达过期时间,不做处理。等下次访问该数据时,我们需要判断:1. 如果未过期,返回数据;2. 发现已过期,删除,返回不存在 。
- 优点:节约CPU性能,发现必须删除的时候才删除
- 缺点:内存压力很大,出现长期占用内存的数据
- 总结:用存储空间换取处理器性能(拿时间换空间) - 定期删除:定期删除就是周期性轮询redis库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度 。
- 特点1:CPU性能占用设置有峰值,检测频度可自定义设置
- 特点2:内存压力不是很大,长期占用内存的冷数据会被持续清理
- 总结:周期性抽查存储空间(随机抽查,重点抽查)
删除策略对比:
二十三、Redis 回收进程如何工作的?
一个客户端运行了新的命令,添加了新的数据。Redi 检查内存使用情况,如果大于 maxmemory 的限制, 则根据设定好的策略进行回收。一个新的命令被执行,等等。所以我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收回到边界以下。如果一个命令的结果导致大量内存被使用(例如很大的集合的交集保存到一个新的键),不用多久内存限制就会被这个内存使用量超越。
二十四、Redis 如何做内存优化?
尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的 web 系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的 key,而是应该把这个用户的所有信息存储到一张散列表里面。
二十五、redis集群主从复制
采用主从复制。主服务器mater,从服务器slave。
主从复制即将master中的数据即时、有效的复制到slave中。
特征: 一个master可以拥有多个slave,一个slave只对应一个master。
职责: master写数据,slave读数据。
故障恢复:当master出现问题时,由slave提供服务,实现快速的故障恢复。
高可用基石:基于主从复制,构建哨兵模式与集群,实现Redis的高可用方案。
集群搭建: master保存每个slave的地址与端口,每个slave保存master的地址与端口。之间创建了连接的socket。
二十六、主从复制的作用
- 读写分离:master写、slave读,提高服务器的读写负载能力;
- 负载均衡:基于主从结构,配合读写分离,由slave分担master负载,并根据需求的变化,改变slave的数 量,通过多个从节点分担数据读取负载,大大提高Redis服务器并发量与数据吞吐量;
- 故障恢复:当master出现问题时,由slave提供服务,实现快速的故障恢复;
- 数据冗余:实现数据热备份,是持久化之外的一种数据冗余方式;
- 高可用基石:基于主从复制,构建哨兵模式与集群,实现Redis的高可用方案;
二十七、主从复制的工作流程(三个阶段)
阶段一:建立连接
建立slave到master的连接,使master能够识别slave,并保存slave端口号。
流程如下:
-
步骤1:设置master的地址和端口,保存master信息
-
步骤2:建立socket连接
-
步骤3:发送ping命令(定时器任务)
-
步骤4:身份验证
-
步骤5:发送slave端口信息
至此,主从连接成功!
当前状态:
slave: 保存master的地址与端口
master: 保存slave的端口
总体: 之间创建了连接的socket
阶段二:数据同步
在slave初次连接master后,复制master中的所有数据到slave将slave的数据库状态更新成master当前的数据库状态。
同步过程如下:
- 步骤1:请求同步数据
- 步骤2:创建RDB同步数据
- 步骤3:恢复RDB同步数据
- 步骤4:请求部分同步数据
- 步骤5:恢复部分同步数据
至此,数据同步工作完成!
当前状态:
slave: 具有master端全部数据,包含RDB过程接收的数据
master: 保存slave当前数据同步的位置
总体: 之间完成了数据克隆
阶段三:命令传播
当master数据库状态被修改后,导致主从服务器数据库状态不一致,此时需要让主从数据同步到一致的状态,同步的动作称为命令传播。
master将接收到的数据变更命令发送给slave,slave接收命令后执行命令
命令传播阶段的部分复制。
命令传播阶段出现了断网现象:
网络闪断闪连:忽略
短时间网络中断:部分复制
长时间网络中断:全量复制
这里我们主要来看部分复制,部分复制的三个核心要素
- 服务器的运行 id(run id)
- 主服务器的复制积压缓冲区
- 主从服务器的复制偏移量
服务器运行ID(runid)
概念:服务器运行ID是每一台服务器每次运行的身份识别码,一台服务器多次运行可以生成多个运行id
组成:运行id由40位字符组成,是一个随机的十六进制字符
例如:fdc9ff13b9bbaab28db42b3d50f852bb5e3fcdce
作用:运行id被用于在服务器间进行传输,识别身份
如果想两次操作均对同一台服务器进行,必须每次操作携带对应的运行id,用于对方识别
实现方式:运行id在每台服务器启动时自动生成的,master在首次连接slave时,会将自己的运行ID发送给slave,
slave保存此ID,通过info Server命令,可以查看节点的runid
复制缓冲区
概念:复制缓冲区,又名复制积压缓冲区,是一个先进先出(FIFO)的队列,用于存储服务器执行过的命令,每次传播命令, master都会将传播的命令记录下来,并存储在复制缓冲区
复制缓冲区默认数据存储空间大小是1M
当入队元素的数量大于队列长度时,最先入队的元素会被弹出,而新元素会被放入队列
作用:用于保存master收到的所有指令(仅影响数据变更的指令,例如set,select)
数据来源:当master接收到主客户端的指令时,除了将指令执行,会将该指令存储到缓冲区中
偏移量
概念: 一个数字,描述复制缓冲区中的指令字节位置
分类:
master复制偏移量:记录发送给所有slave的指令字节对应的位置(多个)
slave复制偏移量:记录slave接收master发送过来的指令字节对应的位置(一个)
作用: 同步信息,比对master与slave的差异,当slave断线后,恢复数据使用
数据来源:
master端: 发送一次记录一次
slave端: 接收一次记录一次
二十八、总结主从复制的三个阶段的工作流程
①需要两个参数,是运行id、偏移量,但是是第一次连接master不知道运行id和偏移量,则赋值为?和-1。③发送的是全量复制、运行id和当前的偏移量。全量赋值补充:在发送偏移量的同时master会接收到客户端的命令,这时master的偏移量值就变化了,但是slave的偏移量不变,他们个人保存个人的。⑦把命令表示的是部分复制。在master和slave连接期间,salve不停的向master发送⑤命令。
二十九、是否使用过 Redis 集群,集群的原理是什么?
- Redis Sentinal 着眼于高可用,在 master 宕机时会自动将 slave 提升为master,继续提供服务。
- Redis Cluster 着眼于扩展性,在单个 redis 内存不足时,使用 Cluster 进行分片存储.
三十、Redis 集群如何选择数据库?
Redis 集群目前无法做数据库选择,默认在 0 数据库。
三十一、怎么测试 Redis 的连通性?
使用 ping 命令
三十二、怎么理解 Redis 事务?
- 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
- 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。