1. 概念
主从复制是将一台redis服务器(主节点-master)的数据,复制到其他的redis服务器(从节点-slave)。数据的复制是单向的,只能从主节点到从节点。Master以写为主,Slave以读为主。
默认情况下,每台redis服务器都是主节点,且一个主节点可以有多个从节点,但一个从节点只能有一个主机点。
2. 作用
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式;
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复,实际上是一种服务的冗余;
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个节点分担读负载,可以大大提高Redis服务器的并发量。
- 高可用:主从复制还是哨兵和集群能够实施的基础,因此主从复制是Redis高可用的基础;
3. 简单架构
一般来说,单台Redis最大使用内存不应该超过20G。
4. 搭建伪集群
1)查看集群信息
[root@192 bin]# redis-server dong_config/redis.conf
[root@192 bin]# redis-cli -p 6379
127.0.0.1:6379> info replication -----> 查看当前Redis信息
# Replication
role:master ---------------> 当前节点为主节点
connected_slaves:0 ---------------> 当前节点没有从节点
master_failover_state:no-failover
master_replid:558600754ee53f807b8161a8c1fe70af9ecd4c5f
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>
2)搭建伪集群
由于实际测试环境限制,在一台机器上搭建3个Redis服务。
a)创建三个配置文件
# 端口6379: redis6379.conf
# 端口6380: redis6380.conf
# 端口6381: redis6381.conf
[root@192 dong_config]# ls
redis6379.conf redis6380.conf redis6381.conf redis.conf
[root@192 dong_config]#
b)修改配置文件
# 修改1 ---------------> 修改对应端口
# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6379
#修改2 ---------------> 默认后台运行
# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
# When Redis is supervised by upstart or systemd, this parameter has no impact.
daemonize yes
#修改3 --------------> 修改pidfile
# If a pid file is specified, Redis writes it where specified at startup
# and removes it at exit.
#
# When the server runs non daemonized, no pid file is created if none is
# specified in the configuration. When the server is daemonized, the pid file
# is used even if not specified, defaulting to "/var/run/redis.pid".
#
# Creating a pid file is best effort: if Redis is not able to create it
# nothing bad happens, the server will start and run normally.
#
# Note that on modern Linux systems "/run/redis.pid" is more conforming
# and should be used instead.
pidfile /var/run/redis_6379.pid
#修改4 ---------------> 修改日志文件
# Specify the log file name. Also the empty string can be used to force
# Redis to log on the standard output. Note that if you use standard
# output for logging but daemonize, logs will be sent to /dev/null
logfile "6379.log"
#修改5 --------------修改dump6379.rdb
# Enables or disables full sanitation checks for ziplist and listpack etc when
# loading an RDB or RESTORE payload. This reduces the chances of a assertion or
# crash later on while processing commands.
# Options:
# no - Never perform full sanitation
# yes - Always perform full sanitation
# clients - Perform full sanitation only for user connections.
# Excludes: RDB files, RESTORE commands received from the master
# connection, and client connections which have the
# skip-sanitize-payload ACL flag.
# The default should be 'clients' but since it currently affects cluster
# resharding via MIGRATE, it is temporarily set to 'no' by default.
#
# sanitize-dump-payload no
# The filename where to dump the DB
dbfilename dump6379.rdb
c)启动3个Redis服务
[root@192 bin]# redis-server dong_config/redis6379.conf
[root@192 bin]# redis-server dong_config/redis6380.conf
[root@192 bin]# redis-server dong_config/redis6381.conf
[root@192 bin]# ps -ef | grep redis
root 1963 1 0 21:32 ? 00:00:00 redis-server 127.0.0.1:6379
root 1969 1 0 21:32 ? 00:00:00 redis-server 127.0.0.1:6380
root 1975 1 0 21:32 ? 00:00:00 redis-server 127.0.0.1:6381
root 1981 1764 0 21:32 pts/0 00:00:00 grep --color=auto redis
[root@192 bin]#
3)搭建一主二从集群
a)配置从机6380
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379 --------------> 设置主节点为6379
OK
127.0.0.1:6380> info replication
# Replication
role:slave --------------> 当前节点为从节点
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_read_repl_offset:0
slave_repl_offset:0
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:
master_replid2:
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:0
127.0.0.1:6380>
b)配置从机6381
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_read_repl_offset:98
slave_repl_offset:98
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:
master_replid2:
master_repl_offset:98
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:99
repl_backlog_histlen:0
127.0.0.1:6381>
c)查看6379节点
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2 ----------------------> 存在两个从节点
slave0:ip=127.0.0.1,port=6380,state=online,offset=238,lag=0 -----> 从节点1
slave1:ip=127.0.0.1,port=6381,state=online,offset=238,lag=0 -----> 从节点2
master_failover_state:no-failover
master_replid:
master_replid2:
master_repl_offset:238
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:238
127.0.0.1:6379>
d)永久配置主从机关系
################################# REPLICATION #################################
# Master-Replica replication. Use replicaof to make a Redis instance a copy of
# another Redis server. A few things to understand ASAP about Redis replication.
#
# +------------------+ +---------------+
# | Master | ---> | Replica |
# | (receive writes) | | (exact copy) |
# +------------------+ +---------------+
#
# 1) Redis replication is asynchronous, but you can configure a master to
# stop accepting writes if it appears to be not connected with at least
# a given number of replicas.
# 2) Redis replicas are able to perform a partial resynchronization with the
# master if the replication link is lost for a relatively small amount of
# time. You may want to configure the replication backlog size (see the next
# sections of this file) with a sensible value depending on your needs.
# 3) Replication is automatic and does not need user intervention. After a
# network partition replicas automatically try to reconnect to masters
# and resynchronize with them.
#
# replicaof <masterip> <masterport> --------------> 此处配置主机ip和端口
5. 主从机节点关系
- 主机中所有信息和数据,都会被从机保存;
- 主机可以写,从机中不能写;
127.0.0.1:6380> set k2 2
(error) READONLY You can't write against a read only replica.
127.0.0.1:6380>
6. 复制原理
Slave启动成功连接到Master后会发送一个sync同步命令。
Master接到命令后,启动后台的存盘进程,同时收集所有接收到的用于修改数据的命令,在后台进行执行完毕之后,Master将传送整个数据文件到Slave,完成一次完全同步。
- 全量复制:Slave服务在接收到数据库文件数据后,将其存盘并加载到内存中;
- 增量复制:Master继续将新的所有收集到的修改命令依次传给Slave,完成同步;
只要重新连接Master,一次完全同步(全量复制)将被自动执行。