• Redis—主从同步


    Redis主从同步:数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布 记录。同步对读取操作的可扩展性和数据冗余很有帮助。

    持久化保证了即使 redis 服务重启也会丢失数据,因为 redis 服务重启后会将硬盘上持久化的数据恢复到内存中,但是当 redis 服务器的硬盘损坏了可能会导致数据丢失,如果通过 redis 的主从复制机制就可以避免这种单点故障,如下图:

    工作原理:

    • Redis的主从结构可以采用一主多从或者级联结构,Redis主从复制可以根据是否是全量分为全量同步和增量同步。

    • 主 redis 中的数据有两个副本(replication)即从 redis1 和从 redis2,即使一台 redis 服务器宕机其它两台 redis 服务也可以继续提供服务。

    • 主 redis 中的数据和从 redis 上的数据保持实时同步,当主 redis 写入数据时通过主从复制机制会复制到两个从 redis 服务上。

    • 只有一个主 redis,可以有多个从 redis。

    • 主从复制不会阻塞 master,在同步数据时,master 可以继续处理 client 请求。

    • 一个 redis 可以即是主又是从,如下图:

    主从复制过程

    2.8以后实现PSYNC的机制,实现断线重连

    1、完整复制过程

    在 redis2.8 版本之前主从复制过程如下图:

    • slave 服务启动,slave 会建立和 master 的连接,发送 sync 命令。
    • master 启动一个后台进程将数据库快照保存到 RDB 文件中
      注意:此时如果生成 RDB 文件过程中存在写数据操作会导致 RDB 文件和当前主 redis 数据不一致,所以此时 master 主进程会开始收集写命令并缓存起来。 
    
    • master 就发送 RDB 文件给 slave
    • slave 将文件保存到磁盘上,然后加载到内存恢复
    • master 把缓存的命令转发给 slave

    注意:后续 master 收到的写命令都会通过开始建立的连接发送给 slave。

    当 master 和 slave 的连接断开时 slave 可以自动重新建立连接。如果 master 同时收到多个 slave 发来的同步连接命令,只会启动一个进程来写数据库镜像,然后发送给所有 slave。

    完整复制的问题:

        在 redis2.8 之前从 redis 每次同步都会从主 redis 中复制全部的数据,如果从 redis 是新创建的从主 redis  中复制全部的数据这是没有问题的,但是,如果当从 redis 停止运行,再启动时可能只有少部分数据和主 redis 不同步,此时启动 redis  仍然会从主 redis 复制全部数据,这样的性能肯定没有只复制那一小部分不同步的数据高。 
    

    2、部分复制

        从机连接主机后,会主动发起 PSYNC 命令,从机会提供 master 的 runid(机器标识,随机生成的一个串) 和  offset(数据偏移量,如果offset主从不一致则说明数据不同步),主机验证 runid 和 offset 是否有效,runid  相当于主机身份验证码,用来验证从机上一次连接的主机,如果 runid 验证未通过则,则进行全同步,如果验证通过则说明曾经同步过,根据  offset 同步部分数据。 
    

    主从复制实践

    1、准备三个redis数据库配置文件

    背景: 一主两从

    • 6380为主,6381和6382 为从
    cd /opt/redis_conf
    vim redis-6380.conf
    # 写入以下配置
    port 6380
    daemonize yes
    pidfile /data/6380/redis.pid
    loglevel notice
    logfile "/data/6380/redis.log"
    dbfilename dump.rdb
    dir /data/6380
    protected-mode no
    
    • 再创建两个配置文件6381和6382
    sed "s/6380/6381/g" redis-6380.conf > redis-6381.conf
    sed "s/6380/6382/g" redis-6380.conf > redis-6382.conf
    
    • 创建数据文件目录
    [root@qishi666 redis_conf]# mkdir -p /data/6380
    [root@qishi666 redis_conf]# mkdir -p /data/6381
    [root@qishi666 redis_conf]# mkdir -p /data/6382
    

    2、启动redis数据库

    [root@qishi666 redis_conf]# redis-server redis-6380.conf 
    [root@qishi666 redis_conf]# redis-server redis-6381.conf 
    [root@qishi666 redis_conf]# redis-server redis-6382.conf
    

    3、确保这三个redis数据库是完全独立的数据库

    4、给两个从服务器配置文件再添加一行配置(很重要)

    在6381和6382配置文件添加这一行配置,表示指定主服务器为6380
    slaveof 127.0.0.1 6380
    

    5、重启数据库

    pkill redis
    redis-server /opt/redis_conf/redis-6380.conf
    redis-server /opt/redis_conf/redis-6381.conf
    redis-server /opt/redis_conf/redis-6382.conf
    

    6、查看主从数据库状态

    redis-cli -p 6380 info
    redis-cli -p 6380 info replication
    

    7、添加数据进行测试

    8、手动进行主从复制故障切换

    • 关闭6381的从库身份
    redis-cli -p 6381
    info replication
    slaveof no one
    
    • 将6382设为6381的从库
    6382连接到6381:
    [root@db03 ~]# redis-cli -p 6382
    127.0.0.1:6382> SLAVEOF no one
    127.0.0.1:6382> SLAVEOF 127.0.0.1 6381
    

  • 相关阅读:
    poj2886 Who Gets the Most Candies?
    poj1201 Intervals
    poj3109 Inner Vertices
    poj1990 MooFest
    poj3368 Frequent values
    NOIP练习赛题目6
    NOIP练习赛题目5
    NOIP练习赛题目4
    NOIP练习赛题目3
    NOIP练习赛题目2
  • 原文地址:https://www.cnblogs.com/jiumo/p/10692050.html
Copyright © 2020-2023  润新知