如何搭建Redis集群(主从+哨兵)
一、什么是redis主从复制?
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。master以写为主,slave以读为主。
二、主从复制的作用
数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
读写分离:可以用于实现读写分离,主库写、从库读,读写分离不仅可以提高服务器的负载能力,同时可根据需求的变化,改变从库的数量;
高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
三、实现主从复制
1、环境准备
先准备三台服务器,并安装好redis服务,具体步骤可参考Centos下安装redis
注意:
我们需要设置一下防火墙,否则主从机之间无法同步数据,命令如下,这里根据自己设置的端口进行更改。或者关闭防火墙也可以
1 2 3 4 5 6 7 8 9 | #开放6379端口 firewall-cmd --add-port=6379 /tcp --permanent --zone=public #重启防火墙(修改配置后要重启防火墙) firewall-cmd --reload #查看防火墙命令 systemctl status firewalld.service #关闭防火墙命令 重启虚拟机防火墙会重新打开 systemctl stop firewalld.service |
2、redis环境配置
1 2 3 4 5 6 7 8 9 10 11 | #修改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服务
1 2 3 4 | 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
命令查看当前主从配置
从节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 |
主节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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、主节点
1 2 | 192.168.10.6:6379> set k1 v1 OK |
2、从节点
1 2 3 4 | 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、搭建哨兵
在每台服务器上部署一个哨兵,配置方式如下:
1 2 | #在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、分别启动三台服务器上的哨兵
1 2 | #启动哨兵命令 分别在三台服务器上启动各自的哨兵 redis-sentinel redisConfig /sentinel .conf |
1 2 3 4 5 6 7 8 9 10 11 12 | #连接客户端 [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 | (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)关闭主节点之后,我们去查看哨兵日志:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | [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下查看哨兵主从切换是否成功
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | [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)重新连接挂掉的主节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | [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)再去主节点确认一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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)哨兵模式的配置文件详解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | # 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构