jinfeng_wang

G-G-S,D-D-U!

BlogJava 首页 新随笔 联系 聚合 管理
  400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
http://bboyjing.github.io/2016/12/08/Redis%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%E5%85%AB%E3%80%90Redis%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6%E3%80%91/

对于高负载应用来说,复制(replication)是不可或缺的一个特性,复制可以让其他服务器拥有一个不断地更新的数据副本,从而使得拥有副本数据的服务器可以用于处理客户端发送的读请求。关系型数据库通常会使用一个主服务器(master)向多个从服务器(slave)发送更行,并使用从服务器来处理所有读请求。Redis也采用了同样的方法来实现自己的复制特性,并将其用作扩展性能的一种手段。

复制相关配置选项

之前说过,当从服务器连接主服务器时,主服务器会执行BGSAVE操作,因此要求主服务器的快照持久化功能正常。配置slaveof host port选项即可连接主服务器。下面来测试下:

  1. 再安装一个Redis,直接拷贝之前的安装好的文件夹即可,本人安装的两个Redis路径为/opt/redis-3.2.4、/opt/redis-replication

    1
    2
    3
    cd /opt
    sudo cp -r redis-3.2.4 redis-replication
    sudo chmod -R 777 redis-replication
  2. 修改redis-replication的redis.conf文件,改两个配置port和slaveof

    1
    2
    port 6380
    slaveof localhost 6379
  3. 启动redis-3.2.4

    1
    2
    3
    4
    5
    6
    7
    8
    cd /opt/redis-3.2.4
    ./src/redis-server ./redis.conf
    //启动交互式命令行并添加两个key
    ./src/redis-cli
    127.0.0.1:6379> set key1 hello
    OK
    127.0.0.1:6379> set key2 world
    OK
  4. 启动redis-replication

    1
    2
    3
    4
    5
    6
    7
    8
    cd /opt/redis-replication
    ./src/redis-server ./redis.conf
    //启动交互式命令行
    ./src/redis-cli -h localhost -p 6380
    //查看数据,6380端口的Redis服务上也有key1和key2了
    localhost:6380> keys *
    1) "key2"
    2) "key1"
  5. 测试数据更新推送

    1
    2
    3
    4
    5
    6
    7
    8
    //主服务添加key3
    127.0.0.1:6379> set key3 !
    OK
    //从服务收到数据更新
    localhost:6380> keys *
    1) "key3"
    2) "key2"
    3) "key1"

对于一个正在运行的Redis服务器,可以发送SLAVEOF no one命令来让服务器终止复制操作,不再接受主服务器的数据更新;也可以通过发送SLAVEOF host port命令来让服务器开始复制一个新的主服务器,这个就不测试了,了解下有这个功能。

Redis复制的启动过程

从服务器连接主服务器时,主服务器会创建一个快照文件并将其发送至从服务器,但这只是主从复制执行过程的其中一步,下面列举出复制过程中Redis所有的行为:

步骤主服务器操作从服务器操作
1等待命令进入连接(或者重连接)主服务器,发送SYNC命令
2开始执行BGSAVE,并使用缓冲区记录BGSAVE之后执行的所有写命令根据配置选项来决定时继续使用现在的数据来处理客户端命令,还是向发送请求的客户端返回错误
3BGSAVE执行完毕,向从服务器发送快照文件,并在发送期间继续使用缓冲区记录杯知行的写命令丢弃所有旧的数据,开始载入主服务器发来的快照文件
4快照文件发送完毕,开始向从服务器发送存储在缓冲区里面的写命令完成对快照文件的解释操作,像往常一样开始接受命令请求
5缓冲区存储的写命令发送完毕;从现在开始,没执行一个写命令,就像从服务器发送相同的写命令执行主服务器发来的所有存储在缓冲区里面的写命令;从现在开始,接收并执行主服务器传来的每个写命令

由上述步骤可以看出,有必要给Redis主服务器留30%~45%的内存用于执行BGSAVE命令和创建记录写命令的缓冲区。另外,从服务器还有一点需要注意的是,从服务器在进行同步时,会清空自己的所有数据,因为第3步中,从服务器会丢弃所有旧数据。
注:Redis不支持主主复制(master-master replication)lian

当多个从服务器尝试连接同一个主服务器的时候,就会出现下表所示的两种情况中的其中一种:

当有新的从服务器连接主服务器时主服务器的操作
上述步骤3尚未执行所有从服务器都会接收相同的快照文件和相同的缓冲区写命令
上述步骤3正在执行或者已经执行当主服务器与较早进行连接的从服务器执行完复制所需的5个步骤之后,主服务器会与新连接的从服务器执行一次新的步骤1至步骤5

由此可以看出多个从服务器的同步对网络的开销挺大的,有可能会影响到主服务器接收写命令,甚至是与主服务器位于同一网络中的其他硬件。

主从链

上面讲到创建多个从服务器可能造成网络不可用,此时可以使用另外一个解决方案,从服务器拥有自己的从服务器,并由此形成主从链(master/slave chaining)。当读请求的重要性明显高于写请求的重要性,并且读请求的数量需求远远超出一台Redis服务器可以处理的范围时,用户就需要添加新的从服务器来处理读请求,随着负载不断上升,主服务器可能会无法快速地更新所有从服务器。为了缓解这个问题,可以创建一个由Redis主/从节点(master/slave node)组成的中间层来分担主服务器的复制工作,如下图所示:
图1
按照上图的树状结构,只有3台从服务器和主服务器通信,其他都向从服务器同步数据,分散了网络开销。如果12台从服务器都向主服务器同步数据的话,想想也觉得有点牵强了。


posted on 2016-12-14 15:24 jinfeng_wang 阅读(115) 评论(0)  编辑  收藏 所属分类: 2016-REDIS

只有注册用户登录后才能发表评论。


网站导航: