Redis进阶:主从复制
1简介
1.1问题及需求
如下图,当前的三个redis节点实例无法做到高可用,一旦有一台redis服务器宕机之后,那么缓存在这台服务器上的数据就不能使用缓存来获取,还会直接访问数据库,访问请求达到一定数量就会产生雪崩。
对于当前的redis集群架构,需要引入高可用的技术。
高可用架构引入主从复制和主从替换的技术,当某一个主节点宕机或通信不可达的时候,从节点自动顶替完成主节点的功能。架构结构如下图:
1.2CAP理论
CAP理论(CAP theorem),又被称作布鲁尔定律(Brewer’s theorem),是分布式集群中的一个重要理论(面试题)。
- C:consistency(一致性)
- A:avalibility(可用性)
- P:partition(分区)-tolenrence to partition(分区容忍度)
随着数据量增长需求,业务的多元化,分布式结构不可或缺。CAP理论是分布式集群中的基础理论之一。
1.2.1分区
一个分布式系统中,多个系统组成的网络本来是互通的,但是可能因为某种原因导致两个或多个节点间的数据通信断开,整个系统的整体被分割成了若干个区域的过程,叫做分布式系统的分区(分区是常态)。一旦分区出现,数据的修改和查询将受到影响,需要考虑数据一致性。
1.2.2一致性
数据在某个查看的时间点上保持整体一致。如果在数据修改时,对于查看数据的客户端要求数据一致,则必须加锁,实现整体一致性。在修改时,如果要求数据一致性,客户端将在加锁的时间段内不能访问数据,会导致可用性的降低。
1.2.3可用性
客户端的请求在一定时间段内都有回应。
1.2.4分区容忍度
在分区出现的情况下,如果对数据的一致性要求较高,分区容忍度高。如果在分区出现的情况下,对数据的一致性要求低,分区容忍度低。
1.2.5CAP理论的结论
在分布式集群中,只可能同时满足CAP理论中的2个条件
- CA--无分区,数据一致性可达。
- CP--数据一致性要求高的分区状态。
- AP--数据一致性要求低的分区状态(不加锁,可用性提高)。
分布式集群中的CAP理论可以理解为:分区是常态,要求数据一致性会导致可以用性降低;可用性提高,数据一致性就会降低。
两个CP 和 AP的现实场景:
- 1.支付:需要第三方平台的数据必须和银行一致(支付宝,银行)。
- 2.抢票:前台的订单下发,但是后台的数据库数据未必立刻修改。
2主从复制结构
redis中可以提供主从复制的结构,master-slave,可以多级复制,如下图:
根据企业的运维经验:主从结构最多2级主从,每个主节点最多6个从节点,否则会导致主从结构不稳定。
3主从复制搭建步骤
3.1移动目录
将redis主要的文件放入/usr/local/bin目录下,这样就可以在全局下使用redis的命令了,操作如下:
代码语言:javascript复制[root@lk7 bin]# cd /home/software/redis-6.2.6/src/
[root@lk7 src]# cp redis-server /usr/local/bin/
[root@lk7 src]# cp redis-cli /usr/local/bin/
[root@lk7 src]# cp redis-sentinel /usr/local/bin/
[root@lk7 src]# cp redis-check-aof /usr/local/bin/
[root@lk7 src]# cp redis-check-rdb /usr/local/bin/
[root@lk7 src]# cp redis-benchmark /usr/local/bin/
[root@lk7 src]# cd ..
[root@lk7 redis-6.2.6]# cp redis.conf /usr/local/bin/
3.2准备配置文件
准备主从节点的配置文件:复制redis.conf文件,并改名为需要的文件名。
代码语言:javascript复制[root@lk7 redis-6.2.6]# cd /usr/local/bin/
[root@lk7 bin]# cp redis.conf masterslave01.conf
[root@lk7 bin]# cp redis.conf masterslave02.conf
[root@lk7 bin]# cp redis.conf masterslave03.conf
[root@lk7 bin]# ll
总用量 47176
-rw-r--r--. 1 root root 93738 2月 6 18:41 masterslave01.conf
-rw-r--r--. 1 root root 93738 2月 6 18:41 masterslave02.conf
-rw-r--r--. 1 root root 93738 2月 6 18:41 masterslave03.conf
-rwxr-xr-x. 1 root root 4830496 1月 2 14:10 redis-benchmark
-rwxr-xr-x. 1 root root 9521744 1月 2 14:09 redis-check-aof
-rwxr-xr-x. 1 root root 9521744 1月 2 14:09 redis-check-rdb
-rwxr-xr-x. 1 root root 5004832 1月 2 14:08 redis-cli
-rw-r--r--. 1 root root 93738 2月 6 18:39 redis.conf
-rwxr-xr-x. 1 root root 9521744 1月 2 14:08 redis-sentinel
-rwxr-xr-x. 1 root root 9521744 1月 2 14:08 redis-server
3.3编辑配置文件
配置文件需要修改的内容如下:
- bind:注释掉
- port:分别将多个redis.conf文件中的端口修改成自己定义的端口号,这里使用6381、6382、6383。
- protected-mode no
- daemonize yes
- pid文件名称根据端口修改。
例如:
代码语言:javascript复制 75 #bind 127.0.0.1 -::1
94 protected-mode no
98 port 6381
257 daemonize yes
289 pidfile /var/run/redis_6381.pid
另外两个配置文件按照这个修改即可。
3.4启动redis服务
分别启动对应文件的redis服务,命令如下:
代码语言:javascript复制redis-server 文件名
启动服务如下:
代码语言:javascript复制[root@lk7 bin]# redis-server masterslave01.conf
[root@lk7 bin]# redis-server masterslave02.conf
[root@lk7 bin]# redis-server masterslave03.conf
[root@lk7 bin]#
3.5查看状态信息
首先进入redis客户端,进入客户端的命令如下:
代码语言:javascript复制# 查看帮助信息
redis-cli --help
# 使用端口登录
redis-cli -p port
登录操作如下:
代码语言:javascript复制[root@lk7 bin]# redis-cli -p 6381
127.0.0.1:6381> exit
[root@lk7 bin]# redis-cli -p 6382
127.0.0.1:6382> exit
[root@lk7 bin]# redis-cli -p 6383
127.0.0.1:6383>
使用info命令查看当前客户端信息,此命令查看的是所有信息。
想要单独查看replication信息,可使用如下命令:
代码语言:javascript复制128.127.0.0.1:6383> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:399d90db2653e317cd69c504b326a870c2e1fb57
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
3.6配置主从结构
调用客户端命令启动一主两从结构:
主从节点分配:
- 主节点:6381。
- 从节点:6382、6383。
主节点不需要配置,只需要配置从节点即可,在从节点客户端执行如下命令:
代码语言:javascript复制slaveof host port(云主机的主节点ip需要使用内网地址)
执行当前节点挂接的主节点ip和端口。
操作如下:
代码语言:javascript复制127.0.0.1:6383> slaveof 192.168.106.171 6381
OK
127.0.0.1:6383> exit
[root@lk7 bin]# redis-cli -p 6382
127.0.0.1:6382> slaveof 192.168.106.171 6381
OK
127.0.0.1:6382>
3.7查看配置信息
挂接完成返回ok查看主节点和从节点的replication变化内容。
6381主节点内容:
代码语言:javascript复制[root@lk7 ~]# redis-cli -p 6381
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.106.171,port=6382,state=online,offset=182,lag=0
slave1:ip=192.168.106.171,port=6383,state=online,offset=182,lag=0
master_failover_state:no-failover
master_replid:869898c1c73e200eeca0bcb41666811836fdf2e5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:182
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:182
127.0.0.1:6381>
6382、6383从节点内容:
代码语言:javascript复制[root@lk7 bin]# redis-cli -p 6382
127.0.0.1:6382> slaveof 192.168.106.171 6381
OK
127.0.0.1:6382> info replication
# Replication
role:slave
master_host:192.168.106.171
master_port:6381
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_read_repl_offset:280
slave_repl_offset:280
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:869898c1c73e200eeca0bcb41666811836fdf2e5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:280
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:280
127.0.0.1:6382>
[root@lk7 bin]# redis-cli -p 6383
127.0.0.1:6383> info replication
# Replication
role:slave
master_host:192.168.106.171
master_port:6381
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_read_repl_offset:126
slave_repl_offset:126
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:869898c1c73e200eeca0bcb41666811836fdf2e5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:126
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:99
repl_backlog_histlen:28
127.0.0.1:6383>
4主从复制测试
4.1同步数据测试
首先登录主节点,然后进行如下测试:
代码语言:javascript复制[root@lk7 bin]# redis-cli -p 6381
127.0.0.1:6381> auth 123
OK
127.0.0.1:6381> keys *
(empty array)
127.0.0.1:6381> set name xujd
OK
127.0.0.1:6381> keys *
1) "name"
127.0.0.1:6381> get name
"xujd"
127.0.0.1:6381> flushall
OK
127.0.0.1:6381>
127.0.0.1:6382> keys *
1) "name"
127.0.0.1:6382> get name
"xujd"
127.0.0.1:6382>
127.0.0.1:6383> keys *
1) "name"
127.0.0.1:6383> get name
"xujd"
127.0.0.1:6383>
4.2测试从节点写数据
在两个从节点都写入东西,操作如下:
代码语言:javascript复制127.0.0.1:6382> set age 18
(error) READONLY You can't write against a read only replica.
127.0.0.1:6382>
127.0.0.1:6383> set age 18
(error) READONLY You can't write against a read only replica.
127.0.0.1:6383>
写入都是失败的。
4.3测试主从结构的高可用HA
将主节点宕机查看从节点的状态。操作如下:
代码语言:javascript复制[root@lk7 ~]# ps -ef | grep redis
root 7091 1 0 20:23 ? 00:00:00 redis-server *:6381
root 7101 1 0 20:23 ? 00:00:00 redis-server *:6382
root 7109 1 0 20:23 ? 00:00:00 redis-server *:6383
root 7185 1691 0 20:24 pts/1 00:00:00 redis-cli -p 6382
root 7277 7238 0 20:26 pts/2 00:00:00 redis-cli -p 6383
root 7605 7331 0 20:32 pts/3 00:00:00 grep --color=auto redis
[root@lk7 ~]# kill -9 7091
[root@lk7 ~]# ps -ef | grep redis
root 7101 1 0 20:23 ? 00:00:00 redis-server *:6382
root 7109 1 0 20:23 ? 00:00:00 redis-server *:6383
root 7185 1691 0 20:24 pts/1 00:00:00 redis-cli -p 6382
root 7277 7238 0 20:26 pts/2 00:00:00 redis-cli -p 6383
root 7629 7331 0 20:32 pts/3 00:00:00 grep --color=auto redis
[root@lk7 ~]#
127.0.0.1:6382> info replication
# Replication
role:slave
master_host:192.168.106.171
master_port:6381
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_read_repl_offset:658
slave_repl_offset:658
master_link_down_since_seconds:30
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:869898c1c73e200eeca0bcb41666811836fdf2e5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:658
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:658
127.0.0.1:6382>
经过观察发现,主节点宕机,从节点并不会自动顶替主节点工作,高可用测试失败。