Cluster-主从模式
# 主从同步
# Stand-alone Deployment Problem
单机部署简单,但是可靠性低,且不能很好利用CPU多核处理能力。生产环境必须要保证高可用,一般不可能单机部署。读写分离适用于可用性要求不高、性能要求较高、数据规模小的情况。也是最简单的分布式模型
# 用途
- 读写分离:扩展主节点的读能力,分担主节点读压力。
- 容灾恢复:一旦主节点宕机,手动将从节点提升为主节点顶上。
# Redis一键安装脚本
yum install -y gcc-c++ autoconf automake
cd /usr/local/
wget http://download.redis.io/redis-stable.tar.gz
tar xvzf redis-stable.tar.gz
cd redis-stable
make
echo "redis installed"
firewall-cmd --zone=public --add-port=6379/tcp --permanent
firewall-cmd --reload
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 一主两从部署方案
必须使用给定的 config 去启动对应的服务
- Master(192.168.31.102) redis-master.conf
sudo tee /usr/local/redis-stable/redis-master.conf <<-'EOF'
bind * -::*
port 6379
daemonize yes
logfile ./master.log
dir ./
dbfilename "master.rdb"
requirepass "123456"
appendonly yes
appendfilename "master.aof"
masterauth "123456"
EOF
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
masterauth
是指从服务器连接到主服务器时认证使用的密码。
cd /usr/local/redis-stable
./src/redis-server ./redis-master.conf
1
2
2
- Slave1(192.168.31.103) redis-slave1.conf
sudo tee /usr/local/redis-stable/redis-slave1.conf <<-'EOF'
bind * -::*
port 6379
daemonize yes
logfile ./slave1.log
dir ./
dbfilename "slave1.rdb"
requirepass "123456"
appendonly yes
appendfilename "slave1.aof"
replicaof 192.168.31.102 6379
masterauth "123456"
replica-read-only yes
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
replicaof 192.168.31.102 6379
- 设置主服务器IP与通信端口;masterauth "123456"
- 与主服务器通信时的密码;replica-read-only yes
- 从节点只读。
cd /usr/local/redis-stable
./src/redis-server ./redis-slave1.conf
1
2
2
- Slave2(192.168.31.104) redis-slave2.conf
sudo tee /usr/local/redis-stable/redis-slave2.conf <<-'EOF'
bind * -::*
port 6379
daemonize yes
logfile ./slave2.log
dir ./
dbfilename "slave2.rdb"
requirepass "123456"
appendonly yes
appendfilename "slave2.aof"
replicaof 192.168.31.102 6379
masterauth "123456"
replica-read-only yes
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
cd /usr/local/redis-stable
./src/redis-server ./redis-slave2.conf
1
2
2
# 主从同步原理
主从复制类型
- 主从刚连接的时候,进行全量同步。
- 全同步结束后,进行增量同步。
全量复制
- master服务器会开启一个后台进程,用于将redis中的数据生成一个rdb文件。主服务器会缓存所有接收到的来自客户端的写命令,当后台保存进程处理完毕后,会将该rdb文件传递给slave服务器。
- slave服务器会将rdb文件保存在磁盘,并通过读取该文件将数据加载到内存。在此之后,master服务器会将在此期间缓存的命令通过redis传输协议发送给slave服务器。
- 然后slave服务器将这些命令依次作用于自己本地的数据集上,最终达到数据的一致性。
全量复制流程【这张图很重要】
- Master请求全量同步sync给Slave。
- Master执行bgsave。
- Master回传RDB给Slave。
- Slave加载RDB到内存。
- Master将后续指令写入buff。
- Master回传指令,Slave重现操作。
增量复制:Slave初始化后开始正常工作时,主服务器发生的写操作同步到从服务器的过程。主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。【这张图很重要】
全量/增量特点
- 主从复制对于主/从redis服务器来说是非阻塞的,所以同步期间都可以正常处理外界请求。
- 一个主redis可以含有多个从redis,每个从redis可以接收来自其他从redis服务器的连接。
- 从节点不会让key过期,而是主节点的key过期删除后,成为del命令传输到从节点进行删除。
加速复制(基本不用,极大降低可用性)
- 完全重新同步需要在磁盘上创建一个RDB文件,然后加载这个文件以便为从服务器发送数据。在比较低速的磁盘,这种操作会给主服务器带来较大的压力。
- 新版支持无磁盘的复制,子进程直接将RDB通过网络发送给从服务器,不使用磁盘作为中间存储。配置项为
repl-diskless-sync no
。 - 使用无盘复制会降低可靠性,了解下即可。
主从断开重连:如果遭遇连接断开,重新连接之后可以从中断处继续进行复制,而不必重新同步。2.8版本后部分重新同步这个新特性内部使用PSYNC命令,根据偏移量去计算当前同步的进度到哪里了,旧的实现中使用SYNC命令。
# 替代版本
docker-compose.yml
简单测试使用,禁止生产使用下面内容!!!
version: '3'
services:
master:
image: redis:7.0-alpine
command: redis-server --appendonly yes
ports:
- "6379:6379"
networks:
- redis-net
volumes:
- ./master-data:/data
slave1:
image: redis:7.0-alpine
command: redis-server --appendonly yes --replicaof master 6379
ports:
- "6380:6379"
networks:
- redis-net
volumes:
- ./slave1-data:/data
slave2:
image: redis:7.0-alpine
command: redis-server --appendonly yes --replicaof master 6379
ports:
- "6381:6379"
networks:
- redis-net
volumes:
- ./slave2-data:/data
networks:
redis-net:
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
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
root@VM-16-14-ubuntu:/home/ubuntu# docker exec redis-slave2-1 redis-cli set test_key "hello"
READONLY You can't write against a read only replica.
root@VM-16-14-ubuntu:/home/ubuntu# docker exec redis-master-1 redis-cli set test "hello"
OK
root@VM-16-14-ubuntu:/home/ubuntu# docker exec redis-master-1 redis-cli get test
hello
root@VM-16-14-ubuntu:/home/ubuntu# docker exec redis-slave2-1 redis-cli get test
hello
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
完善页面 (opens new window)