缓存数据库redis(3)——高可用+集群搭建

1.redis高可用概述

从redis非关系型数据库而言,除了保证提供正常服务(如主从分离、快速容灾技术),还需要考虑数据容量的扩展,数据安全不会丢失等;那么实现高可用的技术主要包括持久化、主从复制、哨兵和集群

2. redis高可用技术(理论部分)

2.1 持久化

主要作用是数据备份,即把数据保存在一个位置或者磁盘中

2.1.1 概述(详见前一篇内容)

redis的持久化介绍

2.2 主从复制

2.2.1 概述

主从复制是高可用Redis的基础,主从复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复
缺陷:
故障恢复无法自动化写操作无法负载均衡
单机的原因限制了存储能力

2.2.2 流程

1.若启动一个slave机器进程,则他会向master机器发送一个sync_command命令,请求同步链接
2.无论是第一次连接还是重新连接,master机器都会启动一个后台进程,将数据快照保存到数据文件中,同时master还会记录修改数据的所有命令并缓存在数据文件中
3.后台进程完成缓存操作之后,,master机器就会向slave机器发送数据文件,slave将数据文件保存至硬盘,然后将其加载到内存中
4.master机器收到slave的连接后,将其完整的数据文件发送给slave,如果master同时收到多个slave发来的同步请求则master会在后台启动一个进程以保存数据文件,然后将其发送给所有的slave机器,确保所有的slave机器都正常

2.3 哨兵

2.3.1 概述

哨兵是Redis集群架构中非常重要的一个组件,哨兵的出现主要是解决了主从复制出现故障时需要人为干预的问题

使用一个或者多个哨兵(Sentinel)实例组成的系统,对redis节点进行监控在主节点出现故障的情况下,能将从节点中的一个从节点角色升级为主节点,进行故障转义,保证系统的可用性

哨兵模式主要功能
①:集群监控:负责监控Redis的master和slave进程是否正常工作
②:消息通知:如果某个Redis实例有故障,那么哨兵负责发送消息作为告警通知给管理员
③:故障转移:如果master node(master角色)挂掉了,会自动转移到slave node上
④:配置中心:如果故障转移发生了,通知client客户端新的master地址

哨兵服务哨兵服务介绍:
-监视master服务器
-发现master宕机后,将从服务器升级为主服务器-主配置文件sentinel.conf
-模板文件:redis-4.0.8/sentinel.conf

优点:高可用,哨兵模式是基于主从模式的,所有主从模式的优点,哨兵模式可以简单的检测和故障自动切换,系统更健壮,可用性更高

缺点:redis比较难支持在线扩容,在群集容量达到上限时在线扩容会变得很复杂

2.3.2 哨兵们监控整个系统节点的过程

①:哨兵之间相互进行命令连接目的为了在同一频道进行信息共享和监控
②:哨兵们向master发送命令连接和订阅连接(周期性)
③:哨兵10/s向master发送info,iR-M会回应哨兵本节点的信息状态+从节点的位置
④:哨兵收到回复之后,知晓R-S01 R-S02的位置
⑤:然后再向slaves发送命令连接和订阅连接(周期性) ,以达到监控整个集群的目的

2.3.3 哨兵模式下的故障迁移

①:主观下线
哨兵(Sentinel)节点会每秒一次的频率向建立了命令连接的实例发送PING命令,如果在down-after-milliseconds毫秒内没有做出有效响应包括(PONG/ LOADING/MASTERDOWN)以外的响应,哨兵就会将该实例在本结构体中的状态标记为SRI_s_DOWN主观下线
②:客观下线
当一个哨兵节点发现主节点处于主观下线状态是,会向其他的哨兵节点发出询问,该节点是不是已经主观下线了。如果超过配置参数quorum个节点认为是主观下线时,该哨兵节点就会将自己维护的结构体中该主节点标记为SRIO DOWN客观下线询问命令SENTINEL is-master-down-by-addr
③:master选举
在认为主节点客观下线的情况下,哨兵节点节点间会发起一.次选举,命令为:SENTINEL is-master-down-by-addr只是runid这次会将自己的runid带进去, 希望接受者将自己设置为主节点。如果超过半数以.上的节点返回将该节点标记为leacer的情况下,会有该leader对故障进行迁移
⑥:故障转移
在从节点中挑选出新的主节点
通讯正常
优先级排序
优先级相同时选择offset最大的( 最接近master的)
将该节点设置成新的主节点SLAVEOFnoone,并确保在后续的INGO命令时该节点返回状态为master
将其他的从节点设置成从新的主节点的从节点,SLAVEQF命令
将旧的主节点变成新的主节点的从节点

2.4 集群(cluster)

写操作无法实现负载均衡这一问题,通过Redis集群解决掉了
针对单机的原因限制了存储能力,也实现了相对较为完善的方案(高可用)

2.4.1 概述

主节点负责读写请求和集群信息的维护,从节点只进行主节点数据和状态信息的复制

2.4.2 作用

1.数据分区
数据分区(或称数据分片)是集群最核心的功能(分布式)
集群将数据分散到多个节点,一方面突破了 Redis 单机内存大小的限制,存储容量大大增加,另一方面每个主节点都可以对外提供读服务和写服务,大大提高了集群的响应能力
Redis 单机内存大小受限问题,在介绍持久化和主从复制时都有提及,例如,如果单机内存太大,bgsave 和 bgrewriteaof 的 fork 操作可能导致主进程阻塞,主从环境下主机切换时可能导致从节点长时间无法提供服务,全量复制阶段主节点的复制缓冲区可能溢出

2.高可用
集群支持主从复制(模式)和主节点的自动故障转移(与哨兵类似),当任意节点发送故障时,集群仍然可以对外提供服务

3.数据分片
Redis 集群引入了哈希槽的概念,有 16384 个哈希槽(编号 0~16383)集群的每个节点负责一部分哈希槽,每个 Key 通过 CRC16 校验后对 16384 取余来决定放置哪个哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作

2.4.3 集群之间的区别

中心化集群和非中心化集群的区别:
1、中心化集群
群集区分主-次关系(区分中心和普通服务器)单点故障由mha缓解(ha不仅仅包含了冗余备份,还有高性能)

2、无中心化/去中心化集群
多台相同的服务器组成集群后,服务器之间不存在主-次关系,即中心服务器和普通服务器关系
去中心化集群,典型的特点是数据共享(每个服务器都会同步对方的数据),挂掉一个不会有太大的影响(非高并发情况下)方便横向扩容(增加服务器),可以说没有特别典型的单点故障,同时去中心化实现ha(高性能)方式是分布式来实现的

有状态和无状态的概念:
无状态:加入集群之后集群认为是普通节点,没有明确的角色定位
有状态:加入集群之后有定位要求(主或从角色),有明确的角色定位

3. 搭建部署三种模式(实验部分)

3.1 主从复制

3.1.1 搭建环境

master 192.168.152.130
slave1 192.168.152.129
slave2 192.168.152.128

3.1.2 搭建过程

详细安装步骤见这篇博客:
5.源码安装redis:安装步骤

使用命令 netstat -natp | grep redis 查看到端口起来之后,开始进入配置文件:

进入配置文件(主从设置不一样):

master:
[root@master ~]# vim /etc/redis/6379.conf

第70行 bind 0.0.0.0                     #修改监听地址
第137行 daemonize yes                   #开启守护进程
第172行 logfile /var/log/redis_6379.log #指定日志文件目录
第264行 dir /var/lib/redis/6379         #指定工作目录
第700行 appendonly yes                  #开启AOF持久化功能

[root@master ~]# /etc/init.d/redis_6379 restart
Stopping ...
Waiting for Redis to shutdown ...
Redis stopped
Starting Redis server...
[root@master ~]# netstat -natp | grep redis
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      29211/redis-server  
[root@master ~]# 

slave1和slave2:
[root@slave1 ~]# vim /etc/redis/6379.conf

第70行 bind 0.0.0.0                      #修改监听端口
第137行 daemonize yes                    #开启守护进程
第172行 logfile /var/log/redis_6379.log  #指定日志文件目录
第264行 dir /var/lib/redis/6379          #指定工作目录
第288行 replicaof 192.168.152.130 6379   #指定同步的master节点ip和端口(添加的配置)
第700行 appendonly yes                   #开启AOF持久化

[root@slave1 ~]# /etc/init.d/redis_6379 restart
Stopping ...
Waiting for Redis to shutdown ...
Redis stopped
Starting Redis server...
[root@slave1 ~]# netstat -natp | grep redis
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      84735/redis-server  
[root@slave1 ~]# 

3.1.3 验证主从复制

在master上进行输入命令:
[root@master ~]# tail -f /var/log/redis_6379.log
或者是下面这则命令,查看日志文件
[root@master ~]# cat /var/log/redis_6379.log

[root@master ~]# redis-cli info replication
# Replication
role:master
#角色是master
connected_slaves:2
#连接从服务器2个
slave0:ip=192.168.152.128,port=6379,state=online,offset=2226,lag=1
slave1:ip=192.168.152.129,port=6379,state=online,offset=2226,lag=1
master_replid:e5ea3429a75e72b43b814353fa8df3f2ace2351f
#master启动时生成的40位16进制的随机字符串,用来标识master节点
master_replid2:0000000000000000000000000000000000000000
#切换主从的时候master节点标识会有更改(暂时是0)
master_repl_offset:2226
#复制流中的一个偏移量,master处理完写入命令后,会把命令的字节长度做累加记录,统计在该字段。该字段也是实现部分复制的关键字段
second_repl_offset:-1
#无论主从,都表示自己上次主实例repid1和复制偏移量;用于兄弟实例或级联复制,主库故障切换
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2226


或者是这样:


分别在master与slave1,slave2上进行验证:
master创建key,slave1和slave2同步,可以查看到值

master:
[root@master ~]# redis-cli
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set aaa 123
OK
127.0.0.1:6379> get aaa
"123"
127.0.0.1:6379> 

slave1,slave2:
[root@slave1 ~]# redis-cli
127.0.0.1:6379> keys *
1) "aaa"
127.0.0.1:6379> get aaa
"123"
127.0.0.1:6379> 

3.2 哨兵

3.2.1 搭建环境

master 192.168.152.130
slave1 192.168.152.129
slave2 192.168.152.128

3.2.2 搭建过程

在主从复制的基础上进行修改文件:
1、首先依据上面步骤搭建好主从复制配置
2、修改哨兵配置文件(所有节点都需要修改)

[root@master ~]# vim /opt/redis-5.0.7/sentinel.conf

17 protected-mode no		#关闭保护模式
21 port 26379		        #Redis哨兵默认的监听端口
26 daemonize yes		    #开启守护进程
36 logfile "/var/log/sentinel.log"		#指定日志存放路径
65 dir /var/lib/redis/6379		        #指定数据库存放路径
84 sentinel monitor mymaster 192.168.152.130 6379 2	
#指定哨兵节点;2:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移
113 sentinel down-after-milliseconds mymaster 3000		
#判定服务器down掉的时间周期,默认30000毫秒 (30秒)
146 sentinel failover- timeout mymaster 180000		
#故障节点的最大超时时间为180000 (180秒)

3.2.3 启动哨兵模式

各服务器先启动主节点在启动从节点

redis-sentinel sentinel.conf &
#使用redis-sentinel启动,再使用sentinel.conf,&:放在在后台启动

[root@master ~]# cd /opt/redis-5.0.7/
[root@master redis-5.0.7]# redis-sentinel sentinel.conf &
[1] 30617
[root@master redis-5.0.7]# 
[root@master redis-5.0.7]# redis-cli -p 26379 info sentinel  #查看哨兵信息;哨兵端口26379
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.152.130:6379,slaves=2,sentinels=3
[1]+  完成                  redis-sentinel sentinel.conf
[root@master redis-5.0.7]# 


[root@slave1 ~]# cd /opt/redis-5.0.7/
[root@slave1 redis-5.0.7]# redis-sentinel sentinel.conf &
[1] 86149
[root@slave1 redis-5.0.7]# 

[root@slave2 ~]# cd /opt/redis-5.0.7/
[root@slave2 redis-5.0.7]# redis-sentinel sentinel.conf &
[1] 92431
[root@slave2 redis-5.0.7]# 

3.2.4 模拟故障

[root@master redis-5.0.7]# ps -ef | grep "redis"
#查看redis-server的进程号
root      29888      1  0 17:56 ?        00:00:12 /usr/local/redis/bin/redis-server 0.0.0.0:6379
root      30618      1  1 19:08 ?        00:00:02 redis-sentinel *:26379 [sentinel]
root      30663  28876  0 19:11 pts/1    00:00:00 grep --color=auto redis
[root@master redis-5.0.7]# 
[root@master redis-5.0.7]# 
[root@master redis-5.0.7]# kill -9 29888
#杀死Master 节点_上的redis-server 的进程号

[root@master redis-5.0.7]# 
[root@master redis-5.0.7]# ps -ef | grep "redis"
root      30618      1  1 19:08 ?        00:00:03 redis-sentinel *:26379 [sentinel]
root      30673  28876  0 19:12 pts/1    00:00:00 grep --color=auto redis
[root@master redis-5.0.7]# 
[root@master redis-5.0.7]# tail -f /var/log/sentinel.log
[root@master redis-5.0.7]# 
[root@master redis-5.0.7]# watch -n 1 redis-cli -p 26379 info sentinel
[root@master redis-5.0.7]# 

效果显示如图:切换成slave2的ip的地址


查看现在哨兵的信息:

3.3 Cluster集群

3.3.1 搭建环境

redis的集群一般需要6个节点,3主3从。方便起见,这里所有节点在同一台服务器上模拟
以端口号进行区分: 3个主节点端口号: 6001/6002/6003, 对应的从节点端口号: 6004/ 6005/ 6006

3.3.2 部署redis步骤

# 创建节点目录,创建6个节点的工作目录

[root@master ~]# cd /etc/redis/
[root@master redis]# mkdir -p redis-cluster/redis600{1..6}
[root@master redis]# ls redis-cluster/
redis6001  redis6002  redis6003  redis6004  redis6005  redis6006
[root@master redis]# 

#创建脚本
[root@master redis]# cd /opt
[root@master opt]# vim redis.sh

[root@master opt]# vim redis.sh

#!/bin/bash
for i in {1..6}
do      
cp /opt/redis-5.0.7/redis.conf /etc/redis/redis-cluster/redis600$i
#配置文件  模拟的6台redis
cp /opt/redis-5.0.7/src/redis-cli /opt/redis-5.0.7/src/redis-server /etc/redis/redis-cluster/redis600$i
#登陆命令  登录脚本
done    

[root@master opt]#  bash -x /opt/redis.sh
#使用脚本将配置文件复制
+ for i in '{1..6}'
+ cp /opt/redis-5.0.7/redis.conf /etc/redis/redis-cluster/redis6001
+ cp /opt/redis-5.0.7/src/redis-cli /opt/redis-5.0.7/src/redis-server /etc/redis/redis-cluster/redis6001
+ for i in '{1..6}'
+ cp /opt/redis-5.0.7/redis.conf /etc/redis/redis-cluster/redis6002
+ cp /opt/redis-5.0.7/src/redis-cli /opt/redis-5.0.7/src/redis-server /etc/redis/redis-cluster/redis6002
+ for i in '{1..6}'
+ cp /opt/redis-5.0.7/redis.conf /etc/redis/redis-cluster/redis6003
+ cp /opt/redis-5.0.7/src/redis-cli /opt/redis-5.0.7/src/redis-server /etc/redis/redis-cluster/redis6003
+ for i in '{1..6}'
+ cp /opt/redis-5.0.7/redis.conf /etc/redis/redis-cluster/redis6004
+ cp /opt/redis-5.0.7/src/redis-cli /opt/redis-5.0.7/src/redis-server /etc/redis/redis-cluster/redis6004
+ for i in '{1..6}'
+ cp /opt/redis-5.0.7/redis.conf /etc/redis/redis-cluster/redis6005
+ cp /opt/redis-5.0.7/src/redis-cli /opt/redis-5.0.7/src/redis-server /etc/redis/redis-cluster/redis6005
+ for i in '{1..6}'
+ cp /opt/redis-5.0.7/redis.conf /etc/redis/redis-cluster/redis6006
+ cp /opt/redis-5.0.7/src/redis-cli /opt/redis-5.0.7/src/redis-server /etc/redis/redis-cluster/redis6006

#查看是否创建成功,目录里面是否存在内容
[root@master opt]# cd /etc/redis/redis-cluster/
[root@master redis-cluster]# ls
redis6001  redis6002  redis6003  redis6004  redis6005  redis6006
[root@master redis-cluster]# ls redis6001
redis-cli  redis.conf  redis-server

3.3.3 修改配置文件

[root@master redis-cluster]# ls
redis6001  redis6002  redis6003  redis6004  redis6005  redis6006
[root@master redis-cluster]# 
[root@master redis-cluster]# cd redis6001
[root@master redis6001]# ls
redis-cli  redis.conf  redis-server
[root@master redis6001]# vim redis.conf 

第69行 bind 127.0.0.1 #注释掉或者不修改,默认监听所有网卡
第88行 protected-mode no #关闭保护模式
第92行 port 6001 #修改监听端口
第136行 daemonize yes #开启守护进程
第699行 appendonly yes #开启AOF持久化
第832行 cluster-enabled yes #取消注释,开启集群功能
第840行 cluster-config-file nodes-6001.conf #取消注释,设置集群名称文件
第846行 cluster-node-timeout 15000 #取消注释,设置集群超时时间

其他五个配置文件除端口号和文件名称外其余改动相同,复制redis6001至redis6002-6006
步骤:
[root@master redis6001]# ls
redis-cli  redis.conf  redis-server
[root@master redis6001]# cp redis.conf ../redis6002/
cp:是否覆盖"../redis6002/redis.conf"? y
[root@master redis6001]# cp redis.conf ../redis6003/
cp:是否覆盖"../redis6003/redis.conf"? y
[root@master redis6001]# cp redis.conf ../redis6004/
cp:是否覆盖"../redis6004/redis.conf"? y
[root@master redis6001]# cp redis.conf ../redis6005/
cp:是否覆盖"../redis6005/redis.conf"? y
[root@master redis6001]# cp redis.conf ../redis6006/
cp:是否覆盖"../redis6006/redis.conf"? y
[root@master redis6001]# 

#逐个修改里面两个内容
#第92行 port 端口
#第840行 cluster-config-file nodes-6001.conf 设置集群名称文件

[root@master redis6003]# cd ..
[root@master redis-cluster]# cd redis6002
[root@master redis6004]# vim redis.conf 
[root@master redis6004]# 

3.3.4 启动服务

可以手动启动六次或者写入脚本执行脚本:
手动启动六次:
[root@master redis-cluster]# ls
redis6001  redis6002  redis6003  redis6004  redis6005  redis6006
[root@master redis-cluster]# cd redis6001/
[root@master redis6001]# redis-server redis.conf 
32495:C 09 Aug 2021 22:04:43.499 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
32495:C 09 Aug 2021 22:04:43.500 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=32495, just started
32495:C 09 Aug 2021 22:04:43.500 # Configuration loaded
[root@master redis6001]# 

或者是执行脚本启动:
vim /opt/redis_start.sh	##根据对应配置文件启动redis
#!/bin/bash
for d in {1..6}
do
cd /etc/redis/redis-cluster/redis600$d
redis-server redis.conf
done

bash -x /opt/redis_start.sh

查看一下端口信息:
[root@master redis6006]# ps -ef | grep redis
root      30618      1  0 19:08 ?        00:01:19 redis-sentinel *:26379 [sentinel]
root      32496      1  0 22:04 ?        00:00:00 redis-server 127.0.0.1:6001 [cluster]
root      32518      1  0 22:07 ?        00:00:00 redis-server 127.0.0.1:6002 [cluster]
root      32524      1  0 22:07 ?        00:00:00 redis-server 127.0.0.1:6003 [cluster]
root      32531      1  0 22:07 ?        00:00:00 redis-server 127.0.0.1:6004 [cluster]
root      32546      1  0 22:07 ?        00:00:00 redis-server 127.0.0.1:6005 [cluster]
root      32552      1  0 22:07 ?        00:00:00 redis-server 127.0.0.1:6006 [cluster]
root      32557  28876  0 22:08 pts/1    00:00:00 grep --color=auto redis
[root@master redis6006]# 

3.3.5 加入集群

六个实例分为三组,每组一主一从,前面的做主节点,后面的做从节点;
下面交互的时候需要输入yes才可以创建;-replicas 1表示每个主节点有一个从节点

[root@master redis6006]# cd
[root@master ~]# 
[root@master ~]# redis-cli --cluster create 127.0.0.1:6001 127.0.0.1:6002 127.0.0.1:6003 127.0.0.1:6004 127.0.0.1:6005 127.0.0.1:6006 --cluster-replicas 1


3.3.6 验证集群是否成功

[root@master ~]# redis-cli -p 6001 -c   #加-c参数,节点之间就可以互相跳转
127.0.0.1:6001> cluster slots           #查看节点的哈希槽编号范围
1) 1) (integer) 10923
   2) (integer) 16383   #哈希槽编号范围
   3) 1) "127.0.0.1"
      2) (integer) 6003  #主节点的ip和端口号
      3) "5473c012c260bb8c4dd731686ad7298e201cafe6"
   4) 1) "127.0.0.1"
      2) (integer) 6006  #从节点的ip和端口号
      3) "87c7beb7c1eaa37cf6c4e7ec575aba5bd55b8406"
2) 1) (integer) 5461
   2) (integer) 10922
   3) 1) "127.0.0.1"
      2) (integer) 6002
      3) "2eb0a1b657aba09f5c3df9d9e81477ec76b0e97a"
   4) 1) "127.0.0.1"
      2) (integer) 6005
      3) "a1fa093e2c5cb57b32ec01af9c2b8c168be2b4ca"
3) 1) (integer) 0
   2) (integer) 5460
   3) 1) "127.0.0.1"
      2) (integer) 6001
      3) "fe3164114a7c15cdca2ba83d5904ddf3e1559e16"
   4) 1) "127.0.0.1"
      2) (integer) 6004
      3) "d613737ffcb866b63aec37a0907df5991121eac1"
127.0.0.1:6001> 
127.0.0.1:6001> 
127.0.0.1:6001> 
127.0.0.1:6001> set abc 123   #新建的键,验证是否会分配到指定哈希槽
-> Redirected to slot [7638] located at 127.0.0.1:6002
OK
127.0.0.1:6002> cluster keyslot abc  #查看哈希槽编号 
(integer) 7638
127.0.0.1:6002> 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值