• Redis 主从同步+哨兵


    一、Redis主从同步

      1.什么是主从同步

        主库:只负责写数据

        从库:只负责读数据(从库手动,配置文件配置)

        主库只要发生更改,数据就会同步到从库

      2.主从同步原理

    1. 副本库通过slaveof 127.0.0.1 6379命令,连接主库,并发送SYNC给主库
    2. 主库收到SYNC,会立即触发BGSAVE,后台保存RDB,发送给副本库
    3. 副本库接收后会应用RDB快照
    4. 主库会陆续将中间产生的新的操作,保存并发送给副本库
    5. 到此,我们主复制集就正常工作了
    6. 再此以后,主库只要发生新的操作,都会以命令传播的形式自动发送给副本库
    7. 所有复制相关信息,从info信息中都可以查到.即使重启任何节点,他的主从关系依然都在
    8. 如果发生主从关系断开时,从库数据没有任何损坏,在下次重连之后,从库发送PSYNC给主库
    9. 主库只会将从库缺失部分的数据同步给从库应用,达到快速恢复主从的目的

      3.主从复制存在的问题

        主从复制,主节点发生故障,需要做故障转移,可以手动转移:让其中一个slave变成master(哨兵)

        主从复制,只能主写数据库,所以写的能力和存储能力有限(集群)

     

    原理

      1.多个sentinel(哨兵)发现并确认master有问题

      2.选举出一个sentinel作为领导

      3.选取一个slave作为新的master

      4.通知其余slave成为新的master的slave

      5.通知客户端主从变化

      6.等待老的master复活成为新master的slave

     二、搭建主从,配置哨兵

    1.Docker拉取CentOS容器,作为本机

    docker run -dit --name centos01 -p 6379:6379 -p 6380:6380 -p 6381:6381 -p 26379:26379 -p 26380:26380 -p 26381:26381 centos:7.9.2009

    2.进入容器

    docker exec -it centos01 bash

    3.安装redis

    # 1.前往用户根目录
    cd ~
    
    # 2.更换yum源,下载redis-5.0.7
    curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
    
    # 安装需要的依赖
    yum install gcc vim wget make -y
    wget http://download.redis.io/releases/redis-5.0.7.tar.gz
    
    # 觉得安装慢的可以先下载下来,然后复制进去
    docker cp /mnt/d/X_Settings/redis/redis-5.0.7.tar.gz centos01:/root/
    
    # 3.解压安装包
    tar -xzf redis-5.0.7.tar.gz
    
    # 4.进入目标文件
    cd redis-5.0.7
    
    
    # 5.编译安装
    make && make install
    
    # 如果出现:[Errno 256] No more mirrors to try 错误
    yum clean all
    yum makecache
    
    # 6.复制环境到指定路径完成安装
    cp -r ~/redis-5.0.7 /usr/local/redis
    
    
    # 7.建立软连接
    ln -s /usr/local/redis/src/redis-server /usr/bin/redis-server
    ln -s /usr/local/redis/src/redis-cli /usr/bin/redis-cli
    ln -s /usr/local/redis/src/redis-sentinel /usr/bin/redis-sentinel
    
    # 配置文件
    vim /usr/local/redis/redis.conf
    # 修改 daemonize yes
    
    # 8.后台运行redis
    cd /usr/local/redis
    redis-server &
    
    # ctrl + c 停止
    
    # 9.测试redis环境
    redis-cli
    # ctrl + c 停止
    
    # 10.关闭redis服务
    pkill -f redis -9

    删除#开头和空行后的redis.conf

    bind 127.0.0.1
    protected-mode yes
    port 6379
    tcp-backlog 511
    timeout 0
    tcp-keepalive 300
    daemonize no
    supervised no
    pidfile /var/run/redis_6379.pid
    loglevel notice
    logfile ""
    databases 16
    always-show-logo yes
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename dump.rdb
    dir ./
    replica-serve-stale-data yes
    replica-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-disable-tcp-nodelay no
    replica-priority 100
    lazyfree-lazy-eviction no
    lazyfree-lazy-expire no
    lazyfree-lazy-server-del no
    replica-lazy-flush no
    appendonly no
    appendfilename "appendonly.aof"
    appendfsync everysec
    no-appendfsync-on-rewrite no
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
    aof-load-truncated yes
    aof-use-rdb-preamble yes
    lua-time-limit 5000
    slowlog-log-slower-than 10000
    slowlog-max-len 128
    latency-monitor-threshold 0
    notify-keyspace-events ""
    hash-max-ziplist-entries 512
    hash-max-ziplist-value 64
    list-max-ziplist-size -2
    list-compress-depth 0
    set-max-intset-entries 512
    zset-max-ziplist-entries 128
    zset-max-ziplist-value 64
    hll-sparse-max-bytes 3000
    stream-node-max-bytes 4096
    stream-node-max-entries 100
    activerehashing yes
    client-output-buffer-limit normal 0 0 0
    client-output-buffer-limit replica 256mb 64mb 60
    client-output-buffer-limit pubsub 32mb 8mb 60
    hz 10
    dynamic-hz yes
    aof-rewrite-incremental-fsync yes
    rdb-save-incremental-fsync yes

    4.创建文件夹,编写配置文件

     

    cd ~
    mkdir master6379 slave6380 slave6381

    主master 6379

    vim redis_6379.conf
    daemonize yes
    bind 0.0.0.0
    port 6379
    logfile redis6379.log
    dbfilename dump.rdb
    dir /root/master6379

    从slave 6380

    vim redis_6380.conf
     
    daemonize yes
    pidfile redis.pid
    bind 0.0.0.0
    port 6380
    logfile redis6380.log
    dbfilename dump.rdb
    dir /root/slave6380
    slaveof 127.0.0.1 6379
    slave-read-only yes

    从 slave 6381

    vim redis_6381.conf
    daemonize yes
    pidfile redis.pid
    bind 0.0.0.0
    port 6381
    logfile redis6381.log
    dbfilename dump.rdb
    dir /root/slave6381
    slaveof 127.0.0.1 6379
    slave-read-only yes

    5.启动一主二从

    redis-server redis_6379.conf
    redis-server redis_6380.conf
    redis-server redis_6381.conf
    
    # 查看redis进程
    ps aux | grep redis 

     6.编写哨兵配置
    创建文件夹
    cd ~
    mkdir sentinel1 sentinel2 sentinel3

    主哨兵 26379

    vim sentinel_26379.conf
    port 26379
    daemonize yes
    dir /root/sentinel1
    bind 0.0.0.0
    logfile "sentinel_6379.log"
    sentinel monitor mymaster 127.0.0.1 6379 2
    sentinel down-after-milliseconds mymaster 30000
    sentinel parallel-syncs mymaster 1
    sentinel failover-timeout mymaster 180000

    从哨兵26380

    vim sentinel_26380.conf
    port 26380
    daemonize yes
    dir /root/sentinel1
    bind 0.0.0.0
    logfile "sentinel_6380.log"
    sentinel monitor mymaster 127.0.0.1 6380 2
    sentinel down-after-milliseconds mymaster 30000
    sentinel parallel-syncs mymaster 1
    sentinel failover-timeout mymaster 180000

    从哨兵26381

    vim sentinel_26381.conf
    port 26381
    daemonize yes
    dir /root/sentinel1
    bind 0.0.0.0
    logfile "sentinel_6381.log"
    sentinel monitor mymaster 127.0.0.1 6381 2
    sentinel down-after-milliseconds mymaster 30000
    sentinel parallel-syncs mymaster 1
    sentinel failover-timeout mymaster 180000

    7.启动三个哨兵

    redis-sentinel sentinel_26379.conf
    redis-sentinel sentinel_26380.conf
    redis-sentinel sentinel_26381.conf
    
    # 查看redis-sentinel进程
    ps aux | grep redis-sentinel

    三、代码

    import redis
    from redis.sentinel import Sentinel
    
    # 连接哨兵服务器(主机名也可以用域名)
    sentinel = Sentinel([('172.25.111.89', 26379),
                         ('172.25.111.89', 26380),
                         ('172.25.111.89', 26381)],
                        socket_timeout=5)
    # print(sentinel)
    # # 获取主服务器地址
    master = sentinel.discover_master('mymaster')
    print(master)
    
    # 获取从服务器地址
    slave = sentinel.discover_slaves('mymaster')
    print(slave)
    
    # 读写分离
    # 获取主服务器进行写入
    master = sentinel.master_for('mymaster', socket_timeout=5)
    w_ret = master.set('foo', 'bar')
    
    slave = sentinel.slave_for('mymaster', socket_timeout=0.5)
    r_ret = slave.get('foo')
    print(r_ret)
  • 相关阅读:
    python-进程池实例
    python-进程通过队列模拟数据的下载
    python-多进程模板
    python-多线程同步中创建互斥锁解决资源竞争的问题
    CentOS6.5配置网络
    解决CentOS系统Yum出现"Cannot find a valid baseurl for repo"问题
    CentOS 6.5安装图形界面
    Centos安装git
    Web前端优化,提高加载速度
    谁说写代码的不懂生活
  • 原文地址:https://www.cnblogs.com/ltyc/p/14474593.html
Copyright © 2020-2023  润新知