• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase
您的位置:首页 > 数据库 >Redis > Redis源码剖析和注释(二十二)---Redis复制(replicate)源码详细解析

Redis源码剖析和注释(二十二)---Redis复制(replicate)源码详细解析

作者:men_wen的博客 字体:[增加 减小] 来源:互联网 时间:2017-07-22

men_wen的博客通过本文主要向大家介绍了redis,数据库,源码等相关知识,希望本文的分享对您有所帮助

Redis 复制(replicate)实现

1. 复制的介绍

Redis为了解决单点数据库问题,会把数据复制多个副本部署到其他节点上,通过复制,实现Redis的高可用性,实现对数据的冗余备份,保证数据和服务的高度可靠性。

关于复制的详细配置和如何建立复制,请参考:Redis 复制功能详解 。

 

  • Redis 复制replicate实现
    • 复制的介绍
    • 复制的实现
      • 1 主从关系的建立
      • 2 主从网络连接建立
      • 3 发送PING命令
      • 4 认证权限
      • 5 发送端口号
      • 6 发送 IP 地址
      • 7 发送能力capability
      • 8 发送PSYNC命令
      • 9 发送输出缓冲区数据
      • 10 命令传播
    • 部分重同步实现
      • 1 心跳机制
      • 2 复制积压缓冲区backlog
</div>

 

2. 复制的实现

本文主要剖析:

  • 第一次执行复制所进行全量同步的全过程
  • 部分重同步的实现

replication.c文件详细注释:Redis 复制代码注释

2.1 主从关系的建立

复制的建立方法有三种。

  1. 在redis.conf文件中配置slaveof <masterip> <masterport>选项,然后指定该配置文件启动Redis生效。
  2. 在redis-server启动命令后加上--slaveof <masterip> <masterport>启动生效。
  3. 直接使用 slaveof <masterip> <masterport>命令在从节点执行生效。

无论是通过哪一种方式来建立主从复制,都是从节点来执行slaveof命令,那么从节点执行了这个命令到底做了什么,我们上源码:

// SLAVEOF host port命令实现
void slaveofCommand(client *c) {
    // 如果当前处于集群模式,不能进行复制操作
    if (server.cluster_enabled) {
        addReplyError(c,"SLAVEOF not allowed in cluster mode.");
        return;
    }

    // SLAVEOF NO ONE命令使得这个从节点关闭复制功能,并从从节点转变回主节点,原来同步所得的数据集不会被丢弃。
    if (!strcasecmp(c->argv[1]->ptr,"no") &&
        !strcasecmp(c->argv[2]->ptr,"one")) {
        // 如果保存了主节点IP
        if (server.masterhost) {
            // 取消复制操作,设置服务器为主服务器
            replicationUnsetMaster();
            // 获取client的每种信息,并以sds形式返回,并打印到日志中
            sds client = catClientInfoString(sdsempty(),c);
            serverLog(LL_NOTICE,"MASTER MODE enabled (user request from '%s')",
                client);
            sdsfree(client);
        }
    // SLAVEOF host port
    } else {
        long port;

        // 获取端口号
        if ((getLongFromObjectOrReply(c, c->argv[2], &port, NULL) != C_OK))
            return;

        // 如果已存在从属于masterhost主节点且命令参数指定的主节点和masterhost相等,端口也相等,直接返回
        if (server.masterhost && !strcasecmp(server.masterhost,c->argv[1]->ptr)
            && server.masterport == port) {
            serverLog(LL_NOTICE,"SLAVE OF would result into synchronization with the master we are already connected with. No operation performed.");
            addReplySds(c,sdsnew("+OK Already connected to specified master\r\n"));
            return;
        }
        // 第一次执行设置端口和ip,或者是重新设置端口和IP
        // 设置服务器复制操作的主节点IP和端口
        replicationSetMaster(c->argv[1]->ptr, port);
        // 获取client的每种信息,并以sds形式返回,并打印到日志中
        sds client = catClientInfoString(sdsempty(),c);
        serverLog(LL_NOTICE,"SLAVE OF %s:%d enabled (user request from '%s')",
            server.masterhost, server.masterport, client);
        sdsfree(client);
    }
    // 回复ok
    addReply(c,shared.ok);
}

当从节点的client执行SLAVEOF命令后,该命令会被构建成Redis协议格式,发送给从节点服务器,然后节点服务器会调用slaveofCommand()函数执行该命令。

具体的命令接受和回复请参考:Redis 网络连接库剖析

而SLAVEOF命令做的操作并不多,主要以下三步:

  • 判断当前环境是否在集群模式下,因为集群模式下不行执行该命令。
  • 是否执行的是SLAVEOF NO ONE命令,该命令会断开主从的关系,设置当前节点为主节点服务器。
  • 设置从节点所属主节点的IP和port。调用了replicationSetMaster()函数。

SLAVEOF命令能做的只有这么多,我们来具体看下replicationSetMaster()函数的代码,看看它做了哪些与复制相关的操作。

// 设置复制操作的主节点IP和端口
void replicationSetMaster(char *ip, int port) {
    // 按需清除原来的主节点信息
    sdsfree(server.masterhost);
    // 设置ip和端口
    server.masterhost = sdsnew(ip);
    server.masterport = port;
    // 如果有其他的主节点,在释放
    // 例如服务器1是服务器2的主节点,现在服务器2要同步服务器3,服务器3要成为服务器2的主节点,因此要释放服务器1
    if (server.master) freeClient(server.master);
    // 解除所有客户端的阻塞状态
    disconnectAllBlockedClients(); /* Clients blocked in master, now slave. */
    // 关闭所有从节点服务器的连接,强制从节点服务器进行重新同步操作
    disconnectSlaves(); /* Force our slaves to resync with us as well. */
    // 释放主节点结构的缓存,不会执行部分重同步PSYNC
    replicationDiscardCachedMaster(); /* Don't try a PSYNC. */
    // 释放复制积压缓冲区
    freeReplicationBacklog(); /* Don't allow our chained slaves to PSYNC. */
    // 取消执行复制操作
    cancelReplicationHandshake();
    // 设置复制必须重新连接主节点的状态
    server.repl_state = REPL_STATE_CONNECT;
    // 初始化复制的偏移量
    server.master_repl_offset = 0;
    // 清零连接断开的时长
    server.repl_down_since = 0;
}

由代码知,replicationSetMaster()函数执行操作的也很简单,总结为两步:

  • 清理之前所属的主节点的信息。
  • 设置新的主节点IP和port等。

因为,当前从节点有可能之前从属于另外的一个主节点服务器,因此要清理所有关于之前主节点的缓存、关闭旧的连接等等。然后设置该从节点的新主节点,设置了IP和port,还设置了以下状态:

// 设置复制必须重新连接主节点的状态
server.repl_state = REPL_STATE_CONNECT;
// 初始化全局复制的偏移量
server.master_repl_offset = 0;

然后,就没有然后了,然后就会执行复制操作吗?这也没有什么关于复制的操作执行了,那么复制操作是怎么开始的呢?

2.2 主从网络连接建立

slaveof命令是一个异步命令,执行命令时,从节点保存主节点的信息,确立主从关系后就会立即返回,后续的复制流程在节点内部异步执行。那么,如何触发复制的执行呢?

周期性执行的函数:replicationCron()函数,该函数被服务器的时间事件的回调函数serverCron()所调用,而serverCron()函数在Redis服务器初始化时,被设置为时间事件

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Windows环境部署Redis集群
  • Redis简介
  • Centos7下Redis3.2.8最新版本安装教程
  • 详解redis是如何实现队列消息的ack
  • Linux中设置Redis开机启动的方法
  • Redis中五种数据类型简单操作
  • Redis 中spark参数executor-cores引起的异常解决办法
  • 关于redis Key淘汰策略的实现方法
  • 浅谈redis的maxmemory设置以及淘汰策略
  • 详谈redis优化配置和redis.conf说明(推荐)

相关文章

  • 2017-05-11redis+mysql+quartz 一种红包发送功能的实现
  • 2017-07-22EasyCMS在幼儿园视频直播项目实战中以redis操作池的方式应对高并发的redis操作问题
  • 2017-05-11Redis教程(六):Sorted-Sets数据类型
  • 2017-05-11Windows环境部署Redis集群
  • 2017-05-11Redis优化经验总结(必看篇)
  • 2017-05-11Redis中的动态字符串学习教程
  • 2017-05-11Windows下Redis的安装使用图解
  • 2017-05-11解锁redis锁的正确姿势
  • 2017-07-22Redis系列(四)--内存淘汰机制(含单机版内存优化建议)
  • 2017-05-11Redis禁用命令、危险命令及规避方法

文章分类

  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase

最近更新的内容

    • Windows下Redis安装配置简单教程
    • 超强、超详细Redis数据库入门教程
    • 利用Redis统计网站在线活跃用户的方法
    • CentOS系统下Redis安装和自启动配置的步骤
    • NoSQL和Redis简介及Redis在Windows下的安装和使用教程
    • Redis数据库的安装配置方法
    • php结合redis实现高并发下的抢购、秒杀功能的实例
    • 解锁redis锁的正确姿势
    • CentOS下Redis数据库的基本安装与配置教程
    • redis启动流程介绍

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有