假如只有一台redis服务器,当它出现故障.比如宕机,CPU占用率满等问题.客户端是无法链接到redis服务.如果只是服务挂了,可以重启服务.但如果是机器出了问题,就可能需要将redis迁移到别的服务器,切保证数据也迁移.

主从复制

  实现主从复制有两种方式,第一种通过命令.第二种通过配置进行主从复制.需要注意的是.当启用了主从复制后.从节点会复制主节点的数据.但是如果取消了主从复制,那么从节点的数据是不会清除的.

方式介绍

  1. 命令

    # 设置主服务
    slaveof master_ip port
    # 关闭主从复制
    slaveof no one
  2. 配置

    slaveof ip port
    # 从节点是否只做读的操作
    slave-read-only yes
    # 从服务器可相应客户端消息
    slave-serve-stale-data yes

使用

  开启主从复制

# 主服务器无需修改.
# 从服务器添加/修改配置
slaveof 192.168.128.131 6379
slave-read-only yes
slave-serve-stale-data yes
# 启动从服务器
redis-server redis_client.conf
# master查看分片信息,部分
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
# client查看分片信息,部分
# master_link_status:up 代表成功主从复制
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.128.131
master_port:6379
master_link_status:up

  主从演示

# master 设置
127.0.0.1:6379> set angel xianxian
OK
# slave 获取
127.0.0.1:6379> get angel
"xianxian"
# slave 设置
127.0.0.1:6379> set hello qvbilam
(error) READONLY You can't write against a read only replica.
# master 日志

  Master Log

# 查看日志
cat 6379.log
# 部分日志
// 132希望做同步
Replica 192.168.128.132:6379 asks for synchronization
// 全量同步复制
Full resync requested by replica 192.168.128.132:6379
// 做RDB快照
Starting BGSAVE for SYNC with target: disk
# 关闭了RDB的触发条件.在启用主从复制.master依然会执行RDB
// 同步成功
Background saving terminated with success
Synchronization with replica 192.168.128.132:6379 succeeded

  Slave Log

# 查看日志
cat 6379.log
# 部分日志
// 链接6379
Connecting to MASTER 192.168.128.131:6379
// 主从复制开始
MASTER <-> REPLICA sync started
// 类似ping操作,尝试部分复制.不用管.最后还是全量
Non blocking connect for SYNC fired the event.
Master replied to PING, replication can continue...
Partial resynchronization not possible (no cached master)
// 获取master的run id
Full resync from master: a76e91ed0b5b2253ba3c360c9f99794e86881317:0
// 接受的rdb文件大小
MASTER <-> REPLICA sync: receiving 194 bytes from master
// 清除自己的数据
MASTER <-> REPLICA sync: Flushing old data
// 加载master的rdb文件
Loading DB in memory
// 成功
Finished with success

  验证开启主从复制后,从节点数据是否会清空

# 关闭132的主从复制
127.0.0.1:6379> slaveof no one
OK
# 查看dbsize
127.0.0.1:6379> dbsize
(integer) 2
# 清除所有数据
127.0.0.1:6379> flushall
OK
# 设置新的字符串
127.0.0.1:6379> set new hello
OK
127.0.0.1:6379> get new
"hello"
# 开启主从复制
127.0.0.1:6379> slaveof 192.168.128.131 6379
OK
127.0.0.1:6379> get new
(nil)
# 结果从节点数据是会被清空.

全量复制

  当Master节点存储了很多数据.这时来了个slave节点做复制.就需要将master之前的数据,以及正在写的数据都复制过来.叫全量复制.

  redis会将master当前状态进行快照,即创建rdb文件.同步给slave,在同步的过程中如果master中有写入的数据会单独记录起来.当slave将master的rdb文件加载完成后,会通过数据的偏移量进行对比,再将master期间写入的数据同步给slave.

步骤

  1. slave内部自动执行psync把主节点的runid和偏移量,发送给master.因为第一次链接,slave不知道master的信息,所以会执行psync ? -1.自动执行的,不用去操作.
  2. master将自己的runid以及偏移量发送给slave.
  3. slave保存主节点的runid和偏移量.
  4. master自动执行bgsave.在此期间,master将新增命令进行保存(复制缓冲区)
  5. master发送RDB,再发送复制缓冲区的命令.
  6. slave接收到数据后进行清楚老的数据.
  7. 加载RDB文件和复制缓冲区的数据.

开销

  1. bgsave 主服务器开启fork进行资源的开销.
  2. RDB文件网络传输
  3. 从节点数据清空时间.
  4. 从节点加载RDB文件
  5. 从节点AOF重写(如果开启,加载完RDB会对AOF进行重写.保证数据最新)

部分复制

  当全量复制执行中的时候,如果链接中断.这段时间内master数据就会丢失.在redis2.8之前的版本是再次进行全面复制.所以部分复制就是解决这种问题的最优办法,

步骤

  1. 当在执行复制的时候,主从服务器断开了
  2. 在master写命令的时候依然会将命令写入缓冲区.
  3. slave再次链接master成功后.执行pysnc将自己的偏移量和runid传输给master.
  4. master将slave的偏移量进行对比.如果不在缓冲区之内.说明错过了很多数据(默认1MB).会进行全量复制的步骤.如果在偏移量在缓冲区之内返回continue.并将部分数据发送给slave.达到数据一致.

使用问题

读写分离:将读取的流量分摊到从节点.减少主节点的压力

# 问题出现原因
1. 例如发送阻塞会造成复制数据延迟
2 .读到过期数据(3.2版本问题)
    //策略1:操作key的时候才判断有没有过期
    //策略2:定时采样key判断有没有过期
    //如过期数量非常多,定时采样跟不上过期产生速度
    // 因为slave是不能操作数据的
3. 从节点故障
    //如果从节点挂掉.怎么迁移客户端链接的服务器

配置不一致:配置如果不一样,如大小文件等可能会造成数据不一致.

全量复制

# 问题出现原因
1. 第一次全量复制
    // 不可避免
2. runId不匹配
    //当master重启,runid是会变化的.
    // slave发现master runid变化
    // 建议故障转移,例如哨兵或集群
3. 复制缓冲区不足
    // rel_backlog_size调高(默认1mb)
Last modification:February 18th, 2020 at 10:18 pm