[redis 源码走读] - 主从数据复制 ②

上一章 简述了主从复制的基本配置,以及抓包查看了数据复制的一些工作流程,本章将通过源码去深入分析 redis 主从节点数据复制的要点逻辑:复制命令,master 服务副本 ID,复制偏移量,积压缓冲区。

redis 是纯 c 源码,阅读起来实现比较清晰,缺点:它也是一个异步的网络框架,回调处理的逻辑理解有点费劲。


1. 数据结构

1.1. redisServer

redis master / slave 节点数据结构 redisServer

 
    #define CONFIG_RUN_ID_SIZE 40
    
    struct redisServer {
        ...
        list *slaves, *monitors;    /* List of slaves and MONITORs */
        ...
        /* Replication (master) */
        char replid[CONFIG_RUN_ID_SIZE+1];  /* My current replication ID. */
        char replid2[CONFIG_RUN_ID_SIZE+1]; /* replid inherited from master*/
        long long master_repl_offset;   /* My current replication offset */
        long long master_repl_meaningful_offset; /* Offset minus latest PINGs. */
        long long second_replid_offset; /* Accept offsets up to this for replid2. */
        char *repl_backlog;             /* Replication backlog for partial syncs */
        long long repl_backlog_size;    /* Backlog circular buffer size */
        long long repl_backlog_histlen; /* Backlog actual data length */
        long long repl_backlog_idx;     /* Backlog circular buffer current offset,
                                           that is the next byte will'll write to.*/
        long long repl_backlog_off;     /* Replication "master offset" of first
        ...
        /* Replication (slave) */
        char *masterhost;               /* Hostname of master */
        int masterport;                 /* Port of master */
        client *master;     /* Client that is master for this slave */
        client *cached_master; /* Cached master to be reused for PSYNC. */
        int repl_state;          /* Replication status if the instance is a slave */
        ...
        char master_replid[CONFIG_RUN_ID_SIZE+1];  /* Master PSYNC runid. */
        long long master_initial_offset;           /* Master PSYNC offset. */
    }
  • master
结构成员 描述
slaves slaves副本链接列表。
replid 副本id,只有master有自己独立的replid,如果服务是slave,那么它需要复制master的replid,进行填充。
replid2 master历史replid。复制双方断开链接或者故障转移过程中,服务节点角色发生改变,需要缓存旧的masterreplid到replid2。因为所有slave数据都来自master。复制双方重新建立链接后,通过PSYNC<replid><offset>命令进行数据复制。
master_repl_offset master数据偏移量。复制双方是异步进行的,所以数据并不是严格的数据强一致。
second_replid_offset 历史数据偏移量。与replid2搭配使用。
repl_backlog 积压缓冲区。被设计成环形数据结构(连续内存空间)。
repl_backlog_size 积压缓冲区容量。可以通过配置文件进行配置。
repl_backlog_histlen 积压缓冲区实际填充了多少数据。
repl_backlog_idx 积压缓冲区,当前填充数据的位置。
repl_backlog_off 积压缓冲区数据起始位置。server.repl_backlog_off=server.master_repl_offset+1
  • slave
结构成员 描述
masterhost 保存master节点的主机地址。
masterport 保存master节点的端口。
repl_state 副本状态,复制双方建立数据复制要经过很多步骤,而这些步骤被进行到哪个环节被记录在repl_state。(您可以为记录异步通信状态机的当前状态。)
master slave链接master的客户端链接。
cached_master slave与master断开链接后,原链接被释放回收。为方便断线重连后数据重复被利用,需要缓存master链接数据到cached_master。
master_replid master的replid。
master_initial_offset slave通过命令PSYNC向master全量复制的数据偏移量。

1.2. client

master 与 slave 节点间异步通信链接对象。

 
    typedef struct client {
        ...
        long long read_reploff; /* Read replication offset if this is a master. */
        long long reploff;      /* Applied replication offset if this is a master. */
        char replid[CONFIG_RUN_ID_SIZE+1]; /* Master replication ID (if master). */
        ...
    }
结构成员 描述
replid master副本id。
read_reploff slave当前向master读取的数据偏移量。
masterport slave当前实际处理的数据偏移量。因为异步复制,有些读数据,读出来没有完全处理完,还在缓冲区里。例如tcp粘包问题,数据没有接收完整,等原因。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值