Redis6 主从复制

时间:2022-10-17 12:58:38

主从复制是什么

主机数据更新后根据配置和策略, 自动同步到从机的master/slaver机制,Master以写为主,Slave以读为主

主从复制作用

读写分离,性能扩展

容灾快速恢复

Redis6 主从复制

webrx@us:/usr/local/redis$ ls 
6379.conf  6379.log  6379.rdb  bin  redis.conf
webrx@us:/usr/local/redis$ ll
总用量 120
drwxr-xr-x  3 root root  4096 12月 13 18:53 ./
drwxr-xr-x 13 root root  4096 12月  9 18:09 ../
-rw-r--r--  1 root root   369 12月  9 18:37 6379.conf
-rw-r--r--  1 root root  5244 12月 13 18:27 6379.log
-rw-r--r--  1 root root   125 12月 13 08:15 6379.rdb
drwxr-xr-x  2 root root  4096 12月  9 18:09 bin/
-rw-r--r--  1 root root 93724 12月  9 18:10 redis.conf
webrx@us:/usr/local/redis$ su sudo
su: 用户 sudo 不存在
webrx@us:/usr/local/redis$ su root
密码: 
su: 认证失败
webrx@us:/usr/local/redis$ sudo su
root@us:/usr/local/redis# grep -E '^port.*$|^d.*$|^log.*$|^pro.*$|^# requirepass.*$|^# masterauth.*' redis.conf
protected-mode yes
port 6379
daemonize no
loglevel notice
logfile ""
databases 16
proc-title-template "{title} {listen-addr} {server-mode}"
dbfilename dump.rdb
dir ./
# masterauth <master-password>
# requirepass foobared
disable-thp yes
dynamic-hz yes
root@us:/usr/local/redis# grep -E '^port.*$|^d.*$|^log.*$|^pro.*$|^# requirepass.*$|^# masterauth.*' redis.conf > 6380.conf
root@us:/usr/local/redis# 

Redis6 主从复制

一主2从

Redis6 主从复制

第一步:建立配置文件 6379主服务器 6380从一 6381从二 在从机客户端输入:slaveof 127.0.0.1 6379

/usr/local/redis/bin/6379.conf

include /usr/local/redis/bin/redis.conf
port 6379
pidfile /var/run/redis_6379.pid
dbfilename 6379.rdb
logfile /usr/local/redis/bin/6379.log

/usr/local/redis/bin/6380.conf

include /usr/local/redis/bin/redis.conf
port 6380
pidfile /var/run/redis_6380.pid
dbfilename 6380.rdb
logfile /usr/local/redis/bin/6380.log

/usr/local/redis/bin/6381.conf

include /usr/local/redis/bin/redis.conf
port 6381
pidfile /var/run/redis_6381pid
dbfilename 6381.rdb
logfile /usr/local/redis/bin/6381.log

Redis6 主从复制

webrx@us:/usr/local/redis/bin$ redis
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:51ed2da022a3cc902ac9b3b3b1cefa5db17e1ea8
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> exit

webrx@us:/usr/local/redis/bin$ redis -p 6380
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:982839e2488af5b6955cf6509f7fea4c4656fe70
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:6380> exit

webrx@us:/usr/local/redis/bin$ redis -p 6381
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:945080e8cde314dc1d5713158696f997ceb91dec
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: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:9
master_sync_in_progress:0
slave_read_repl_offset:14
slave_repl_offset:14
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:2e76ab16f25b4d67bb0a607247ce240a6cf318e7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14
127.0.0.1:6381> exit

webrx@us:/usr/local/redis/bin$ redis -p 6380
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:982839e2488af5b6955cf6509f7fea4c4656fe70
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:6380> slaveof 127.0.0.1 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:8
master_sync_in_progress:0
slave_read_repl_offset:84
slave_repl_offset:84
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:2e76ab16f25b4d67bb0a607247ce240a6cf318e7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:84
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:85
repl_backlog_histlen:0
127.0.0.1:6380> exit

#登录主服务器 redis -p 6379 端口号可以省
webrx@us:/usr/local/redis/bin$ redis 
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=140,lag=1
slave1:ip=127.0.0.1,port=6380,state=online,offset=140,lag=0
master_failover_state:no-failover
master_replid:2e76ab16f25b4d67bb0a607247ce240a6cf318e7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:140
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:140
127.0.0.1:6379> exit

webrx@us:/usr/local/redis/bin$ redis -p 6380
127.0.0.1:6380> set name lisi
(error) READONLY You can't write against a read only replica.
127.0.0.1:6380> keys *
(empty array)
127.0.0.1:6380> exit

webrx@us:/usr/local/redis/bin$ redis 
127.0.0.1:6379> set name lisi
OK
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> exit
webrx@us:/usr/local/redis/bin$ redis -p 6380
127.0.0.1:6380> get name
"lisi"
127.0.0.1:6380> keys *
1) "name"
127.0.0.1:6380> 

slaveof no one设置从机变为主机

slaveof 127.0.0.1 6379

先注释redis.conf bind 127.0.0.1 -::1,再修改protected-mode no

  • 建立6380.conf 主

    include /usr/local/redis/redis.conf
    protected-mode no
    port 6380
    daemonize yes
    loglevel notice
    logfile "6380.log"
    databases 16
    proc-title-template "{title} {listen-addr} {server-mode}"
    dbfilename 6380.rdb
    dir ./
    # masterauth <master-password>
    requirepass root
    disable-thp yes
    dynamic-hz yes
    
  • 建立6381.conf 从

    include /usr/local/redis/redis.conf
    protected-mode no
    port 6381
    daemonize yes
    loglevel notice
    logfile "6381.log"
    databases 16
    proc-title-template "{title} {listen-addr} {server-mode}"
    dbfilename 6381.rdb
    dir ./
    masterauth root
    requirepass 6381
    disable-thp yes
    dynamic-hz yes
    
  • 建立6382.conf 从

    include /usr/local/redis/redis.conf
    protected-mode no
    port 6382
    daemonize yes
    loglevel notice
    logfile "6382.log"
    databases 16
    proc-title-template "{title} {listen-addr} {server-mode}"
    dbfilename 6382.rdb
    dir ./
    masterauth root
    requirepass 6382
    disable-thp yes
    dynamic-hz yes
    
  • 建立主从操作

    root@us:/usr/local/redis# bin/redis-server 6380.conf
    root@us:/usr/local/redis# bin/redis-server 6381.conf
    root@us:/usr/local/redis# bin/redis-server 6382.conf
    root@us:/usr/local/redis# ps -ef | grep redis
    root         900       1  0 18:27 ?        00:00:07 /usr/local/redis/bin/redis-server 127.0.0.1:6379
    root        2653       1  0 19:07 ?        00:00:00 bin/redis-server *:6380
    root        2662       1  0 19:07 ?        00:00:00 bin/redis-server *:6381
    root        2670       1  0 19:08 ?        00:00:00 bin/redis-server *:6382
    root        2682    2330  0 19:08 pts/0    00:00:00 grep --color=auto redis
    root@us:/usr/local/redis# redis-cli -p 6380
    127.0.0.1:6380> auth root
    OK
    127.0.0.1:6380> exit
    root@us:/usr/local/redis# redis-cli -p 6381
    127.0.0.1:6381> auth 6381
    OK
    127.0.0.1:6381> exit
    root@us:/usr/local/redis# redis-cli -p 6382
    127.0.0.1:6382> auth 6382
    OK
    127.0.0.1:6382> slaveof localhost 6380
    OK
    127.0.0.1:6382> exit
    root@us:/usr/local/redis# redis-cli -p 6381
    127.0.0.1:6381> auth 6381
    OK
    127.0.0.1:6381> slaveof localhost 6380
    OK
    127.0.0.1:6381> exit
    root@us:/usr/local/redis# redis-cli -p 6380
    127.0.0.1:6380> auth root
    OK
    127.0.0.1:6380> info replication
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=127.0.0.1,port=6382,state=online,offset=56,lag=0
    slave1:ip=127.0.0.1,port=6381,state=online,offset=56,lag=1
    master_failover_state:no-failover
    master_replid:476059f24fb9cf7904a1c8e7ee6edbc8f149f2ae
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:56
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:56
    127.0.0.1:6380> set name lisi
    OK
    127.0.0.1:6380> set age 888
    OK
    127.0.0.1:6380> exit
    root@us:/usr/local/redis# redis-cli -p 6381
    127.0.0.1:6381> auth 6381
    OK
    127.0.0.1:6381> keys *
    1) "age"
    2) "name"
    127.0.0.1:6381> get age
    "888"
    127.0.0.1:6381> exit
    root@us:/usr/local/redis# 
    

复制原理概念

  • Slave启动成功连接到master后会发送一个sync命令
  • Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令, 在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步
  • 全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
  • 增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步
  • 但是只要是重新连接master,一次完全同步(全量复制)将被自动执行

Redis6 主从复制

10.5 哨兵模式(sentinel)

能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库

Redis6 主从复制

Redis6 主从复制

设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同

1)建立sentinel.conf哨兵配置文件

sentinel monitor mserver 127.0.0.1 6379 1

mserver 别名 1代表投票至少1台同意

2)启动哨兵监听

sudo ./redis-sentinel sentinel.conf

Redis6 主从复制

Redis6 主从复制

Last login: Thu Dec  9 21:48:55 2021 from 192.168.0.145
webrx@us:~$ redis
127.0.0.1:6379> shutdown
not connected> exit
webrx@us:~$ redis -p 6381
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=21192,lag=1
master_failover_state:no-failover
master_replid:b24e8af5be7a34a651e7c672f3e3ab5be91f067e
master_replid2:a0880c8b8019a3b6f5b43a4f9494a24feece94c3
master_repl_offset:21192
second_repl_offset:15778
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:29
repl_backlog_histlen:21164
127.0.0.1:6381> exit

webrx@us:~$ cd /usr/local/redis/bin
webrx@us:/usr/local/redis/bin$ sudo ./redis-server 6379.conf
[sudo] webrx 的密码: 

webrx@us:/usr/local/redis/bin$ redis
127.0.0.1:6379> info replication
Error: Server closed the connection
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6381
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_read_repl_offset:26051
slave_repl_offset:26051
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover

#(大概10秒左右可以看到哨兵窗口日志,切换了新的主机)
#哪个从机会被选举为主机呢?根据优先级别:slave-priority 
#原主机重启后会变为从机。

Redis6 主从复制

Redis6 主从复制

优先级在redis.conf中默认:slave-priority 100,值越小优先级越高

偏移量是指获得原主机数据最全的

每个redis实例启动后都会随机生成一个40位的runid

private static JedisSentinelPool jedisSentinelPool=null;

public static  Jedis getJedisFromSentinel(){
if(jedisSentinelPool==null){
            Set<String> sentinelSet=new HashSet<>();
            sentinelSet.add("192.168.11.103:26379");

            JedisPoolConfig jedisPoolConfig =new JedisPoolConfig();
            jedisPoolConfig.setMaxTotal(10); //最大可用连接数
            jedisPoolConfig.setMaxIdle(5); //最大闲置连接数
            jedisPoolConfig.setMinIdle(5); //最小闲置连接数
            jedisPoolConfig.setBlockWhenExhausted(true); //连接耗尽是否等待
            jedisPoolConfig.setMaxWaitMillis(2000); //等待时间
            jedisPoolConfig.setTestOnBorrow(true); //取连接的时候进行一下测试 ping pong

			jedisSentinelPool=new JedisSentinelPool("mymaster",sentinelSet,jedisPoolConfig);
			return jedisSentinelPool.getResource();
        }else{
			return jedisSentinelPool.getResource();
        }
}

Redis6 主从复制