如何搭建Redis集群(主从+哨兵)

一、什么是redis主从复制?

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。master以写为主,slave以读为主。

 

二、主从复制的作用
数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。

故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。

负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。

读写分离:可以用于实现读写分离,主库写、从库读,读写分离不仅可以提高服务器的负载能力,同时可根据需求的变化,改变从库的数量;

高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。

三、实现主从复制

1、环境准备

先准备三台服务器,并安装好redis服务,具体步骤可参考Centos下安装redis

注意:我们需要设置一下防火墙,否则主从机之间无法同步数据,命令如下,这里根据自己设置的端口进行更改。或者关闭防火墙也可以

#开放6379端口
firewall-cmd --add-port=6379/tcp --permanent --zone=public
#重启防火墙(修改配置后要重启防火墙)
firewall-cmd --reload

#查看防火墙命令
systemctl status firewalld.service
#关闭防火墙命令 重启虚拟机防火墙会重新打开
systemctl stop firewalld.service    

2、redis环境配置

#修改redis.conf
bind  192.168.XX.XX #绑定本机ip地址
port 6739 # 绑定端口号
daemonize yes #用来指定redis是否要用守护进程的方式启动,默认为no
logfile ./redis_6379.log #redis日志文件
pidfile  ./redis_6379.pid #当Redis以守护进程方式运行时,即使该项没有配置,Redis也会默认把pid写入/var/run/redis.pid文件;而当Redis不是以守护进程凡是运行时,若该项没有配置,则redis不会创建pid文件。创建pid文件是尝试性的动作,即使创建写入失败,redis依然可以启动运行
replicaof  192.168.10.6 6379 #配置文件中设置主节点的方法,redis主从复制这个地方只配置从库,不用配置主库!注意:主库不需要这个配置
requirepass 668668  #本地redis密码
masterauth  668668  #主节点redis密码 注意:主节点也要配置,后边哨兵容灾切换用到
#了解即可
#protected-mode yes  Protected-mode 是为了禁止公网访问redis缓存,加强redis安全的它启用的条件,有两个: 1、没有bind IP 2 、没有设置访问密码

 

注解:

为了后边的哨兵配置,切记一定要把主节点和从节点的密码设置为一样的, 因为sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同要是不信邪可以试一试,我就是不信邪掉坑里了

daemonize 设置yes或者no区别:

daemonize:yes:redis采用的是单进程多线程的模式。当daemonize设置成yes时,代表开启守护进程模式。在该模式下,redis会在后台运行,此时redis将一直运行,除非手动kill该进程。

daemonize:no: 当daemonize选项设置成no时,当前界面将进入redis的命令行界面,exit强制退出或者关闭连接工具(putty,xshell等)都会导致redis进程退出。

3、分别启动3台redis服务

redis-server redisConfig/redis.conf #启动redis服务
redis-cli -p 6379 -h 192.168.XX.XX #连接客户端
192.168.10.99:6379> auth 本机密码  #验证密码
OK

redis服务启动完毕之后,执行info replication命令查看当前主从配置

从节点

192.168.10.99:6379> info replication 
# Replication
role:slave # 当前角色是从机
master_host:192.168.10.6 #主机信息
master_port:6379
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_repl_offset:14
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:0f3632a522ad99e6b2950160fc7065eb04f8707a
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14

主节点

192.168.10.6:6379> info replication
# Replication
role:master
connected_Slaves :2 #主节点下有两个从机
slave0:ip=192.168.10.99,port=6379,state=on1ine,offset=2796, lag=0 #从机的ip和端口
slave1:ip=192.168.10.66,port=6379,state=online,offset=2796,lag=0
masterfailoverstate:no-failover 
masterrep1id:Bf3632a5Z2ad99e6b2950160fc7065eb04f8707a
masterreplid2:0000000000000000000000000000000000000
masterrepl_offset:2796
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_Size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2796

测试主从:
1、主节点

192.168.10.6:6379> set k1 v1 
OK

2、从节点

192.168.10.66:6379> keys *
1) "k1"
192.168.10.66:6379> get k1
"v1"

  

注意:

1、主机可以写,从机不能写,只能读。主机中的所有数据都会保存到从机中去。

2、主机断开连接,从机依旧连接到主机的,但是没有写操作,这个时候,主机如果回来了,从机依旧可以直接获取到主机写的信息!

3、如果是使用命令行,来配置的主从,这个时候如果重启了,就会变回主机!只要变为从机,立马就会从主机中获取值!

4、主从复制原理
Slave 启动成功连接到 master 后会发送一个sync同步命令

Master 接到命令,启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,并完成一次完全同步。

全量复制:slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。

增量复制:Master 继续将新的所有收集到的修改命令依次传给slave,完成同步,但是只要是重新连接master,一次完全同步(全量复制)将被自动执行! 主机的数据一定可以在从机中看到。

三、哨兵模式搭建
1、什么是redis哨兵?
Redis Sentinel是Redis 的高可用性解决方案,由一个或多个Sentinel(哨兵)实例组成。它可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,它的主要功能如下:

监控(Monitoring):Sentinel会不断地检查你的主服务器和从服务器是否运作正常。

通知(Notification):当被监控的某个 Redis 服务器出现问题时, Sentinel可以通过API向管理员或者其他应用程序发送通知。

故障迁移:当主服务器不能正常工作时,Sentinel会自动进行故障迁移,也就是主从切换。

统一的配置:管理连接者询问sentinel取得主从的地址。

2、哨兵原理是什么?
Sentinel 使用的算法核心是 Raft算法,主要用途就是用于分布式系统,系统容错,以及Leader选举,每个Sentinel都需要定期的执行以下任务:

每个 Sentinel会自动发现其他 Sentinel 和从服务器,它以每秒钟一次的频率向它所知的主服务器、从服务器以及其他Sentinel实例发送一个 PING 命令。

如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds选项所指定的值, 那么这个实例会被Sentinel标记为主观下线。 有效回复可以是: +PONG 、 -LOADING 或者 -MASTERDOWN 。

如果一个主服务器被标记为主观下线, 那么正在监视这个主服务器的所有Sentinel要以每秒一次的频率确认主服务器的确进入了主观下线状态。

如果一个主服务器被标记为主观下线, 并且有足够数量的Sentinel(至少要达到配置文件指定的数量)在指定的时间范围内同意这一判断,
那么这个主服务器被标记为客观下线。

在一般情况下, 每个Sentinel会以每 10 秒一次的频率向它已知的所有主服务器和从服务器发送 INFO 命令。当一个主服务器Sentinel标记为客观下线时,Sentinel向下线主服务器的所有从服务器发送 INFO 命令的频率会从 10秒一次改为每秒一次。

当没有足够数量的Sentinel同意主服务器已经下线, 主服务器的客观下线状态就会被移除。 当主服务器重新向Sentinel的 PING命令返回有效回复时, 主服务器的主管下线状态就会被移除。

 

 

 

3、搭建哨兵

在每台服务器上部署一个哨兵,配置方式如下:

#在redis安装目录下使用vi命令创建哨兵配置文件
vi sentinel.conf

#端口默认为26379。
port 26379
#关闭保护模式,可以外部访问。
protected-mode no
#设置为后台启动。
daemonize yes
#日志文件。
logfile ./sentinel.log
#指定服务器IP地址和端口,并且指定当有2台哨兵认为主机挂了,则对主机进行容灾切换。 注意:三台哨兵这里的ip配置均为主节点ip 和端口
sentinel monitor mymaster 192.168.10.6 6379 2
#当在Redis实例中开启了requirepass,这里就需要提供密码。
sentinel auth-pass mymaster psw66
#这里设置了主机多少秒无响应,则认为挂了。
sentinel down-after-milliseconds mymaster 3000
#主备切换时,最多有多少个slave同时对新的master进行同步,这里设置为默认的snetinel parallel-syncs mymaster 1
#故障转移的超时时间,这里设置为三分钟。
sentinel failover-timeout mymaster 180000

4、分别启动三台服务器上的哨兵

#启动哨兵命令  分别在三台服务器上启动各自的哨兵
redis-sentinel redisConfig/sentinel.conf 

  

#连接客户端
[root@localhost bin]# redis-cli -p 26379
#查看哨兵信息
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
#哨兵已经监听到主节点IP端口和运行状态,并且有2个从节点,3个哨兵。
master0:name=mymaster,status=ok,address=192.168.10.6:6379,slaves=2,sentinels=3

5、redis容灾切换

(1)通过模拟主节点宕机,来查看哨兵的作用:

#连接redis客户端
[root@localhost bin]# redis-cli -p 6379 -h 192.168.10.6
#验证密码
192.168.10.6:6379> auth psw66
OK
#关闭redis服务
192.168.10.6:6379> shutdown
#退出客户端
not connected> exit
[root@localhost bin]#

(2)关闭主节点之后,我们去查看哨兵日志:

[root@192 bin]# cat sentinel.log 
2352:X 12 Aug 2021 22:38:48.917 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2352:X 12 Aug 2021 22:38:48.917 # Redis version=6.2.4, bits=64, commit=00000000, modified=0, pid=2352, just started
2352:X 12 Aug 2021 22:38:48.917 # Configuration loaded
2352:X 12 Aug 2021 22:38:48.918 * Increased maximum number of open files to 10032 (it was originally set to 1024).
2352:X 12 Aug 2021 22:38:48.918 * monotonic clock: POSIX clock_gettime
2352:X 12 Aug 2021 22:38:48.919 * Running mode=sentinel, port=26380.
2352:X 12 Aug 2021 22:38:48.919  WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
2352:X 12 Aug 2021 22:38:48.930  Sentinel ID is 1c6eda14adbdc0e12688f41626353c3235e46e72
2352:X 12 Aug 2021 22:38:48.930  +monitor master mymaster 192.168.10.6 6379 quorum 2
2352:X 12 Aug 2021 22:38:48.931 * +slave slave 192.168.10.99:6379 192.168.10.99 6379 @ mymaster 192.168.10.6 6379   #从节点信息 从节点哨兵信息
2352:X 12 Aug 2021 22:38:48.938 * +slave slave 192.168.10.66:6379 192.168.10.66 6379 @ mymaster 192.168.10.6 6379 #从节点信息 从节点哨兵信息
2352:X 12 Aug 2021 22:38:49.057 * +sentinel sentinel 34f7b8efb06e45e3d2e7869dff5634e2cdba19e4 192.168.10.66 26380 @ mymaster 192.168.10.6 6379
2352:X 12 Aug 2021 22:38:55.439 * +sentinel sentinel 061a4011a57eac73fda058642336fe015b7fe1bc 192.168.10.99 26380 @ mymaster 192.168.10.6 6379
2352:X 12 Aug 2021 22:40:28.202  +sdown master mymaster 192.168.10.6 6379  #这里应该是发现主节点宕机
2352:X 12 Aug 2021 22:40:28.286  +new-epoch 1
2352:X 12 Aug 2021 22:40:28.292  +vote-for-leader 34f7b8efb06e45e3d2e7869dff5634e2cdba19e4 1
2352:X 12 Aug 2021 22:40:28.294  +odown master mymaster 192.168.10.6 6379 #quorum 3/2 两个哨兵都觉得主节点宕机了
2352:X 12 Aug 2021 22:40:28.294  Next failover delay: I will not start a failover before Thu Aug 12 22:46:29 2021
2352:X 12 Aug 2021 22:40:29.395 +config-update-from sentinel 34f7b8efb06e45e3d2e7869dff5634e2cdba19e4 192.168.10.66 26380 @ mymaster 192.168.10.6 6379
2352:X 12 Aug 2021 22:40:29.395  +switch-master mymaster 192.168.10.6 6379 192.168.10.99 6379 #通过投票选举10.99为新的主节点
2352:X 12 Aug 2021 22:40:29.398 * +slave slave 192.168.10.66:6379 192.168.10.66 6379 @ mymaster 192.168.10.99 6379
2352:X 12 Aug 2021 22:40:29.398 * +slave slave 192.168.10.6:6379 192.168.10.6 6379 @ mymaster 192.168.10.99 6379
2352:X 12 Aug 2021 22:40:32.451 +sdown slave 192.168.10.6:6379 192.168.10.6 6379 @ mymaster 192.168.10.99 6379

(3)下面我们去10.99下查看哨兵主从切换是否成功

[root@localhost bin]# redis-cli -p 6379 -h 192.168.10.99
192.168.10.99:6379> auth psw66
OK
192.168.10.99:6379> info replication
# Replication
role:master # 10.99变成主节点了
connected_slaves:1 # 下面的从机个数为1
slave0:ip=192.168.10.66,port=6379,state=online,offset=49933,lag=0
master_failover_state:no-failover
master_replid:5425eedab2bb409875e69f327d9d76ee65bc2363
master_replid2:0f7aed0b145677c90a04673d16196f199efe727c
master_repl_offset:49933
second_repl_offset:20459
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:49933

 (4)重新连接挂掉的主节点

[root@192 bin] redis-server redisConfig/redis.conf  #启动redis服务
[root@192 bin] redis-cli -p 6379 -h 192.168.10.6  #连接客户端
192.168.10.6:6379> auth psw66
OK
192.168.10.6:6379> info replication
# Replication
role:slave #主节点连接回来之后自动变成了从节点,并且成功连上了主机
master_host:192.168.10.99  #主机ip
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:185329
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:5425eedab2bb409875e69f327d9d76ee65bc2363
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:185329
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:179498
repl_backlog_histlen:5832

 (5)再去主节点确认一下

192.168.10.99:6379> info replication
# Replication
role:master
connected_slaves:2 #两个从节点
slave0:ip=192.168.10.66,port=6379,state=online,offset=186187,lag=1
slave1:ip=192.168.10.6,port=6379,state=online,offset=186609,lag=1
master_failover_state:no-failover
master_replid:5425eedab2bb409875e69f327d9d76ee65bc2363
master_replid2:0f7aed0b145677c90a04673d16196f199efe727c
master_repl_offset:186609
second_repl_offset:20459
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:186609

六、哨兵模式的优缺点
(1)优点

哨兵集群,基于主从复制模式,所有的主从配置优点,它全有

主从可以切换,故障可以转移,系统的可用性就会更好

哨兵模式就是主从模式的升级,手动到自动,更加健壮!

(2)缺点

Redis不好在线扩容,集群容量一旦到达上限,在线扩容就十分麻烦

哨兵模式的配置繁琐

(3)哨兵模式的配置文件详解

# Example sentinel.conf 
# 哨兵sentinel实例运行的端口 默认26379 
port 26379 

# 哨兵sentinel的工作目录 
dir /tmp 

# 哨兵sentinel监控的redis主节点的 ip port 
# master-name 可以自己命名的主节点名字 只能由字母A-z、数字0-9 、这三个字符".-_"组成。 
# quorum 配置多少个sentinel哨兵统一认为master主节点失联 那么这时客观上认为主节点失联了
# sentinel monitor <master-name> <ip> <redis-port> <quorum> 
sentinel monitor mymaster 127.0.0.1 6379 2 
 
# 当在Redis实例中开启了requirepass foobared 授权密码 这样所有连接Redis实例的客户端都要提供 密码
# 设置哨兵sentinel 连接主从的密码 注意必须为主从设置一样的验证密码 
# sentinel auth-pass <master-name> <password> 
sentinel auth-pass mymaster MySUPER--secret-0123passw0rd 

# 指定多少毫秒之后 主节点没有应答哨兵sentinel 此时 哨兵主观上认为主节点下线 默认30秒 
# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 30000 

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

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

# SCRIPTS EXECUTION
#配置当某一事件发生时所需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时发邮件通知 相关人员。
#对于脚本的运行结果有以下规则:
#若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10 
#若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。 
#如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同。 
#一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被一个SIGKILL信号终止,之后重新执行。 
#通知型脚本:当sentinel有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等等), 将会去调用这个脚本,这时这个脚本应该通过邮件,SMS等方式去通知系统管理员关于系统不正常运行的信 息。调用该脚本时,将传给脚本两个参数,一个是事件的类型,一个是事件的描述。如果sentinel.conf配 置文件中配置了这个脚本路径,那么必须保证这个脚本存在于这个路径,并且是可执行的,否则sentinel无 法正常启动成功。 
#通知脚本 
# shell编程 
# sentinel notification-script <master-name> <script-path> sentinel 
notification-script mymaster /var/redis/notify.sh

# 客户端重新配置主节点参数脚本 
# 当一个master由于failover而发生改变时,这个脚本将会被调用,通知相关的客户端关于master地址已 经发生改变的信息。 
# 以下参数将会在调用脚本时传给脚本: 
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port> # 目前<state>总是“failover”, 
# <role>是“leader”或者“observer”中的一个。 
# 参数 from-ip, from-port, to-ip, to-port是用来和旧的master和新的master(即旧的slave)通 信的# 这个脚本应该是通用的,能被多次调用,不是针对性的。 
# sentinel client-reconfig-script <master-name> <script-path> sentinel client-reconfig-
script mymaster /var/redis/reconfig.sh 

 有兴趣可以再去看一下redis的配置文件和哨兵的配置文件,你会惊讶的发现,里边的配置文件已经被改过来了。

四、踩坑总结

防火墙一定要关掉,或者是开放指定redis的端口
如果要用哨兵模式,redis.conf配置文件的主节点密码要和从节点密码一样,并且在主节点配置文件中也要配置主节点密码requirepass 和从节点密码masterauth (因为切换主机,好像不能自动配置密码,这样会导致宕机的主节点恢复之后,连接不上新的主节点。)。
哨兵配置文件里边的IP和端口为主节点的IP和端口
————————————————
版权声明:本文为CSDN博主「程序猿爱篮球」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Ever_Ardour/article/details/119547363

posted on 2023-02-21 11:12  大兄弟666  阅读(254)  评论(0编辑  收藏  举报