【Redis】分布式场景下Redis高可用部署方案

1、Redis高可用概述

参考博文:

在介绍Redis高可用之前,先说明一下在Redis的语境中高可用的含义。

我们知道,在web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999% 等等)。但是在Redis语境中,高可用的含义似乎要宽泛一些,除了保证提供正常服务(如主从分离快速容灾技术),还需要考虑数据容量的扩展数据安全不会丢失等。

在Redis中,实现高可用的技术主要包括持久化复制哨兵集群,下面分别说明它们的作用,以及解决了什么样的问题。

  • 持久化:持久化是最简单的高可用方法(有时甚至不被归为高可用的手段),主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失
  • 复制:复制是Redis高可用的基础,哨兵和集群都是在复制基础上实现高可用的。复制主要实现了数据的多机备份(解决单点故障问题),以及对于读操作的负载均衡简单的故障恢复。缺陷:故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制
  • 哨兵:在复制的基础上,哨兵实现了自动化的故障恢复。缺陷:写操作无法负载均衡;存储能力受到单机的限制
  • 集群:通过集群,Redis解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案。

2、持久化

Redis持久化分为RDB持久化和AOF持久化:前者将当前数据保存到硬盘,后者则是将每次执行的写命令保存到硬盘(类似于MySQL的binlog);由于AOF持久化的实时性更好,即当进程意外退出时丢失的数据更少,因此AOF是目前主流的持久化方式,不过RDB持久化仍然有其用武之地。(AOF和RDB持久化的区别以及如何选择使用?)

1)RDB持久化

save命令和bgsave命令都可以生成RDB文件。但由于save的整个过程会阻塞服务器,导致服务器无法处理其他请求,现已基本废弃使用。而bgsave命令会创建一个子进程(bgsave仅会在fork子进程的时候阻塞),由子进程来负责创建RDB文件,父进程(即Redis主进程)则继续处理请求。因此线上命令行应使用bgsave命令触发持久化。

也可以修改redis的默认配置文件实现自动触发。如下图:

在这里插入图片描述

save m n	# 指定当m秒内发生n次变化时,会触发bgsave

其中save 900 1的含义是:当时间到900秒时,如果redis数据发生了至少1次变化,则执行bgsave;save 300 10和save 60 10000同理。当三个save条件满足任意一个时,都会引起bgsave的调用。

RDB文件的载入工作是在服务器启动时自动执行的,并没有专门的命令。但是由于AOF的优先级更高,因此当AOF开启时,Redis会优先载入AOF文件来恢复数据;只有当AOF关闭时,才会在Redis服务器启动时检测RDB文件,并自动载入。服务器载入RDB文件期间处于阻塞状态,直到载入完成为止

下面是RDB常用的配置项,以及默认值。

  • save m n:bgsave自动触发的条件;如果没有save m n配置,相当于自动的RDB持久化关闭,不过此时仍可以通过其他方式触发
  • stop-writes-on-bgsave-error yes:当bgsave出现错误时,Redis是否停止执行写命令;设置为yes,则当硬盘出现问题时,可以及时发现,避免数据的大量丢失;设置为no,则Redis无视bgsave的错误继续执行写命令,当对Redis服务器的系统(尤其是硬盘)使用了监控时,该选项考虑设置为no
  • rdbcompression yes:是否开启RDB文件压缩
  • rdbchecksum yes:是否开启RDB文件的校验,在写入文件和读取文件时都起作用;关闭checksum在写入文件和启动文件时大约能带来10%的性能提升,但是数据损坏时无法发现
  • dbfilename dump.rdb:RDB文件名
  • dir ./:RDB文件和AOF文件所在目录
2)AOF持久化

将Redis执行的每次写命令记录到单独的日志文件中(有点像MySQL的binlog);当Redis重启时再次执行AOF文件中的命令来恢复数据。

appendonly yes	# 开启AOF持久化

执行流程:

  1. 命令追加(append):将Redis的写命令追加到缓冲区aof_buf。Redis先将写命令追加到缓冲区,而不是直接写入文件,主要是为了避免每次有写命令都直接写入硬盘,导致硬盘IO成为Redis负载的瓶颈。
  2. 文件写入(write)和文件同步(sync):根据不同的同步策略将aof_buf中的内容同步到硬盘;AOF缓存区的同步文件策略由参数appendfsync控制,各个值的含义如下:
    1)always:命令写入aof_buf后立即调用系统fsync操作同步到AOF文件,fsync完成后线程返回。这种情况下,每次有写命令都要同步到AOF文件,硬盘IO成为性能瓶颈,Redis只能支持大约几百TPS写入,严重降低了Redis的性能;即便是使用固态硬盘(SSD),每秒大约也只能处理几万个命令,而且会大大降低SSD的寿命。
    2)no:命令写入aof_buf后调用系统write操作,不对AOF文件做fsync同步;同步由操作系统负责,通常同步周期为30秒。这种情况下,文件同步的时间不可控,且缓冲区中堆积的数据会很多,数据安全性无法保证。
    3)everysec:命令写入aof_buf后调用系统write操作,write完成后线程返回;fsync同步文件操作由专门的线程每秒调用一次。everysec是前述两种策略的折中,是性能和数据安全性的平衡,因此是Redis的默认配置,也是我们推荐的配置。
  3. 文件重写(rewrite):定期重写AOF文件,达到压缩的目的。需要注意的是,AOF重写是把Redis进程内的数据转化为写命令,同步到新的AOF文件;不会对旧的AOF文件进行任何读取、写入操作。文件重写之所以能够压缩AOF文件,原因在于:
    1)过期的数据不再写入文件
    2)无效的命令不再写入文件:如有些数据被重复设值(set mykey v1, set mykey v2)、有些数据被删除了(sadd myset v1, del myset)等等
    3)多条命令可以合并为一个:如sadd myset v1, sadd myset v2, sadd myset v3可以合并为sadd myset v1 v2 v3。不过为了防止单条命令过大造成客户端缓冲区溢出,对于list、set、hash、zset类型的key,并不一定只使用一条命令;而是以某个常量为界将命令拆分为多条。(这个常量在redis.h/REDIS_AOF_REWRITE_ITEMS_PER_CMD中定义,不可更改,3.0版本中值是64。)

文件重写的触发

手动触发:bgrewriteaof

在这里插入图片描述

自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数,以及aof_current_size和aof_base_size状态确定触发时机。

  • auto-aof-rewrite-min-size:执行AOF重写时,文件的最小体积,默认值为64MB。
  • auto-aof-rewrite-percentage:执行AOF重写时,当前AOF大小(即aof_current_size)和上一次重写时AOF大小(aof_base_size)的比值。

其中,参数可以通过config get命令查看:

在这里插入图片描述

状态可以通过info persistence查看

在这里插入图片描述
有当auto-aof-rewrite-min-size和auto-aof-rewrite-percentage两个参数同时满足时,才会自动触发AOF重写,即bgrewriteaof操作。

下面是AOF常用的配置项,以及默认值;前面介绍过的这里不再详细介绍。

  • appendonly no:是否开启AOF
  • appendfilename “appendonly.aof”:AOF文件名
  • dir ./:RDB文件和AOF文件所在目录
  • appendfsync everysec:fsync持久化策略
  • no-appendfsync-on-rewrite no:AOF重写期间是否禁止fsync;如果开启该选项,可以减轻文件重写时CPU和硬盘的负载(尤其是硬盘),但是可能会丢失AOF重写期间的数据;需要在负载和安全性之间进行平衡
  • auto-aof-rewrite-percentage 100:文件重写触发条件之一
  • auto-aof-rewrite-min-size 64mb:文件重写触发提交之一
  • aof-load-truncated yes:如果AOF文件结尾损坏,Redis启动时是否仍载入AOF文件

一般我们在生产上采用的持久化策略为

  • master关闭持久化
  • slave开RDB即可,必要的时候AOF和RDB都开启

AOF和RDB持久化的区别?

3、Redis主从复制

利用docker启动两个redis实例

# 拉取redis镜像
​docker pull redis:5.0.0
# 创建配置文件
​touch /docker/redis/conf/redis.conf
# 启动镜像容器
docker run -p 6379:6379 --name redis \
-v /docker/redis/data:/data \
-v /docker/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis:5.0.0 redis-server   
# 开启自启动
​docker update redis --restart=always

服务器ip为172.16.31.128 分别映射在6379(主)和6380(从)端口下(默认都是主节点)

在这里插入图片描述

实现方式

需要注意,主从复制的开启,完全是在从节点发起的;不需要我们在主节点做任何事情。

从节点开启主从复制,有3种方式:

  • 配置文件。在从服务器的配置文件中加入:slaveof <masterip> <masterport>
  • 启动命令。redis-server启动命令后加入 --slaveof <masterip> <masterport>
  • 客户端命令。Redis服务器启动后,直接通过客户端执行命令:slaveof ,则该Redis实例成为从节点。

上述3种方式是等效的,下面以客户端命令的方式为例,看一下当执行了slaveof后,Redis主节点和从节点的变化。

从节点输入slaveof命令,加入到主节点下

在这里插入图片描述
向主节点添加 hello ——> world

在这里插入图片描述
从节点能够get出来,说明主从没问题!!!

在这里插入图片描述
删除以后查看从节点,发现从节点也同步删除了。

在这里插入图片描述
在这里插入图片描述

可以通过slaveof no one命令断开所有主从连接

4、Redis哨兵模式

3、Redis集群模式

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值