Redis【第二篇】Redis持久化设置,主从复制,Redis集群与分片式集群

一、为什么需要持久化?

  Redis对数据的操作都是基于内存的,当遇到了进程退出、服务器宕机等意外情况,如果没有持久化机制,那么Redis中的数据将会丢失无法恢复。有了持久化机制,Redis在下次重启时可以利用之前持久化的文件进行数据恢复。理解和掌握Redis的持久机制,对于Redis的日常开发和运维都有很大帮助,也是在大厂面试经常被问到的知识点。Redis支持的两种持久化机制:
    1、RDB:把当前数据生成快照保存在硬盘上。
    2、AOF:记录每次对数据的操作到硬盘上。

二、Redis持久化方案
1、RDB持久化

  (1) 简单介绍
   ① RDB(Redis DataBase)持久化是把当前Redis中全部数据生成快照保存在硬盘上,RDB方式的持久化是通过快照(snapshotting)完成的,当符合一定条件时Redis会自动将内存中的数据进行快照并持久化到硬盘,你可以对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动保存一次数据集。比如说, 以下设置会让 Redis 在满足“ 10 秒内有至少有 100 个键被改动”这一条件时, 自动保存一次数据集:

# save 10 100

   ② RDB是Redis默认采用的持久化方式,Redis 将内存数据库快照保存在名字为 dump.rdb 的二进制文件中。
   ③ RDB持久化可以手动触发,也可以自动触发
   ④ 关闭RDB只需要将所有的save保存策略注释掉即可
  (2) 手动触发
   save和bgsave命令都可以手动触发RDB持久化,,进入redis客户端执行命令save或bgsave可以生成dump.rdb文件,每次命令执行都会将所有redis内存快照到一个新的rdb文件里,并覆盖原有rdb快照文件。
  (3) RDB持久化相关配置
   Ⅰ、 save命令
   ① 执行save命令会手动触发RDB持久化,save是同步命令,会阻塞Redis服务,直到RDB持久化完成。当Redis服务储存大量数据时,会造成较长时间的阻塞,不建议使用。

> save
OK
-------执行后日志重记录-------------
 * DB saved on disk

   Ⅱ、 bgsave命令
   ① 执行bgsave命令也会手动触发RDB持久化,和save命令不同是:bgsave是异步命令,bgsave会从redis主进程fork(fork()是linux函数)出一个子进程专门用来生成rdb快照文件,不会阻塞Redis服务进程。Redis服务的阻塞只发生在fork阶段,一般情况时间很短。

> bgsave
Background saving started
-------执行后日志重记录-------------
 * Background saving started by pid 2645
 * DB saved on disk
 * RDB: 0 MB of memory used by copy-on-write
 * Background saving terminated with success

   ② bgsave命令的具体流程如下图:
在这里插入图片描述

  • a :执行bgsave命令,Redis进程先判断当前是否存在正在执行的RDB或AOF子线程,如果存在就是直接结束。
  • b:Redis进程执行fork操作创建子线程,在fork操作的过程中Redis进程会被阻塞。
  • c:Redis进程fork完成后,bgsave命令就结束了,自此Redis进程不会被阻塞,可以响应其他命令。
  • d:子进程根据Redis进程的内存生成快照文件,并替换原有的RDB文件。
  • e:子进程通过信号量通知Redis进程已完成。
    save与bgsave对比:
命令savebgsave
io类型同步异步
是否阻塞redis其它命令否(在生成子进程执行调用fork函数时会有短暂阻塞)
复杂度O(n)O(n)
优点不会消耗额外内存不阻塞客户端命令
缺点阻塞客户端命令需要fork子进程,消耗内存

  (4) 自动触发
    除了执行以上命令手动触发以外,Redis内部可以自动触发RDB持久化。自动触发的RDB持久化都是采用bgsave的方式,减少Redis进程的阻塞。那么,在什么场景下会自动触发呢?

  • 在配置文件中设置了save的相关配置,如sava m n,它表示在m秒内数据被修改过n次时,自动触发bgsave操作。
       ① save 开头的一行就是持久化配置,可以配置多个条件(每行配置一个条件),每个条件之间是“或”的关系
       “save 900 1”表示15分钟(900秒钟)内至少1个键被更改则进行快照
       “save 300 10”表示5分钟(300秒)内至少10个键被更改则进行快照
save 900 1
save 300 10
save 60 10000

   ② 配置快照文件目录

# Note that you must specify a directory here, not a file name.
dir ./

   ③配置快照文件的名称

# The filename where to dump the DB
dbfilename dump.rdb    					<!--默认名称:dump.rdb-->
  • 当从节点做全量复制时,主节点会自动执行bgsave操作,并且把生成的RDB文件发送给从节点。
  • 执行debug reload命令时,也会自动触发bgsave操作。
  • 执行shutdown命令时,如果没有开启AOF持久化也会自动触发bgsave操作。
      (5) RDB优点
        RDB文件是一个紧凑的二进制压缩文件,是Redis在某个时间点的全部数据快照。所以使用RDB恢复数据的速度远远比AOF的快,非常适合备份、全量复制、灾难恢复等场景。
      (6) RDB缺点
         每次进行bgsave操作都要执行fork操作创建子线程,属于重量级操作,频繁执行成本过高,所以无法做到实时持久化,或者秒级持久化。另外,由于Redis版本的不断迭代,存在不同格式的RDB版本,有可能出现低版本的RDB格式无法兼容高版本RDB文件的问题。
2、 AOF持久化

  RDB快照功能并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化,将修改的每一条指令记录进文件appendonly.aof 中
  (1) 简单介绍
     ① AOF(Append Only File)持久化是把每次写命令追加写入日志中,当需要恢复数据时重新执行AOF文件中的命令就可以了。AOF解决了数据持久化的实时性,也是目前主流的Redis持久化方式。
     ② AOF流程
在这里插入图片描述

  • 命令追加(append):所有写命令都会被追加到AOF缓存区(aof_buf)中。
  • 文件同步(sync):根据不同策略将AOF缓存区同步到AOF文件中。
  • 文件重写(rewrite):定期对AOF文件进行重写,以达到压缩的目的。
  • 数据加载(load):当需要恢复数据时,重新执行AOF文件中的命令。

  (2) 文件同步策略
    AOF持久化流程中的文件同步有以下几个策略:
   ① always:每次写入缓存区都要同步到AOF文件中,硬盘的操作比较慢,限制了Redis高并发,不建议配置,但是非常安全。
   ② no:每次写入缓存区后不进行同步,同步到AOF文件的操作由操作系统负责,每次同步AOF文件的周期不可控,而且增大了每次同步的硬盘的数据量。
   ③ eversec:每次写入缓存区后,由专门的线程每秒钟同步一次,做到了兼顾性能和数据安全。是建议的同步策略,也是默认的策略。
  (3) 触发文件重写
    AOF持久化流程中的文件重写可以手动触发,也可以自动触发。
   ① 手动触发:使用bgrewriteaof命令。
   ② 自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage配置确定自动触发的时机。auto-aof-rewrite-min-size表示运行AOF重写时文件大小的最小值,默认为64MB;auto-aof-rewrite-percentage表示当前AOF文件大小和上一次重写后AOF文件大小的比值的最小值,默认为100。只用前两者同时超过时才会自动触发文件重写。
注意:AOF重写redis会fork出一个子进程去做,不会对redis正常命令处理有太多影响
  (4) AOF持久化配置
    对AOF持久化的具体流程有了了解后,我们来看一下如何配置AOF。AOF持久化默认是不开启的,需要修改配置文件,如:

# appendonly改为yes,开启AOF
appendonly yes
# AOF文件的名字
appendfilename "appendonly.aof"
# AOF文件的写入方式
# everysec 每个一秒将缓存区内容写入文件 默认开启的写入方式
appendfsync everysec
# 运行AOF重写时AOF文件大小的增长率的最小值
auto-aof-rewrite-percentage 100
# 运行AOF重写时文件大小的最小值
auto-aof-rewrite-min-size 64mb

3、 RDB 和 AOF ,用哪一个?
命令RDBAOF
启动优先级
体积
恢复速度
数据安全性容易丢数据根据策略决定

注意:redis启动时如果既有rdb文件又有aof文件则优先选择aof文件恢复数据,因为aof一般来说数据更全一点。

4、 Redis 4.0 混合持久化

重启 Redis 时,我们很少使用 RDB来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 RDB来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。
通过如下配置可以开启混合持久化:

# aof-use-rdb-preamble yes

如果开启了混合持久化,AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,原子的覆盖原有的AOF文件,完成新旧两个AOF文件的替换。

于是在 Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,因此重启效率大幅得到提升。
混合持久化AOF文件结构:
在这里插入图片描述

三、主从复制
1、 Redis 主从复制

在这里插入图片描述
主从复制就是现在有俩台redis服务器,把一台redis的数据同步到另一台redis数据库上。前者称之为主节点(master),后者为从节点(slave)。数据是只能master往slave同步单向。

但是在实际过程中是不可能只有俩台redis服务器来做主从复制的,这也就意味这每台redis服务器都有可能会称为主节点(master)

2、 Redis主从工作原理

如果你为master配置了一个slave,不管这个slave是否是第一次连接上Master,它都会发送一个SYNC命令(redis2.8版本之前的命令)给master请求复制数据。

master收到SYNC命令后,会在后台进行数据持久化通过bgsave生成最新的rdb快照文件,持久化期间,master会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存中。当持久化进行完毕以后,master会把这份rdb文件数据集发送给slave,slave会把接收到的数据进行持久化生成rdb,然后再加载到内存中。然后,master再将之前缓存在内存中的命令发送给slave。

当master与slave之间的连接由于某些原因而断开时,slave能够自动重连Master,如果master收到了多个slave并发连接请求,它只会进行一次持久化,而不是一个连接一次,然后再把这一份持久化的数据发送给多个并发连接的slave。

当master和slave断开重连后,一般都会对整份数据进行复制。但从redis2.8版本开始,master和slave断开重连后支持部分复制。

数据部分复制

从2.8版本开始,slave与master能够在网络连接断开重连后只进行部分数据复制。

master会在其内存中创建一个复制数据用的缓存队列,缓存最近一段时间的数据,master和它所有的slave都维护了复制的数据下标offset和master的进程id,因此,当网络连接断开后,slave会请求master继续进行未完成的复制,从所记录的数据下标开始。如果master进程id变化了,或者从节点数据下标offset太旧,已经不在master的缓存队列里了,那么将会进行一次全量数据的复制~

3、 Redis主从复制流程图(全量,部分)

主从复制(全量复制)流程图:
在这里插入图片描述
主从复制(部分复制)流程图:
在这里插入图片描述
redis主从架构搭建,配置从节点步骤:

1、复制一份redis.conf文件
2、将相关配置修改为如下值:

port 6380
pidfile /var/run/redis_6380.pid
logfile "6380.log"
dir /usr/local/redis-5.0.3/data/6380

3、配置主从复制

replicaof 192.168.0.60 6379   # 从本机6379的redis实例复制数据
replica-read-only yes

4、启动从节点

redis-server redis.conf

5、连接从节点

redis-cli -p 6380

6、测试在6379实例上写数据,6380实例是否能及时同步新修改数据

四、Redis缓存高可用集群
1、Redis哨兵模式

在这里插入图片描述
sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。

哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)

redis哨兵架构搭建步骤:

1、复制一份sentinel.conf文件

cp sentinel.conf sentinel-26379.conf

2、将相关配置修改为如下值:

port 26379
daemonize yes
pidfile "/var/run/redis-sentinel-26379.pid"
logfile "26379.log"
dir "/usr/local/redis-5.0.3/data"
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
# quorum是一个数字,指明当有多少个sentinel认为一个master失效时(值一般为:sentinel总数/2 + 1),master才算真正失效
sentinel monitor mymaster 192.168.0.60 6379 2

3、启动sentinel哨兵实例

src/redis-sentinel sentinel-26379.conf

4、查看sentinel的info信息

src/redis-cli -p 26379
127.0.0.1:26379>info

可以看到Sentinel的info里已经识别出了redis的主从

2、Redis高可用集群模式

  在redis3.0以前的版本要实现集群一般是借助哨兵sentinel工具来监控master节点的状态,如果master节点异常,则会做主从切换,将某一台slave作为master,哨兵的配置略微复杂,并且性能和高可用性等各方面表现一般,特别是在主从切换的瞬间存在访问瞬断的情况,而且哨兵模式只有一个主节点对外提供服务,没法支持很高的并发,且单个主节点内存也不宜设置得过大,否则会导致持久化文件过大,影响数据恢复或主从同步的效率。
  redis集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。Redis集群不需要sentinel哨兵也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中心节点,可水平扩展,据官方文档称可以线性扩展到上万个节点(官方推荐不超过1000个节点)。redis集群的性能和高可用性均优于之前版本的哨兵模式,且集群配置非常简单。
注意:redis集群需要至少要三个master节点。

在这里插入图片描述

3、Redis高可用集群原理分析

  Redis Cluster 将所有数据划分为 16384 个 slots(槽位),每个节点负责其中一部分槽位。槽位的信息存储于每个节点中。

  当 Redis Cluster 的客户端来连接集群时,它也会得到一份集群的槽位配置信息并将其缓存在客户端本地。这样当客户端要查找某个 key 时,可以直接定位到目标节点。同时因为槽位的信息可能会存在客户端与服务器不一致的情况,还需要纠正机制来实现槽位信息的校验调整。
槽位定位算法:

  Cluster 默认会对 key 值使用 crc16 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模来得到具体槽位。

HASH_SLOT = CRC16(key) mod 16384

跳转重定位:

  当客户端向一个错误的节点发出了指令,该节点会发现指令的 key 所在的槽位并不归自己管理,这时它会向客户端发送一个特殊的跳转指令携带目标操作的节点地址,告诉客户端去连这个节点去获取数据。客户端收到指令后除了跳转到正确的节点上去操作,还会同步更新纠正本地的槽位映射表缓存,后续所有 key 将使用新的槽位映射表。

五、总结

希望可以帮助需要的朋友。有不懂的地方可以在此博客下面评论,看到后会及时回复~

Redis 【第三篇】Redis缓存穿透、击穿、雪崩与相对应的解决方案,以及跳跃表实现原理

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值