目录
从官网上可以总结出一句话,"主从复制,master 以写为主,slave 以读为主,当 master 数据发生变化之后,自动将新的数据异步同步到其他 salve 数据库"。
严格意义上来说,现在的 Redis 已经不是单线程了,但是 Redis 的读写数据操作仍然是基于内存的单线程的,在同一时刻只能读或着写,那么它就一定会有一个上线,如果我们的用户业务需求量过于庞大,一台 Redis 很有可能是支持不过来的,所以我们就需要多配备几台 Redis 服务器,像 MySQL 一样,进行分库分表读写分离设置集群,主 Redis 服务器用于写数据,也可以读操作,但以写数据为主,从 Redis 服务器用于读数据,减轻了主 Redis 服务器读数据的访问压力。
Redis 是基于内存存储的数据库,如果我们的业务只设置一台 Redis 服务器,一旦 Redis 服务器发生故障宕机了,短时间内又无法马上恢复正常,那么所有的数据访问都会直接打到 MySQL,MySQL肯定是承受不了巨大的访问量的,也会接连宕机,造成其它业务接连崩溃,对我们的业务造成巨大的损失。所以设置多台 Redis 服务器,就可以保证其中某台 Redis 服务器宕机之后,业务不会受到很大的影响,保证业务的正常运行。
从服务器的数据是从主服务器读取过来的,就算主服务器挂了,从服务器中的数据也和主服务器中的数据基本一致,不会对查询业务造成很大的影响,但会对写数据业务造成影响,但是客户端一般查询请求非常非常多,所以不会对业务造成很大影响。所以不管是大企业或是小企业,一般都会配备至少两到三台 Redis 服务器, 一台服务器挂了,我还有替补不至于服务崩溃。
我们设置多台服务器之后,大量用户的访问需求就可以均匀分布在多台服务器上,极大的提高了业务的并发能力。
很好理解,就是你想让谁当从库,就对谁进行配置,想让谁当主库,不做配置即可。
一般来说,我们的 Redis 数据库都会设置密码,如果设置了密码,那么在从数据库的配置文件中,就需要配置 masterauth 配置项配置主数据库的密码。如果不进行配置,那么从库在访问主库数据的时候就会被拒绝访问。
info replication:可以查看复制节点的主从关系配置信息;
replicaof:配置主机的IP和端口,要写入到 redis.conf 配置文件内,此项不是命令;
slaveof:修改另一台以及作为自己的主机,配置主机IP和端口,在服务器运行期间加入到 redis.conf 配置文件中;
slaveof no one:自己独立,不与其他服务器产生关联,自己就是主机;
下面是动手自己建立一个 Redis 主从服务器,有条件的同学可以跟着我一起做,或者看一遍也可以,实际面试的时候一般也不会让你动手做,但其中的命令还是要记住的哦。
这里我给大家简单演示一下主从复制如何做,我使用两台 Redis 服务器,一个是我本地电脑 vmweare 虚拟机上的 Redis 服务器,另一个是我阿里云服务器上的 Redis 服务器,我将阿里云服务器上的 Redis 作为主数据库服务器,我本地电脑虚拟机上的 Redis 数据库作为从数据库服务器。
注意点一:我们再启动 Redis 服务器之前,要先把各项配置配置完毕之后再启动,在这里的话我就是在从服务器的配置文件中做配置即可;
注意点二:建议先启动主服务器,然后再启动从服务器;
如下图,使用 vim 指令对从数据库服务器做一下修改,添加上主Redis数据库服务器的IP和端口,并配置上 masterauth 密码,masterauth 就是我们主数据库服务器的密码,有了密码从服务器才有权限进行访问,不配置密码会被拒绝访问。
121.41.67.181 是我的云服务器IP地址,6379 就是 Redis 服务器的端口。

因为我之前就已经配置过了,所以就不重复演示了,界面如下,就表示开放 6379 端口成功;

上述一切都准备就绪之后,就可以开始启动了服务器了,先在电脑上打开 FinalShell 远程连接工具,连接上阿里云服务器,由于我的云服务器一起都是处于运行状态,Redis 也是一直处于运行状态,就不重新启动了,如下图

命令也没什么难度,就是一个查看运行状态和打开客户端命令界面
- // 查看 Redis 运行状态 Active 为 active 表示正在运行
- [root@iZbp14kue6pz0ps43izpczZ ~]# systemctl status redis
- ● redis.service - LSB: starts Redis
- Loaded: loaded (/etc/rc.d/init.d/redis; bad; vendor preset: disabled)
- Active: active (exited) since 二 2023-10-17 15:47:48 CST; 19min ago
- Docs: man:systemd-sysv-generator(8)
- Process: 1101 ExecStop=/etc/rc.d/init.d/redis stop (code=exited, status=0/SUCCESS)
- Process: 1474 ExecStart=/etc/rc.d/init.d/redis start (code=exited, status=0/SUCCESS)
-
- 10月 17 15:47:48 iZbp14kue6pz0ps43izpczZ systemd[1]: Starting LSB: starts Redis...
- 10月 17 15:47:48 iZbp14kue6pz0ps43izpczZ redis[1474]: Starting redis server...
- 10月 17 15:47:48 iZbp14kue6pz0ps43izpczZ sudo[1491]: root : TTY=unknown ; PWD=/ ; USER=redis ; COMMAND=/www/server/redis/src/redis-server /www/server/redis/redis.conf
- 10月 17 15:47:48 iZbp14kue6pz0ps43izpczZ systemd[1]: Started LSB: starts Redis.
- 10月 17 15:47:48 iZbp14kue6pz0ps43izpczZ redis[1474]: Starting redis success!
- [root@iZbp14kue6pz0ps43izpczZ ~]#
- [root@iZbp14kue6pz0ps43izpczZ ~]#
-
- // redis-cli 打开客户端命令界面, -a 加上密码 -p 表示指定的端口
- [root@iZbp14kue6pz0ps43izpczZ ~]# redis-cli -a 123456 -p 6379
-
- // 此处警告不需要关心,只是告诉我们直接把命令显示在界面不安全
- Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
-
- // 如下就已经说明正常打开了 Redis 的客户端命令界面
- 127.0.0.1:6379>
以下为打开 vmweare 虚拟机中后我所做的一些操作,如下图,下面有命令

方便各位阅读,我将命令都复制到下面来了,各位同学可以简单看一下,我做了注释也不难理解,到了这一步,虚拟机的 Redis 服务器和连接环境说明已经没有大问题了。
- // 关闭虚拟机防火墙,以便后续可以被外界访问
- [zhangsir@localhost ~]$ systemctl stop firewalld
-
- // 查看虚拟机防火墙状态,Active 为 dead 表示现在处于关闭状态
- [zhangsir@localhost ~]$ systemctl status firewalld
- ● firewalld.service - firewalld - dynamic firewall daemon
- Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
- Active: inactive (dead) since Tue 2023-10-17 11:26:08 CST; 10s ago
- Docs: man:firewalld(1)
- Process: 6547 ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS (code=exited, status=0/SUCCESS)
- Main PID: 6547 (code=exited, status=0/SUCCESS)
- [zhangsir@localhost ~]$
-
- // 通过 redis6.conf 配置文件启动 redis
- [zhangsir@localhost ~]$ redis-server /myredis/redis6.conf
- [zhangsir@localhost ~]$
-
- // 启动后查看启动状态,Active 为 active 表示已经启动成功
- [zhangsir@localhost ~]$ systemctl status redis
- ● redis.service - redis-server
- Loaded: loaded (/etc/systemd/system/redis.service; enabled; vendor preset: disabled)
- Active: active (running) since Tue 2023-10-17 11:13:56 CST; 13min ago
- Process: 7014 ExecStart=/usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.conf (code=exited, status=0/SUCCESS)
- Main PID: 7082 (redis-server)
- Tasks: 5
- CGroup: /system.slice/redis.service
- └─7082 /usr/local/bin/redis-server 0.0.0.0:6379
- [zhangsir@localhost ~]$
- [zhangsir@localhost ~]$
-
- // 测试与云服务器的连接是否成功,这里可以看到连接一切正常
- [zhangsir@localhost ~]$ ping 121.41.67.181
- PING 121.41.67.181 (121.41.67.181) 56(84) bytes of data.
- 64 bytes from 121.41.67.181: icmp_seq=1 ttl=128 time=26.8 ms
- 64 bytes from 121.41.67.181: icmp_seq=2 ttl=128 time=23.2 ms
- 64 bytes from 121.41.67.181: icmp_seq=3 ttl=128 time=21.0 ms
- 64 bytes from 121.41.67.181: icmp_seq=4 ttl=128 time=21.1 ms
- 64 bytes from 121.41.67.181: icmp_seq=5 ttl=128 time=22.6 ms
- 64 bytes from 121.41.67.181: icmp_seq=6 ttl=128 time=24.0 ms
- 64 bytes from 121.41.67.181: icmp_seq=7 ttl=128 time=29.4 ms
- 64 bytes from 121.41.67.181: icmp_seq=8 ttl=128 time=24.7 ms
- 64 bytes from 121.41.67.181: icmp_seq=9 ttl=128 time=22.4 ms
- 64 bytes from 121.41.67.181: icmp_seq=10 ttl=128 time=23.1 ms
主从服务器都运行就绪之后,我们打开从服务器的客户端命令界面,输入 info replication 命令即可查看主从关系配置信息;
- // 通过 redis-cli 命令即可打开客户端界面,-a 指定密码,-p指定端口
- [root@localhost ~]# redis-cli -a 123456 -p 6379
- Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
- 127.0.0.1:6379> info replication
-
- // 这里可以看到它输出了很多信息,我们姑且不看那么多,只看前三行
- // role:slave 表示当前节点是从节点
- // master_host:121.41.67.181 表示主服务器的 IP地址
- // master_port:6379 表示主服务器的端口号
- # Replication
- role:slave
- master_host:121.41.67.181
- master_port:6379
- master_link_status:down
- master_last_io_seconds_ago:-1
- master_sync_in_progress:1
- slave_read_repl_offset:1
- slave_repl_offset:1
- master_sync_total_bytes:-1
- master_sync_read_bytes:0
- master_sync_left_bytes:-1
- master_sync_perc:-0.00
- master_sync_last_io_seconds_ago:0
- master_link_down_since_seconds:-1
- slave_priority:100
- slave_read_only:1
- replica_announced:1
- connected_slaves:0
- master_failover_state:no-failover
- master_replid:4fb057dae9e8d87e21976a97681fec1738d41367
- master_replid2:0000000000000000000000000000000000000000
- master_repl_offset:0
- second_repl_offset:-1
- repl_backlog_active:0
- repl_backlog_size:1048576
- repl_backlog_first_byte_offset:0
- repl_backlog_histlen:0
- 127.0.0.1:6379>
由于没有第三个服务器,我这里就不做额外的演示了,但我给大家解释一下它的作用。
slaveof:它的作用是更改另一台服务器作为自己的主服务器。但有两个前提要求,第一:当前从服务器配置文件内必须有要更改的主服务器的密码;第二:要把配置文件内执勤的从服务器IP和端口注释掉。
举个最简单的例子,现在我的A服务器是主服务器,B服务器是从服务器,B服务器想要通过 slaveof 更改原来的A主服务器变成C主服务器,就需要把自身配置文件内关于A服务器的IP地址和端口号注释或删除,并且C服务器的密码必须和A服务器的密码保持一致或者把密码更改为C服务器的密码,否则C服务器会拒绝访问。而且还有一点要注意!!!slaveof 命令是一次性的命令,也就是说,如果我们删除了配置文件中关于主服务器的IP和端口号,那么下次在重启B服务器的时候,B服务器就会变成一个独立的 master ,自立为王,不再是其他主数据库服务器的小弟。
slaveof no one 命令可以让当前节点脱离主服务器变成独立的服务器,如下,我在刚才的虚拟机从服务器的中执行 slaveof no one 命令,在执行 info replication 命令查看,可以发现刚才作为从服务器的的数据库现在自己变成了 master。
- // 执行 slaveof no one 命令
- 127.0.0.1:6379> slaveof no one
- OK
-
- 127.0.0.1:6379> info replication
- # Replication
- role:master // master 表示自己就是主服务器
- connected_slaves:0
- master_failover_state:no-failover
- master_replid:1d611a4e5bebd42d9b084ac13e3f1cc14b033bb1
- master_replid2:4fb057dae9e8d87e21976a97681fec1738d41367
- master_repl_offset:0
- second_repl_offset:1
- repl_backlog_active:0
- repl_backlog_size:1048576
- repl_backlog_first_byte_offset:0
- repl_backlog_histlen:0
- 127.0.0.1:6379>
(1)从服务器首次启动之后,会向主服务器发送一个 sync 同步命令请求,在首次连接 master 时,会一次性完全同步 master 上的数据,slave 从服务器上的数据就会被主服务器上的数据覆盖清除。
(2)主服务器会受到同步请求,会保存快照,生成一个RDB快照文件(即RDB持久化,主从复制时会发生RDB),同时将所有接收到的修改数据的命令缓存起来一起生成RDB文件,然后 master 会将RDB文件发送给 slave 从服务器,slave 在接收到RDB文件之后,会存盘并加载到内存,从而完成数据的同步化。
(3)从服务器在同步主服务器上存储的所有数据之后,主服务器写入一个数据,从服务器跟一个;
(4)就算从服务器宕机了,我们再次重启从服务器之后,从服务器上的数据仍然能与主服务器上的数据保持同步,原理是依据偏移量 offset,主从服务器都会有一个 offset,保存在 backlog 包中,在从机重新启动之后,mster 会把已经复制的 offset 赋值给 slave 让从机同步数据,但只能同步已经复制过的 offset ,类似于断点续传;
(5)只有主服务器拥有读和写的权限,从服务器只有读的权限而不能写数据;
(6)主从服务器之间每隔 10s 会发送一次ping心跳包来确保其他从服务器是否还在正常运行;
(7)如果主服务器宕机了,从服务器不会自动晋升为主服务器,而是会一直等待主服务器恢复正常;
(1)复制延时,信号衰减。在高并发的场景下,一主二从是不太够用的,而只有主服务器具有写操作,再同步到其他从服务器,所以从机变得更多,就会导致复制会发生延时,信号衰减;
(2)master 主机挂了会很麻烦。因为主机挂了之后从机不会上位替代主机,而是会一直等待主机恢复正常,这样就会导致写数据操作的业务面临中断。所以,我们就需要用到哨兵,时刻监控 master 主机的健康状态,如果 master 出现了故障,马上选取一个新的 master 继续对外服务,保证业务安全运行。
redis 哨兵我单独开了一篇文章,有兴趣的小伙伴可以跳转观看哦。