redis高级:持久化方案、主从复制原理和方案、哨兵高可用

一、持久化方案

1、什么是持久化

redis的所有数据保存在内存中,把内存中的数据同步到硬盘上这个过程称之为持久化

ps:redis是默认使用自动持久化的,在使用redis的时候我们如果不是强行关掉redis服务,再启动,就可以看到之前设置的数据。因为正常退出或执行shutdown关闭redis连接的时候会自动持久化生成rdb文件

2、持久化的实现方式

实现持久化有两方式:

  • 快照:记录某时某刻的数据,把他当作一个备份

举例:

1、mysql的Dump

2、redis的RDB

  • 写日志:我们执行任何操作的时候,都会在日志上记录下来,需要恢复数据的时候,只要把日志记录的命令重新执行一遍即可

举例:

1、mysql的 Binlog

2、Redis的 AOF

Redis支持两种持久化方式:RDB和AOF。

3、RDB

img

RDB是Redis默认的持久化方式,它会周期性地将Redis中的数据快照保存到磁盘上,生成一个RDB文件。RDB文件是一个二进制文件,包含了Redis在某个时间点上的数据状态。RDB持久化的优点是占用空间小,恢复速度快,适合用于备份和灾难恢复。缺点是可能会出现数据的丢失,因为RDB是定时快照,如果Redis进程在快照之前崩溃,会导致数据的丢失。

前面我们提到redis默认就是自动使用持久化的,如果我们在退出之后,进入redis文件夹内部的data文件夹内,可以看到一个rdb文件,他就是缓存文件,删除之后,我们再启动redis,就没有之前的数据了

但是我们强行关掉服务,redis并没有生成持久化的rdb文件,这会导致最近一段时间的数据丢失

ps:rdb文件在每次执行持久化操作的时候都会替换掉之前的文件

rdb 持久化配置方式

方式一:

save

主动生成rdb持久化文件,是一个同步操作,如果数据量很大会出现阻塞的情况

方式二:

bgsave

主动生成rdb持久化文件,是一个异步持久化操作,不会阻塞住其他命令的执行

方式三:

在配置文件配置(根据配置文件自动执行持久化)

这个条件触发,就执行bgsave

    save   900        1
    save   300        10
    save   60         10000
    dbfilename dump.rdb
    dir "/root/redis-6.2.9/data"
    如果60s中改变了1w条数据,自动生成rdb
    如果300s中改变了10条数据,自动生成rdb
    如果900s中改变了1条数据,自动生成rdb
    dbfilename是配置rdb文件的名称
    配置文件存储路径
    
	以上三条符合任意一条,就自动生成rdb,内部使用bgsave
    
    其他不常用配置:
    stop-writes-on-bgsave-error yes #出现错误停止
	rdbcompression yes #压缩
	rdbchecksum yes #校验

其他知识点

1、rdb持久化是全量复制

没有执行save和bgsave没有添加rdb策略,还会生成rdb文件,如果开启主从复制,主会自动生成rdb

2、debug reload

debug级别的重启,不会将内存中的数据清空

3、shutdown save

关闭会出发rdb的生成

把save替换成nosave就是不持久化

4、redis的src文件夹中有一个 redis-check-rdb 可执行文件,他可以校验rdb文件是否正确

4、aof方案

在学习rdb的时候我们可以发现,他会出现数据丢失的问题,因此可以用aof方案处理

ps:如果redis只是用来做缓存,那丢了也没什么关系

RDB问题

耗时,耗性能:

不可控,可能会丢失数据

AOF介绍

客户端每写入一条命令,都记录一条日志,放到日志文件中,如果出现宕机,可以将数据完全恢复

AOF的三种策略

日志不是直接写到硬盘上,而是先放在缓冲区,缓冲区根据一些策略,写到硬盘上

  • always:redis–》写命令刷新的缓冲区—》每条命令fsync到硬盘—》AOF文件
  • everysec(默认值):redis——》写命令刷新的缓冲区—》每秒把缓冲区fsync到硬盘–》AOF文件
  • no:redis——》写命令刷新的缓冲区—》操作系统决定,缓冲区fsync到硬盘–》AOF文件
命令 always everysec no
优点 不丢失数据 每秒一次fsync,丢失1秒数据 不用管
缺点 IO开销大,一般的sata盘只有几百TPS 丢1秒数据 不可控

AOF重写

随着命令的逐步写入,并发量的变大, AOF文件会越来越大,通过AOF重写来解决该问题

举例:

原生AOF 重写后的AOF
set hello world set hello java set hello hehe incr counter incr counter rpush mylist a rpush mylist b rpush mylist c 过期数据 set hello hehe set counter 2 rpush mylist a b c

本质就是把过期的,无用的,重复的,可以优化的命令,来优化

这样可以减少磁盘占用量,加速恢复速度

AOF重写配置参数

配置名 含义
auto-aof-rewrite-min-size AOF文件重写需要尺寸
auto-aof-rewrite-percentage AOF文件增长率

自动触发时机(两个条件同时满足):

aof_current_size>auto-aof-rewrite-min-size:当前尺寸大于重写需要尺寸

(aof_current_size-aof_base_size)/aof_base_size>auto-aof-rewrite-percentage:(增长率)当前尺寸减去上次重写的尺寸,除以上次重写的尺寸如果大于配置中的增长率

统计名 含义
aof_current_size AOF当前尺寸(单位:字节)
aof_base_size AOF上次启动和重写的尺寸(单位:字节)

AOF重写配置

# aof持久化的配置 appendonly yes #将该选项设置为yes,打开 appendfilename "appendonly.aof" #文件保存的名字 appendfsync everysec #采用第二种策略 no-appendfsync-on-rewrite yes #在aof重写的时候,是否要做aof的append操作,因为aof重写消耗性能,磁盘消耗,正常aof写磁盘有一定的冲突,这段期间的数据,允许丢失

ps:aof重写可以使用配置文件触发,也可以手动触发:

python

bgrewriteaof

5、RDB和AOF的选择

rdb和aof的比较

命令 rdb aof
启动优先级 高(挂掉重启,会加载aof的数据)
体积
恢复速度
数据安全性 丢数据 根据策略决定
轻重

rdb最佳策略

rdb关掉,主从操作时

集中管理:按天,按小时备份数据

主从配置,从节点打开

aof最佳策略

开:缓存和存储,大部分情况都打开,

aof重写集中管理

everysec:通过每秒刷新的策略

最佳策略

小分片:每个redis的最大内存为4g

缓存或存储:根据特性,使用不通策略

时时监控硬盘,内存,负载网络等

ps:要有有足够内存

6、混合持久化

重启Redis时,我们很少使用RDB来恢复内存状态,因为会丢失大量数据。我们通常使用AOF日志重放。

但是重放AOF日志性能相对RDB来说要慢很多,这样在Redis实例很大的情况下,启动需要花费很长的时间。

Redis4.0 为了解决这个问题,带来了一个新的持久化选项 --- 混合持久化。

ps:混合持久化不是简单的同时开启aof和rdb,他们是相互不影响的

如果开启了混合持久化,AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将重写这一刻之前的内存做RDB快照处理

并且将RDB快照内容和增量的AOF修改内存数据的命令存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件

才会进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。

于是在Redis重启的时候,可以先加载RDB的内容,然后再重放增量AOF日志就可以完全替代之前的AOF全量文件重放,因此重启效率大幅得到提升

img

配置参数

必须先开启AOF

# 开启 aof
appendonly yes
# 开启 aof复写(这两个是主要配置)
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 开启 混合持久化
aof-use-rdb-preamble yes  # 这正有用的是这句话
# 关闭 rdb
save ""

ps:aof重写可以使用配置文件触发,也可以手动触发:

bgrewriteaof

二、主从复制原理和方案

1、为什么要用主从复制

我们使用redis的时候可能会出现一下问题:

  • 机器故障
  • 容量瓶颈(内存不够了)
  • QPS瓶颈(QPS是指每秒钟能够处理的查询数)

主从解决了qps问题,机器故障问题

2、主从复制介绍

Redis主从复制是一种用于实现Redis高可用性的技术,通过将一个Redis实例(称为主节点)的数据复制到多个Redis实例(称为从节点)中,以提高系统的可用性和容错性。

在Redis主从复制中,主节点负责处理所有的写请求和读请求,从节点通过复制主节点的数据来实现读请求的负载均衡和故障转移。当主节点出现故障时,从节点中的某个节点可以被选举为新的主节点,以继续处理客户端请求。

通常来说都是:一主一从,一主多从

从库的作用如下:

1、做读写分离

2、做数据副本

3、扩展数据性能

注意事项:

一个maskter可以有多个slave

一个slave只能有一个master

数据流向是单向的,从master到slave,从库只能读,不能写,主库既能读又能写

3、redis主从赋值流程,原理

# redis主从赋值流程,原理
1. 副本(从)库通过slaveof 127.0.0.1 6379命令,连接主库,并发送SYNC给主库 
2. 主库收到SYNC,会立即触发BGSAVE,后台保存RDB,发送给副本库
3. 副本库接收后会应用RDB快照,load进内存
4. 主库会陆续将中间产生的新的操作,保存并发送给副本库
5. 到此,我们主复制集就正常工作了
6. 再此以后,主库只要发生新的操作,都会以命令传播的形式自动发送给副本库.
7. 所有复制相关信息,从info信息中都可以查到.即使重启任何节点,他的主从关系依然都在.
8. 如果发生主从关系断开时,从库数据没有任何损坏,在下次重连之后,从库发送PSYNC给主库
9. 主库只会将从库缺失部分的数据同步给从库应用,达到快速恢复主从的目的

主库是否要开启持久化

如果不开有可能,主库重启操作,造成所有主从数据丢失!

操作命令方式配置从库

启动两台redis服务

在从库的redis客户端执行命名

slaveof 127.0.0.1 6379 #异步

ps:执行命令后从库不能写了,以后只能用来读

断开主从关系的命令

slaveof no one

配置文件中配置主从

在从库的redis配置文件中加入配置

    slaveof 127.0.0.1 6379 #配置从节点ip和端口
	slave-read-only yes #从节点只读,因为可读可写,数据会乱
    autpass 123456

辅助配置(主库用的主从数据一致性配置)

min-slaves-to-write 1
min-slaves-max-lag 3
#那么在从服务器的数量少于1个,或者三个从服务器的延迟(lag)值都大于或等于3秒时,主服务器将拒绝执行写命令

三、哨兵高可用

1、什么是高可用

高可用性(High Availability,简称HA)是指系统在面对各种故障或异常情况时,仍能够保持正常运行的能力。在计算机系统中,高可用性通常指系统能够在出现硬件故障、软件错误、网络中断、自然灾害等情况下,继续提供服务,保证系统的可靠性和可用性。

这里可以看看阿里云,自称高可用性达:99.99%(一年内百分之99.99%的时间都是可用的)

2、哨兵实现高可用

哨兵(Sentinel)是Redis官方提供的一种用于实现Redis高可用性的解决方案。哨兵通过监控Redis主节点的状态,自动进行故障检测和故障转移,以确保Redis集群的高可用性和容错性。

主从复制不是高可用,一旦主机挂了,整个服务就没了

主从存在问题

1、主从复制,主节点发生故障,需要做故障转移,可以手动转移:让其中一个slave变成master(这就是哨兵)

2、主从复制,只能主写数据,所以写能力和存储能力有限(可以通过集群解决)

架构说明(工作原理)

可以做故障判断,故障转移,通知客户端(其实是一个进程),客户端直接连接sentinel的地址

img

在上图中我们可以看到,哨兵也是要做成高可用的

工作原理:

1 多个sentinel发现并确认master有问题

2 选举触一个sentinel作为领导

3 选取一个slave作为新的master

4 通知其余slave成为新的master的slave

5 通知客户端主从变化(通知从库)

6 等待老的master复活成为新master的slave

3、哨兵实现高可用搭建步骤

我们可以在一台设备上开启多个redis实现高可用,也可以在多态设备上实现redis高可用

步骤一

先搭建一主两从

步骤二

哨兵配置文件,启动哨兵(redis的进程,也要监听端口,启动进程有配置文件)

由于我们是在一台设备上实现哨兵高可用的,需要在不同的端口启动redis

配置参数介绍

port 26379
'redis启动的端口'
daemonize yes
'以后台进程的方式启动'
dir /root/redis/data
'日志文件保存的位置'
bind 0.0.0.0
'redis启动的ip地址'
logfile "redis_sentinel.log"
'配置日志文件的名称'
sentinel monitor mymaster 127.0.0.1 6379 2 
'这里的mymaster是主机名称,从库的配置中也要一致,然后这个配置的意思是,两个从库认为你这个主机挂了,就确认你是挂掉的状态了,一般写:哨兵数量/2+1'
sentinel down-after-milliseconds mymaster 30000
'这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒,默认为30秒'

其他辅助配置

protected-mode no 
# 保护模式(设为no就是没有密码)

sentinel parallel-syncs <master-name> <numslaves> 
# 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。

sentinel failover-timeout <master-name> <milliseconds>
failover-timeout 可以用在以下这些方面:     
1. 同一个sentinel对同一个master两次failover之间的间隔时间。   
2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。    
3.当想要取消一个正在进行的failover所需要的时间。    
4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了。

搭一个一主两从,创建三个配置文件:

配置文件名称:sentinal_端口号.conf

创建 data1 data2 data3 个文件夹

    port 26379
    daemonize yes
    dir /root/redis/data
    
    bind 0.0.0.0
    logfile "redis_sentinel.log"
    sentinel monitor mymaster 127.0.0.1 6379 2 
    sentinel down-after-milliseconds mymaster 30000



    port 26380
    daemonize yes
    dir /root/redis/data1
    bind 0.0.0.0
    logfile "redis_sentinel.log"
    sentinel monitor mymaster 127.0.0.1 6379 2
    sentinel down-after-milliseconds mymaster 30000


    port 26381
    daemonize yes
    dir /root/redis/data2
    bind 0.0.0.0
    logfile "redis_sentinel.log"
    sentinel monitor mymaster 127.0.0.1 6379 2
    sentinel down-after-milliseconds mymaster 30000

步骤三

启动三个哨兵

./src/redis-sentinel ./sentinal_26379.conf    ./src/redis-sentinel ./sentinal_26380.conf    ./src/redis-sentinel ./sentinal_26381.conf

步骤四

登陆哨兵的命令

./src/redis-cli -p 26377

主动停掉主redis 6379,哨兵会自动选择一个从库作为主库

redis-cli -p 6379 shutdown

我们发现80库变成了主库,以后79库启动,变成了从库

posted @ 2023-04-22 15:57  wwwxxx123  阅读(99)  评论(0编辑  收藏  举报