美文网首页
修改Redis4.0 psync2链式复制

修改Redis4.0 psync2链式复制

作者: 白馨_1114 | 来源:发表于2020-04-21 17:40 被阅读0次

    1.psync2解释

    以A ---> B ---> C ---> D为例说明一下psync2

    B,C,D都是只读从库,无论怎么转化角色关系,半同步数据都一致。

    B可写从库,C,D只读。那么B一旦写入数据,只要涉及到B的角色转换关系,半同步都会致使数据不一致。但复制链上的A,C,D仍然一致。

    A ---> B ---> C ---> D
    B写入数据,不会同步到C,D。B提升为主库,那么B作为可写从库时,写入的数据也不会同步到C,D(除非全同步)。

    B开始为可写从库,之后提升为主库。提升为主库过程中,B强制C断开链接。接着C再半同步。B已经不是从库的角色,C无法同步B全部数据是不合理的。

    所以说psync2这个协议只适合只读从库。

    针对可写从库,作者做的设计就是只要可写,那么针对这个可写实例,做角色转换关系数据就必然不一致。他也明说了。
    A ---> B ---> C
    Even if B is writable, C will not see B writes and will instead have identical dataset as the master instance A.
    这种设计是易于理解的。

    2.修改方案

    但是我们的场景,就是针对可写从库。要求可写从库数据必须同步到它的下一个复制链接。
    假设B写入的数据,能同步到C。
    A ---> B ---> C ---> D
    B可写,写入的数据,会同步到C,D。
    那么C,D,B互相转换角色时,半同步数据是一致的。那么C,D,B互相转换角色时,半同步数据是一致的。
    A不一致,不一致的数据源来源不可控(C,D也可能可写)。

    如果我们能接受如上设计。
    只需要
    1.对可读从库,保证遵守对可读从库,保证遵守psync2。
    2.走清楚逻辑,避免改动对其他功能造成影响。

    3.代码修改

    1)从socket缓冲区中读取数据

    readQueryFromClient(networking.c)
    
    注释掉对pending_querybuf(缓存从库将主库发送过来的命令)的操作。
    //else if (c->flags & CLIENT_MASTER) {
            //c->pending_querybuf = sdscatlen(c->pending_querybuf,
            //                                c->querybuf+qblen,nread);
        //}
    
    将以下代码修改为processInputBuffer(c);不对主库传播的命令做特殊处理。
    让所有命令传播都经过replicationFeedSlaves。
        /*if (!(c->flags & CLIENT_MASTER)) {
            processInputBuffer(c);
        } else {
            size_t prev_offset = c->reploff;
            processInputBuffer(c);
            size_t applied = c->reploff - prev_offset;
            if (applied) {
                replicationFeedSlavesFromMasterStream(server.slaves,
                        c->pending_querybuf, applied);
                sdsrange(c->pending_querybuf,applied,-1);
            }
        }*/
    

    2.Redis通过processInputBuffer处理完命令之后,将命令传播到从库。
    replicationFeedSlaves(replication.c)
    注释掉对从库的操作
    //if (server.masterhost != NULL) return; //当实例为从库,不传播到从库,直接返回。
    这部分修改都是跟psync2相关,不影响redis其他部分的功能。合并起来比较容易。

    4.方案影响

    修改完成后:
    对于可读从库,主库传播的命令正常通过replicationFeedSlaves传播到自己的slave。不破坏整个复制协议。
    对于可写从库,主库传播的命令也正常通过replicationFeedSlaves传播到自己的slave,从库可写从客户端接受的命令传播到自己的slave。

    相关文章

      网友评论

          本文标题:修改Redis4.0 psync2链式复制

          本文链接:https://www.haomeiwen.com/subject/sqspihtx.html