首页

文章

两个Redis实例互相SLAVEOF会怎样

发布网友 发布时间:2022-04-19 09:50

我来回答

1个回答

热心网友 时间:2022-04-11 15:34

今天尝试配置Redis Sentinel 来监控Redis服务器,中间由于某些设想我突然想到如果两个Redis实例互相slaveof会怎样。以下是我的试验:
两个Redis实例,redis1配置作为master,redis2配置作为slave:slaveof redis1。
启动redis1、redis2。
启动成功并且redis2也成功slaveof redis1后,redis-cli连接redis1,执行命令将redis1设置为redis2的从库:
slaveof [redis2 IP] [redis2 port]
执行后的结果是......两个redis都在重复抛出SYNC命令执行失败的log,也就是显然两个redis不能互相作为从库。
redis1执行slaveof后的log:

[14793] 06 Sep 17:36:20.426 * SLAVE OF 10.18.129.49:9778 enabled (user request)
[14793] 06 Sep 17:36:20.636 - Accepted 10.18.129.49:44277
[14793] 06 Sep 17:36:20.637 - Client closed connection
[14793] 06 Sep 17:36:20.804 * Connecting to MASTER...
[14793] 06 Sep 17:36:20.804 * MASTER <-> SLAVE sync started
[14793] 06 Sep 17:36:20.804 * Non blocking connect for SYNC fired the event.
[14793] 06 Sep 17:36:20.804 * Master replied to PING, replication can continue...
[14793] 06 Sep 17:36:20.804 # MASTER aborted replication with an error: ERR Can't SYNC while not connected with my master
[14793] 06 Sep 17:36:21.636 - Accepted 10.18.129.49:44279
[14793] 06 Sep 17:36:21.637 - Client closed connection
[14793] 06 Sep 17:36:21.804 * Connecting to MASTER...
[14793] 06 Sep 17:36:21.804 * MASTER <-> SLAVE sync started
[14793] 06 Sep 17:36:21.804 * Non blocking connect for SYNC fired the event.
[14793] 06 Sep 17:36:21.804 * Master replied to PING, replication can continue...
[14793] 06 Sep 17:36:21.804 # MASTER aborted replication with an error: ERR Can't SYNC while not connected with my master
[14793] 06 Sep 17:36:22.636 - Accepted 10.18.129.49:44281
[14793] 06 Sep 17:36:22.637 - Client closed connection
[14793] 06 Sep 17:36:22.804 * Connecting to MASTER...
[14793] 06 Sep 17:36:22.804 * MASTER <-> SLAVE sync started
[14793] 06 Sep 17:36:22.804 * Non blocking connect for SYNC fired the event.
[14793] 06 Sep 17:36:22.804 * Master replied to PING, replication can continue..

redis2的log:

[14796] 06 Sep 17:36:20.426 - Client closed connection
[14796] 06 Sep 17:36:20.636 * Connecting to MASTER...
[14796] 06 Sep 17:36:20.636 * MASTER <-> SLAVE sync started
[14796] 06 Sep 17:36:20.636 * Non blocking connect for SYNC fired the event.
[14796] 06 Sep 17:36:20.636 * Master replied to PING, replication can continue...
[14796] 06 Sep 17:36:20.636 # MASTER aborted replication with an error: ERR Can't SYNC while not connected with my master
[14796] 06 Sep 17:36:20.804 - Accepted 10.18.129.49:51034
[14796] 06 Sep 17:36:20.805 - Client closed connection
[14796] 06 Sep 17:36:21.636 * Connecting to MASTER...
[14796] 06 Sep 17:36:21.636 * MASTER <-> SLAVE sync started
[14796] 06 Sep 17:36:21.636 * Non blocking connect for SYNC fired the event.
[14796] 06 Sep 17:36:21.636 * Master replied to PING, replication can continue...
[14796] 06 Sep 17:36:21.637 # MASTER aborted replication with an error: ERR Can't SYNC while not connected with my master
[14796] 06 Sep 17:36:21.804 - Accepted 10.18.129.49:51036
[14796] 06 Sep 17:36:21.805 - Client closed connection
[14796] 06 Sep 17:36:22.636 - DB 0: 20 keys (0 volatile) in 32 slots HT.
[14796] 06 Sep 17:36:22.636 - 0 clients connected (0 slaves), 801176 bytes in use
[14796] 06 Sep 17:36:22.636 * Connecting to MASTER...
[14796] 06 Sep 17:36:22.636 * MASTER <-> SLAVE sync started
[14796] 06 Sep 17:36:22.636 * Non blocking connect for SYNC fired the event.
[14796] 06 Sep 17:36:22.636 * Master replied to PING, replication can continue..

两个redis就这样都进入SYNC失败的死循环状态。
我想到的疑问是:为什么原来的从库redis2会重新执行SYNC命令?
从上面的redis2的log第一行可以看到原先的主从连接断开了。
看了执行主从设置的源码replication.c,下面是redis1执行slaveof命令的代码,它在中间执行disconnectSlaves()导致原来的主从连接断开:

void slaveofCommand(redisClient *c) {
if (!strcasecmp(c->argv[1]->ptr,"no") &&!strcasecmp(c->argv[2]->ptr,"one")) {
// 省略了
} else {
// 省略了
/* There was no previous master or the user specified a different one,
* we can continue. */
sdsfree(server.masterhost);
server.masterhost = sdsp(c->argv[1]->ptr);
server.masterport = port;
if (server.master) freeClient(server.master);
disconnectSlaves(); /* Force our slaves to resync with us as well. */
cancelReplicationHandshake();
server.repl_state = REDIS_REPL_CONNECT;
redisLog(REDIS_NOTICE,"SLAVE OF %s:%d enabled (user request)",
server.masterhost, server.masterport);
}
addReply(c,shared.ok);
}

disconnectSlaves()旁边的注解是:Force our slaves to resync with us as well. 意思类似于先把你们(redis2)断开,等我(redis1)同步我的主库搞定后你们再来向我同步。这样导致redis2和redis1断开了,而redis2一开始作为从库如果它和主库断开它会不断尝试重新连接并执行SYNC命令直到成功。
了解了为什么redis2也执行SYNC命令后,第二个疑问是为什么两个redis的SYNC操作都会一直失败,实际上原因和第一个差不多。两个redis的log异常都是:ERR Can't SYNC while not connected with my master。这个log在代码中是:

void syncCommand(redisClient *c) {
/* ignore SYNC if already slave or in monitor mode */
if (c->flags & REDIS_SLAVE) return;

/* Refuse SYNC requests if we are a slave but the link with our master
* is not ok... */
if (server.masterhost && server.repl_state != REDIS_REPL_CONNECTED) {
addReplyError(c,"Can't SYNC while not connected with my master");
return;
}

/* SYNC can't be issued when the server has pending data to send to
* the client about already issued commands. We need a fresh reply
* buffer registering the differences between the BGSAVE and the current
* dataset, so that we can copy to other slaves if needed. */
if (listLength(c->reply) != 0) {
addReplyError(c,"SYNC is invalid with pending input");
return;
}
//省略
}

syncCommand函数是Redis作为主库收到从库发来的SYNC命令时的处理,看上面注释部分“Refuse SYNC requests if we are a slave but the link with our master is not ok...”。当redis1作为主库收到从库的SYNC命令,会执行syncCommand函数,其中if (server.masterhost && server.repl_state != REDIS_REPL_CONNECTED)... ,redis1刚好设置为别的主库(redis2)的从库但还没完成同步工作(redis1需要向redis2发送SYNC请求并且返回成功才能完成同步,而redis2处理redis1的SYNC请求时又需要redis1处理好redis2的SYNC请求才行,这导致死锁了),所以这个判断返回true,redis1直接reply error:Can't SYNC while not connected with my master)。redis2的情况也一样,所以双方都处在Can't SYNC while not connected with my master的状态。
ups快递客服电话24小时 贷款记录在征信保留几年? 安徽徽商城有限公司公司简介 安徽省徽商集团新能源股份有限公司基本情况 安徽省徽商集团有限公司经营理念 2019哈尔滨煤气费怎么有税? 快手删除的作品如何恢复 体育理念体育理念 有关体育的格言和理念 什么是体育理念 万里挑一算彩礼还是见面礼 绿萝扦插多少天后发芽 绿萝扦插多久发芽 扦插绿萝多久发芽 炖牛排骨的做法和配料 网络诈骗定罪标准揭秘 “流水不争先”是什么意思? mc中钻石装备怎么做 为什么我的MC里的钻石块是这样的?我想要那种。是不是版本的问题?如果是... 带“偷儿”的诗句 “君不见巴丘古城如培塿”的出处是哪里 带“奈何”的诗句大全(229句) 里翁行()拼音版、注音及读音 带“不虑”的诗句 “鲁肃当年万人守”的出处是哪里 无尘防尘棚 进出口报关流程,越详细越好。谢谢大家指教。 双线桥不是看化合价升多少就标多少的吗?为什么CL2+2KI=2KCL+I2中I失... 出师表高锰酸钾有画面了吗 2021年幼儿园新学期致家长一封信 电脑屏幕一条黑线怎么办? 销售代理商销售代理商的特点 商业代理商业代理的特征 如何看微信有没有开通微众银行 为什么微众没有开户 微众银行怎么开户 微众银行APP开户流程是什么? 唐古拉山海拔唐古拉山海拔是多少 怎么看待取消跳广场舞的人的退休金 如何选购新鲜的蓝田水柿? 恭城水柿柿树作用 创维洗衣机使用教程 创维全自动洗衣机怎么使用 自动开门器 狗羊属相婚姻相配吗 3岁的小孩不会说话怎么办 3岁孩子不会说话,应该挂什么科? 3岁小孩不会说话正常吗 鹿茸炖乌鸡怎么做? 新型冠状肺炎吃什么药可以预防 冰箱上电后一直响 食品生产许可证编号开头为“ G”。 fate里面master是随机选择吗? coursework master 是什么? 如何创建从SQL到Oracle的DBlink 摄像头显示设备离线怎么回事? 详细解释一下这段代码是什么意思。 acaa认证证书和adobe认证证书的区别 oracle中如何创建dblink ASP循环打开页面 蓝牙技术的优缺点 澳洲 Westpac 计算机中的英文缩写 客户要求选个带主控(master)的交换机,什么是主控? s7-1200 4 x i/o link master 怎么用 404 Not Found 链路聚合,怎么选master路由器的 IO link master等级 谁有Alesis ML-9600说明书 linux下安装jdk并设置环境变量 master link是什么意思 摄像机离线了怎么处理? 小眯眼,摄像头老是显示设备离线,要怎么办? 东风天龙遥控器太大,可以改小点吗 遥控器声音很大怎么调 立式空调遥控器越大空调越好还是越小空调越好? 遥控器声音大怎么调 最大的电视遥控器有多大? 禹鼎遥控器大功率怎么调 空调遥控器上有个大拇指是什么意思? “遥控器耗电量大”怎么办 机顶盒没有声音需要用遥控器调大 怎么办? 遥控器耗电大是什么原因,应如何处理? 怎样给大门摇控器争大功能 空调遥控器的数字越大越低吗 美博空调摇控器显示大拇指什么意思? 空调遥控器的数字越大越冷吗 遥控飞机的遥控器最大几通道,遥控距离多远 空调遥控器如何把风速调大 遥控器的简介 大疆精灵4遥控器最大可以夹多宽 万能空调遥控器风大怎么调?
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com