redis主从复制原理
小码今天去面试。
面试官:给我介绍一下Redis
集群,
小码:啊,平时开发用的都是单机Redis
,没怎么用过集群了。
面试官:好的,出门右转不谢。
小码内心困惑:在小公司业务量也不大,单机的 Redis
完全够用,也不会发生宕机问题啊。面试要问到 Redis 集群该怎么办呢?
Redis 为何要有集群
很多小伙伴也有类似的困惑,自己的公司并不大。并发量、访问量要求不高,使用单机 Redis 就能很好的解决数据请求的问题。为啥要使用集群呢?
对于访问量小、并发低的系统,对数据的高可用要求不高的数据,单机部署都能满足需求。但是在大公司,随便一个系统的QPS
都是成千上万,对系统的高可用、高并发要求比较高,这个时候就需要要使用Redis
集群模式了,Redis
有三种集群模式:
- 主从复制模式
- 哨兵模式
- Cluster 模式
主从复制模式
Redis
想要不丢失数据,就需要开始持久化,数据会写入到磁盘中,这样即使服务关闭再重启服务器后,数据也能从硬盘加载到内存中。但是如果服务器的硬盘出现故障,也会导致数据丢失。
为了避免硬盘故障问题,需要将数据复制在多个副本上,这样即使一个服务出现故障,其他服务器也能提供数据服务。
Redis
提供了主从模式,一个主数据库master
绑定多个从数据库slave
:
主数据可以读和写,从数据库一般是只读,主从库之间采用读写分离,主数据库数据更新后同步复制给绑定的从数据库,主从数据库的数据保持一致:
数据主从同步原理
- 从数据库启动后,连接主数据库,发送
SYNC
命令。 - 主数据库接收到SYNC命令后,开始执行
BGSAVE
命令生成RDB
文件并使用缓冲区记录后面执行的所有写命令。 - 主数据库执行完
BGSAVE
命令之后,向所有从数据库发送RDB
文件。从数据库加载RDB
文件。 - 主数据将记录的缓存区所有的写命令发送给从数据库,从数据库执行命令。
SYNC
每次从服务重启,都会请求所有的数据。如果服务宕机再重启还是同步所有的数据,就会造成资源的浪费,所以有了PSYNC
命令,PSYNC
有完整同步和部分同步,其中完整同步和SYNC
一致,而部分同步是根据数据偏移量复制数据。
主从复制服务搭建
Redis
单机搭建可以查看前面写的的教程
Centos安装单机Redis
首先创建三个文件夹6380、6381、6382
:
mkdir 6380
mkdir 6381
mkdir 6382
复制redis.conf
到这三个文件夹里:
cp redis.conf 6380/
cp redis.conf 6381/
cp redis.conf 6382/
配置一主两从,6380
为主,6381、6382
为从。然后修改redis.conf
文件:
参数 | maser (6380) | slave1 (6381) | slave2 (6382) |
---|---|---|---|
port | 6380 | 6381 | 6382 |
requirepass | requirepass "xxxx" | requirepass "xxxx" | requirepass "xxxx" |
slaveof | slaveof 本机ip 6380 | slaveof 本机ip 6380 | |
masterauth | masterauth ”xxx“ | masterauth ”xxx“ | |
pidfile | pidfile /redis_6380.pid | pidfile /redis_6381.pid | pidfile /redis_6382.pid |
logfile | logfile "redis_6380.log" | logfile "redis_6381.log" | logfile "redis_6382.log" |
设置了requirepass
,就需要设置masterauth
,三台服务器的密码需要一致。
启动服务器:
[root@instance-3 redis]# bin/redis-server 6380/redis.conf
[root@instance-3 redis]# bin/redis-server 6381/redis.conf
[root@instance-3 redis]# bin/redis-server 6382/redis.conf
然后查看进程,如果有以下的显示,说明启动成功了:
[root@instance-3 redis]# ps -ef |grep redis
root 6652 1 0 16:28 ? 00:00:00 bin/redis-server *:6380
root 6665 1 0 16:28 ? 00:00:00 bin/redis-server *:6381
root 6682 1 0 16:28 ? 00:00:00 bin/redis-server *:6382
root 7188 4291 0 16:30 pts/0 00:00:00 grep --color=auto redis
进入Redis
客户端,使用info replication
命令查看数据库的信息。
master 6380:
[root@instance-3 redis]# bin/redis-cli -p 6380
127.0.0.1:6380> auth xxxx
OK
127.0.0.1:6380> info replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=42,lag=0
slave1:ip=127.0.0.1,port=6382,state=online,offset=42,lag=1
master_replid:19ca382e3c05014988002a295078687dae9bb92e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:42
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:42
role:master
表示 6380 是主服务器,slave0
和salve1
表示绑定的从服务器。
slave 6381:
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_repl_offset:126
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:19ca382e3c05014988002a295078687dae9bb92e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:126
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:126
role:slave
表示 6381 是从服务器,master_host
和master_port
表示绑定对应的主服务器。
slave 6382:
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:476
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:19ca382e3c05014988002a295078687dae9bb92e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:476
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:476
role:slave
表示 6382 是从服务器,master_host
和master_port
表示绑定对应的主服务器。
主服务器添加数据,再从从服务器获取数据。
6380
服务器添加数据:
127.0.0.1:6380> set name jeremy
OK
6381
服务器获取数据:
127.0.0.1:6381> get name
"jeremy"
经过以上测试,说明主服务器的数据,从服务器也能同步获取。主从服务都搭建成功。
总结
- 主从模式: 单机宕机或者磁盘出现故障,会导致数据丢失,主从模式将数据复制给多个从服务器上,即使一台数据库宕机了,其他数据也能正常提供数据。主从模式有一台主数据库,多台从数据库的模式。客户端对主数据库进行读写,从数据库只能读操作。启动主从数据库之后,从数据库发送
SYNC
- 同步命令给主数据库,主数据库接收到命令之后,生成
RDB
- 文件。并且使用缓冲区记录所有写命令。写完毕后发送
RDB
- 文件给每个从数据库解析,以及发送缓存写命名给所以从数据库执行。主数据库更新数据后,数据会同步更新到从数据库中。主从模式实现了简单的可用,但是如果主数据库宕机了,手动切换主数据库比较费力,就有了哨兵模式。