主从复制是什么
主机数据更新后根据配置和策略, 自动同步到从机的master/slaver机制,Master以写为主,Slave以读为主
主从复制作用
读写分离,性能扩展
容灾快速恢复
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#
一主2从
第一步:建立配置文件 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
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,一次完全同步(全量复制)将被自动执行
10.5 哨兵模式(sentinel)
能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库
设置连接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
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
#原主机重启后会变为从机。
优先级在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();
}
}