前言
在web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等).
高可用的计算公式是1-(宕机时间)/(宕机时间+运行时间)有点类似与网络传输的参数误码率,我们用9的个数表示可用性:
2个9:99%=1%365=3.6524h=87.6h
4个9:99.99%=0.01%36524*60=52.56min
5个9:99.999%=0.001%*365=5.265min
11个9:几乎一年宕机时间只有几分钟
但是在Redis语境中,高可用的含义似乎要宽泛一些,除了保证提供正常服务(如主从分离、快速容灾技术),还需要考虑数据容量的扩展、数据安全不会丢失等.
在Redis中,实现高可用的技术主要包括持久化、主从复制、哨兵和Cluster集群,下面分别说明它们的作用,以及解决了什么样的问题.
持久化:持久化是最简单的高可用方法(有时甚至不被归为高可用的手段),主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而天失.
主从复制:主从复制是高可用Redis的基础,哨兵和集群都是在主从复制基础上实现高可用的.主从复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复.缺陷:故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制.
哨兵:在主从复制的基础上,哨兵实现了自动化的故障恢复.缺陷:写操作无法负载均衡;存储能力受到单机的限制.
cluster集群:通过集群,Redis解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案.
一、Redis主从复制
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(Master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
1.1 主从复制的作用
数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
1.2 主从复制流程
(1)若启动一个slave机器进程,则它会向Master机器发送一个sync command命令,请求同步连接.
(2)无论是第一次连接还是重新连接,Master机器都会启动一个后台进程,将数据快照保存到数据文件中(执行rdb操作),同时Master还会记录修改数据的所有命令并缓存在数据文件中.
(3)后台进程完成缓存操作之后,Master机器就会向slave机器发送数据文件,slave端机器将数据文件保存到硬盘上,然后将其加载到内存中,接着Master机器就会将修改数据的所有操作一并发送给slave端机器.若slave出现故障导致宕机,则恢复正常后会自动重新连接.
(4)Master机器收到slave端机器的连接后,将其完整的数据文件发送给slave端机器,如果Mater同时收到多个slave发来的同步请求,则Master会在后台启动一个进程以保存数据文件,然后将其发送给所有的slave端机器,确保所有的slave端机器都正常.
1.3 搭建Redis主从复制
1.3.1 实验环境
主从 | 虚机 | IP地址 |
master | centos7-1 | 192.168.109.131 |
slave1 | centos7-2 | 192.168.109.132 |
slave2 | centos7-3 | 192.168.109.133 |
1.3.2 所有节点安装
#关闭防火墙 systemctl stop firewalld systemctl disabled firewalld setenforce 0 #下载编译工具 yum install -y gcc gcc-c++ make #上传软件包并解压 tar zxvf redis-5.0.7.tar.gz cd /opt/redis-5.0.7/ #指明安装路径开始安装 make && make PREFIX=/usr/local/redis install #由于Redis源码包中直接提供了Makefile文件,所以在解压完软件包后,不用先执行./configure 进行配置,可直接执行make与make install命令进行安装. #执行软件包提供的insta11 server.sh 脚本文件设置Redis服务所需要的相关配置文件 cd /opt/redis-5.0.7/utils ./install_server.sh #一直回车 Please select the redis executable path [] /usr/local/redis/bin/redis-server#需要手动修改为 /usr/local/redis/bin/redis-server #注意要一次性正确输入 #优化路径 ln -s /usr/local/redis/bin/* /usr/local/bin/ #查看端口状态 netstat -natp |grep redis
1.3.3 修改master节点
vim /etc/redis/6379.conf bind 0.0.0.0 #70行,修改监听地址为0.0.0.0 daemonize yes #137行,开启守护进程 logfile /var/log/redis_6379.1og #172行,指定日志文件目录 dir /var/lib/redis/6379 #264行,指定工作目录 appendonly yes #700行,开启AOF持久化功能 /etc/init.d/redis_6379 restart
1.3.4 修改slave节点
vim /etc/redis/6379.conf bind 0.0.0.0 #70行,修改监听地址为0.0.0.0 daemonize yes #137行,开启守护进程 logfile /var/log/redis_6379.log #172行,指定日志文件目录 dir /var/lib/redis/6379 #264行,指定工作目录 replicaof 192.168.109.131 6379 #288行,指定要同步的Master节点Ip和端口 appendonly yes #700行,开启AOF持久化功能 #传给另一台从 scp /etc/redis/6379.conf 192.168.109.133:/etc/redis/ #重启 /etc/init.d/redis_6379 restart
1.3.5 验证
主节点
cd /var/log/ [root@localhost log]# tail redis_6379.log 56591:M 10 Jun 2022 09:38:24.942 * Background saving terminated with success 56591:M 10 Jun 2022 09:38:24.942 * Synchronization with replica 192.168.109.132:6379 succeeded 56591:M 10 Jun 2022 09:47:14.587 * Replica 192.168.109.133:6379 asks for synchronization 56591:M 10 Jun 2022 09:47:14.588 * Full resync requested by replica 192.168.109.133:6379 56591:M 10 Jun 2022 09:47:14.588 * Starting BGSAVE for SYNC with target: disk 56591:M 10 Jun 2022 09:47:14.588 * Background saving started by pid 56860 56860:C 10 Jun 2022 09:47:14.589 * DB saved on disk 56860:C 10 Jun 2022 09:47:14.589 * RDB: 0 MB of memory used by copy-on-write 56591:M 10 Jun 2022 09:47:14.601 * Background saving terminated with success 56591:M 10 Jun 2022 09:47:14.602 * Synchronization with replica 192.168.109.133:6379 succeeded [root@localhost log]# redis-cli 127.0.0.1:6379> info replication # Replication role:master connected_slaves:2 slave0:ip=192.168.109.132,port=6379,state=online,offset=1134,lag=1 slave1:ip=192.168.109.133,port=6379,state=online,offset=1134,lag=1 master_replid:aeaccb960b6f240d243b13bf642716d2680416a6 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1134 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:1134 127.0.0.1:6379> set name stevelu OK 127.0.0.1:6379> keys * 1) "name" 127.0.0.1:6379> get name "stevelu"
从节点
[root@localhost utils]# redis-cli 127.0.0.1:6379> keys * 1) "name" 127.0.0.1:6379> get name "stevelu"