美文网首页
Redis主从复制

Redis主从复制

作者: 唯爱熊 | 来源:发表于2019-12-28 21:32 被阅读0次

    Redis主从复制

    一.主从复制介绍

    1.Redis复制功能介绍

    1)Redis 使用异步复制。从 Redis2.8开始,从服务器会以每秒一次的频率向主服务器报告复制流(replication stream)的处理进度。

    2)一个主服务器可以有多个从服务器。

    3)不仅主服务器可以有从服务器,从服务器也可以有自己的从服务器,多个从服务器之间可以构成一个图状结构。

    4)复制功能不会阻塞主服务器:即使有一个或多个从服务器正在进行初次同步, 主服务器也可以继续处理命令请求。

    5)复制功能也不会阻塞从服务器:只要在 redis.conf 文件中进行了相应的设置, 即使从服务器正在进行初次同步, 服务器也可以使用旧版本的数据集来处理命令查询。

    6)在从服务器删除旧版本数据集并载入新版本数据集的那段时间内,连接请求会被阻塞。

    7)还可以配置从服务器,让它在与主服务器之间的连接断开时,向客户端发送一个错误。

    8)复制功能可以单纯地用于数据冗余(data redundancy),也可以通过让多个从服务器处理只读命令请求来提升扩展性(scalability): 比如说,繁重的SORT命令可以交给附属节点去运行。

    9)可以通过复制功能来让主服务器免于执行持久化操作:只要关闭主服务器的持久化功能,然后由从服务器去执行持久化操作即可。

    二.架构图
    三.关闭主服务器持久化时,复制功能的数据安全问题

    1.当配置Redis复制功能时,强烈建议打开主服务器的持久化功能。 否则的话,由于延迟等问题,部署的服务应该要避免自动拉起。

    2.为了帮助理解主服务器关闭持久化时自动拉起的危险性,参考一下以下会导致主从服务器数据全部丢失的例子:

    1)假设节点A为主服务器,并且关闭了持久化。并且节点B和节点C从节点A复制数据

    2)节点A崩溃,然后由自动拉起服务重启了节点A. 由于节点A的持久化被关闭了,所以重启之后没有任何数据

    3)节点B和节点C将从节点A复制数据,但是A的数据是空的,于是就把自身保存的数据副本删除。

    结论:

    1)在关闭主服务器上的持久化,并同时开启自动拉起进程的情况下,即便使用Sentinel来实现Redis的高可用性,也是非常危险的。因为主服务器可能拉起得非常快,以至于Sentinel在配置的心跳时间间隔内没有检测到主服务器已被重启,然后还是会执行上面的数据丢失的流程。

    2)无论何时,数据安全都是极其重要的,所以应该禁止主服务器关闭持久化的同时自动拉起。

    四.主从复制原理

    主从复制流程:
    1.从节点发送同步请求到主节点
    2.主节点接收到从节点的请求之后,做了如下操作

    • 立即执行bgsave将当前内存里的数据持久化到磁盘上

    • 持久化完成之后,将rdb文件发送给从节点

    3.从节点从主节点接收到rdb文件之后,做了如下操作

    • 清空自己的数据

    • 载入从主节点接收的rdb文件到自己的内存里

    4.后面的操作就是和主节点实时的了

    五.复制的一致性

    1)在读写分离环境下,客户端向主服务器发送写命令 SET k10086 v10086,主服务器在执行这个写命令之后,向客户端返回回复,并将这个写命令传播给从服务器。

    2)接到回复的客户端继续向从服务器发送读命令 GET k10086 ,并且因为网络状态的原因,客户端的 GET命令比主服务器传播的 SET 命令更快到达了从服务器。

    3)因为从服务器键k10086的值还未被更新,所以客户端在从服务器读取到的将是一个错误(过期)的k10086值。

    Redis是怎么保证数据安全的呢?

    1)主服务器只在有至少N个从服务器的情况下,才执行写操作

    2)从Redis 2.8开始,为了保证数据的安全性,可以通过配置,让主服务器只在有至少N个当前已连接从服务器的情况下,才执行写命令。

    3)不过,因为 Redis 使用异步复制,所以主服务器发送的写数据并不一定会被从服务器接收到,因此, 数据丢失的可能性仍然是存在的。

    4)通过以下两个参数保证数据的安全:

    #执行写操作所需的至少从服务器数量
    min-slaves-to-write <number of slaves>
    #指定网络延迟的最大值
    min-slaves-max-lag <number of seconds>
    

    这个特性的运作原理:

    1)从服务器以每秒一次的频率 PING 主服务器一次, 并报告复制流的处理情况。主服务器会记录各个从服务器最后一次向它发送 PING 的时间。用户可以通过配置, 指定网络延迟的最大值 min-slaves-max-lag , 以及执行写操作所需的至少从服务器数量 min-slaves-to-write 。

    2)如果至少有 min-slaves-to-write 个从服务器, 并且这些服务器的延迟值都少于 min-slaves-max-lag 秒, 那么主服务器就会执行客户端请求的写操作。你可以将这个特性看作 CAP 理论中的 C 的条件放宽版本: 尽管不能保证写操作的持久性, 但起码丢失数据的窗口会被严格限制在指定的秒数中。

    3)另一方面, 如果条件达不到 min-slaves-to-write 和 min-slaves-max-lag 所指定的条件, 那么写操作就不会被执行, 主服务器会向请求执行写操作的客户端返回一个错误。

    六.Redis主从实战

    环境规划以及地址分配

    配置主从

    1.安装redis

    #安装依赖
    [root@redis01 ~]# install gcc -y
    #创建目录
    [root@redis01 ~]# mkdir -p /data/soft
    [root@redis01 ~]# mkdir -p /data/redis_6379
    [root@redis01 ~]# mkdir -p /opt/redis_6379/{conf,pid,logs}
    #下载并安装
    [root@redis01 ~]# cd /data/soft/
    [root@redis01 ~]# wget http://download.redis.io/releases/redis-3.2.9.tar.gz
    [root@redis01 ~]# tar zxf redis-3.2.9.tar.gz -C /opt/
    [root@redis01 ~]# ln -s /opt/redis-3.2.9/ /opt/redis
    [root@redis01 ~]# cd /opt/redis
    [root@redis01 ~]# make && make install
    #配置文件
    [root@redis01 ~]# vim /opt/redis_6379/conf/redis_6379.conf
    ### 以守护进程模式启动
    daemonize yes
    ### 绑定的主机地址
    bind 127.0.0.1 10.0.0.73
    ### 监听端口
    port 6379
    ### pid文件和log文件的保存地址
    pidfile /opt/redis_6379/pid/redis_6379.pid
    logfile /opt/redis_6379/logs/redis_6379.log
    ### 本地数据库的目录
    dir /data/redis_6379
    ### 指定本地持久化文件的文件名,默认是dump.rdb
    dbfilename redis_6379.rdb
    #如果需要密码认证做如下配置
    主从密码配置文件里添加2行参数:
    requirepass "123456"
    masterauth "123456"
    
    #启动redis
    [root@redis01 ~]# redis-server /opt/redis_6379/conf/redis_6379.conf
    
    #检查是否启动
    [root@redis01 ~]#  ps -ef|grep redis
    [root@redis01 ~]# netstat -lntup|grep redis
    

    2.快速部署其它服务器

    [root@redis02 ~]# rsync -avz 10.0.0.73:/opt/* /opt/
    [root@redis02 ~]# mkdir /data/redis_6379/ -p
    [root@redis02 ~]# cd /opt/redis 
    [root@redis02 ~]# make install 
    [root@redis02 ~]# sed -i 's#73#74#g' /opt/redis_6379/conf/redis_6379.conf
    [root@redis02 ~]# redis-server /opt/redis_6379/conf/redis_6379.conf
    

    3.开启主从

    #开启从库
    配置方法:
    方法1: 临时生效
    [root@redis02 ~]# redis-cli -h 10.0.0.74
    10.0.0.74:6379> SLAVEOF 10.0.0.73 6379
    OK
    ​
    方法2: 写入配置文件(如果使用哨兵不建议写入配置文件)
    SLAVEOF 10.0.0.73 6379
    

    4.检测主从

    #master
    [root@redis01 ~]# redis-cli 
    127.0.0.1:6379> info replication
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=10.0.0.75,port=6379,state=online,offset=15261,lag=0
    slave1:ip=10.0.0.74,port=6379,state=online,offset=15261,lag=0
    master_repl_offset:15261
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:2
    repl_backlog_histlen:15260
    ​
    #连接从库查看
    [root@redis02 ~]# redis-cli 
    127.0.0.1:6379>  INFO replication
    # Replication
    role:slave
    master_host:10.0.0.73
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:10
    master_sync_in_progress:0
    slave_repl_offset:1107
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    ​
    [root@redis03 ~]# redis-cli
    127.0.0.1:6379> info replication
    # Replication
    role:slave
    master_host:10.0.0.73
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:2
    master_sync_in_progress:0
    slave_repl_offset:1205
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    

    注意

    1.从节点只读不可写
    2.从节点不会自动故障转移,它会一直同步主
    10.0.0.74:6379> set k1 v1
    (error) READONLY You can't write against a read only slave.
    3.主从复制故障转移需要人工介入
    ​
    - 修改代码指向REDIS的IP地址
    - 从节点需要执行SLAVEOF no one
    
    4.从节点会清空自己原有的数据,如果同步的对象写错了,就会导致数据丢失
    ​
    安全的操作:
    1.无论是同步,无论是主节点还是从节点
    2.先备份一下数据
    

    主从切换

    #连接master
    [root@redis01 ~]# redis-cli
    #关闭主库
    127.0.0.1:6379> shutdown
    ​
    #连接slave01
    [root@redis02 ~]# redis-cli
    #查看主从信息
    127.0.0.1:6379> info replication
    # Replication
    role:slave
    master_host:10.0.0.73
    master_port:6379
    master_link_status:down   #连接主库的状态是:down
    master_last_io_seconds_ago:-1
    master_sync_in_progress:0
    slave_repl_offset:16717
    master_link_down_since_seconds:77
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    #取消主从关系
    127.0.0.1:6379> SLAVEOF no one
    OK
    127.0.0.1:6379> info replication
    # Replication
    role:master            #此时的角色就变成了master
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    ​
    #将其他从库重新只想新主
    #连接从库
    [root@redis03 ~]# redis-cli
    127.0.0.1:6379> SLAVEOF 10.0.0.74 6379
    OK
    127.0.0.1:6379> info replication
    # Replication
    role:slave
    master_host:10.0.0.74
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:5
    master_sync_in_progress:0
    slave_repl_offset:15
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    

    相关文章

      网友评论

          本文标题:Redis主从复制

          本文链接:https://www.haomeiwen.com/subject/adkeoctx.html