zoukankan      html  css  js  c++  java
  • Sentinel-Redis高可用方案(一):主从复制

    引言

    大概是因为Redis是个人开发的产品,所以Redis的高可用方案是被分成了几块来实现:主从复制、主从切换以及虚拟IP或客户端方案。

    从Redis 2.8开始加入对Sentinel机制从而实现了服务器端的主从切换,但目前尚未发现实现虚拟IP或客户端切换方案。

    主从复制研究

    wget http://download.redis.io/releases/redis-2.8.2.tar.gz
    tar xzf redis-2.8.2.tar.gz

    mv redis-2.8.2 /opt/
    cp redis.conf redis-master.conf
    cp redis.conf redis-slave.conf

    cd /opt/redis-2.8.2
    make


    以下是关于 Redis 复制功能的几个重要方面:
    1. 一个Master可以有多个Slave;
    2. Redis使用异步复制。从2.8开始,Slave会周期性(每秒一次)发起一个Ack确认复制流(replication stream)被处理进度;
    3. 不仅主服务器可以有从服务器, 从服务器也可以有自己的从服务器, 多个从服务器之间可以构成一个图状结构;
    4. 复制在Master端是非阻塞模式的,这意味着即便是多个Slave执行首次同步时,Master依然可以提供查询服务;
    5. 复制在Slave端也是非阻塞模式的:如果你在redis.conf做了设置,Slave在执行首次同步的时候仍可以使用旧数据集提供查询;你也可以配置为当Master与Slave失去联系时,让Slave返回客户端一个错误提示;
    6. 当Slave要删掉旧的数据集,并重新加载新版数据时,Slave会阻塞连接请求(一般发生在与Master断开重连后的恢复阶段);
    7. 复制功能可以单纯地用于数据冗余(data redundancy),也可以通过让多个从服务器处理只读命令请求来提升扩展性(scalability): 比如说, 繁重的 SORT 命令可以交给附属节点去运行。
    8. 可以通过修改Master端的redis.config来避免在Master端执行持久化操作(Save),由Slave端来执行持久化。

    分别修改redis-master.conf和redis-slave.conf,
    daemonize项,改为yes(缺省为no):daemonize yes
    maxmemory项,设最大占用内存为50MB:maxmemory 50mb
    而有6种内存过期策略,通过maxmemory-policy修改,一般使用默认值或allkeys-lru:
    volatile-lru:只对设置了过期时间的key进行LRU(默认值)
    allkeys-lru : 是从所有key里 删除 不经常使用的key
    volatile-random:随机删除即将过期key
    allkeys-random:随机删除
    volatile-ttl : 删除即将过期的
    noeviction : 永不过期,返回错误

    修改redis-slave.conf中的端口,避免和Master的相同:port 7379

    Redis复制工作原理:
    1. 如果设置了一个Slave,无论是第一次连接还是重连到Master,它都会发出一个SYNC命令;
    2. 当Master收到SYNC命令之后,会做两件事:
    a) Master执行BGSAVE,即在后台保存数据到磁盘(rdb快照文件);
    b) Master同时将新收到的写入和修改数据集的命令存入缓冲区(非查询类);
    3. 当Master在后台把数据保存到快照文件完成之后,Master会把这个快照文件传送给Slave,而Slave则把内存清空后,加载该文件到内存中;
    4. 而Master也会把此前收集到缓冲区中的命令,通过Reids命令协议形式转发给Slave,Slave执行这些命令,实现和Master的同步;
    5. Master/Slave此后会不断通过异步方式进行命令的同步,达到最终数据的同步一致;
    6. 需要注意的是Master和Slave之间一旦发生重连都会引发全量同步操作。但在2.8之后版本,也可能是部分同步操作。

    部分复制
    2.8开始,当Master和Slave之间的连接断开之后,他们之间可以采用持续复制处理方式代替采用全量同步。
    Master端为复制流维护一个内存缓冲区(in-memory backlog),记录最近发送的复制流命令;同时,Master和Slave之间都维护一个复制偏移量(replication offset)和当前Master服务器ID(Master run id)。当网络断开,Slave尝试重连时:
    a. 如果MasterID相同(即仍是断网前的Master服务器),并且从断开时到当前时刻的历史命令依然在Master的内存缓冲区中存在,则Master会将缺失的这段时间的所有命令发送给Slave执行,然后复制工作就可以继续执行了;
    b. 否则,依然需要全量复制操作;

    Redis 2.8 的这个部分重同步特性会用到一个新增的 PSYNC 内部命令, 而 Redis 2.8 以前的旧版本只有 SYNC 命令, 不过, 只要从服务器是 Redis 2.8 或以上的版本, 它就会根据主服务器的版本来决定到底是使用 PSYNC 还是 SYNC :

    如果主服务器是 Redis 2.8 或以上版本,那么从服务器使用 PSYNC 命令来进行同步。
    如果主服务器是 Redis 2.8 之前的版本,那么从服务器使用 SYNC 命令来进行同步。

    配置Slave
    只需要将redis-slave.conf中REPLICATION段中的slaveof <masterip> <masterport>行的注释去掉,并修改为:
    slaveof 127.0.0.1 6379
    即完成该Slave的配置,并指向本地端口为6379的Master端。

    masterauth
    如果Master端通过requirepass设置了密码,Slave需要对应的通过masterauth <password>设置密码;

    slave-serve-stale-data
    当Slave和Master断开连接时,Slave是直接返回错误提示还是利用历史数据响应客户端(或是直接返回空数据,当全量复制进行时)。yes是缺省值,即利用历史数据响应。


    slave-read-only
    缺省模式下,Slave服务器是只读的。

    repl-ping-slave-peroid
    即心跳检测间隔时间,缺省值为10秒。

    repl-timeout 60
    复制超时

    启动Redis
    #redis-server redis-master.conf
    #redis-server redis-slave.conf
    使用ps查看进程
    #ps -ef | grep redis
    还可以用netstat查看端口
    #netstat -tpln

    验证主从复制
    #redis-cli set test 1000
    #redis-cli get test #只能说明目前Master工作正常,不能说明Slave已经复制数据
    根据刚刚查看到的端口号,把端口号是6379的Master进程杀掉
    #kill -9 XXXX(PID号)
    #redis-cli -p 7379 get test #连接到Slave上,读取test
    #redis-cli -p 7379 set test 1000 #会提示Slave只读错误,不能写入

  • 相关阅读:
    实验
    概率与期望
    2020CSP-S模板
    洛谷:P2538 [SCOI2008]城堡
    洛谷P1731 生日蛋糕
    洛谷 P1180 石子合并
    洛谷 P2831 愤怒的小鸟
    浅谈状压DP
    浅谈线段树
    LCA-树链剖分
  • 原文地址:https://www.cnblogs.com/Xrinehart/p/3501372.html
Copyright © 2011-2022 走看看