华为云开发者联盟 如何搭建redis的双主

如何搭建redis的双主

如何搭建redis的双主?这方面最具代表性的是dynamo和bigtable2篇论文所阐述的思路。前者是一个完全无中心的设计,节点之间通过gossip方式传递集群信息,数据保证最终一致性后者是一个中心化的方案设计,通过类似一个分布式锁服务来保证强一致性,数据写入先写内存和redolog,然后定期compat归并到磁...

yetaoseo  ·  2021-11-13 18:30:03 发布

如何搭建redis的双主?

这方面最具代表性的是dynamo和bigtable2篇论文所阐述的思路。前者是一个完全无中心的设计,节点之间通过gossip方式传递集群信息,数据保证最终一致性

后者是一个中心化的方案设计,通过类似一个分布式锁服务来保证强一致性,数据写入先写内存和redolog,然后定期compat归并到磁盘上,将随机写优化为顺序写,提高写入性能。

如何搭建redis的双主_redis双主

两个Redis实例互相SLAVEOF会怎样?

今天尝试配置RedisSentinel来监控Redis服务器,中间由于某些设想我突然想到如果两个Redis实例互相slaveof会怎样。以下是我的试验:

两个Redis实例,redis1配置作为master,redis2配置作为slave:slaveofredis1。

启动redis1、redis2。

启动成功并且redis2也成功slaveofredis1后,redis-cli连接redis1,执行命令将redis1设置为redis2的从库:

slaveof[redis2IP][redis2port]

执行后的结果是......两个redis都在重复抛出SYNC命令执行失败的log,也就是显然两个redis不能互相作为从库。

redis1执行slaveof后的log:

[14793]06Sep17:36:20.426*SLAVEOF10.18.129.49:9778enabled(userrequest)

[14793]06Sep17:36:20.636-Accepted10.18.129.49:44277

[14793]06Sep17:36:20.637-Clientclosedconnection

[14793]06Sep17:36:20.804*ConnectingtoMASTER...

[14793]06Sep17:36:20.804*MASTERSLAVEsyncstarted

[14793]06Sep17:36:20.804*NonblockingconnectforSYNCfiredtheevent.

[14793]06Sep17:36:20.804*MasterrepliedtoPING,replicationcancontinue...

[14793]06Sep17:36:20.804#MASTERabortedreplicationwithanerror:ERRCan'tSYNCwhilenotconnectedwithmymaster

[14793]06Sep17:36:21.636-Accepted10.18.129.49:44279

[14793]06Sep17:36:21.637-Clientclosedconnection

[14793]06Sep17:36:21.804*ConnectingtoMASTER...

[14793]06Sep17:36:21.804*MASTERSLAVEsyncstarted

[14793]06Sep17:36:21.804*NonblockingconnectforSYNCfiredtheevent.

[14793]06Sep17:36:21.804*MasterrepliedtoPING,replicationcancontinue...

[14793]06Sep17:36:21.804#MASTERabortedreplicationwithanerror:ERRCan'tSYNCwhilenotconnectedwithmymaster

[14793]06Sep17:36:22.636-Accepted10.18.129.49:44281

[14793]06Sep17:36:22.637-Clientclosedconnection

[14793]06Sep17:36:22.804*ConnectingtoMASTER...

[14793]06Sep17:36:22.804*MASTERSLAVEsyncstarted

[14793]06Sep17:36:22.804*NonblockingconnectforSYNCfiredtheevent.

[14793]06Sep17:36:22.804*MasterrepliedtoPING,replicationcancontinue..

redis2的log:

[14796]06Sep17:36:20.426-Clientclosedconnection

[14796]06Sep17:36:20.636*ConnectingtoMASTER...

[14796]06Sep17:36:20.636*MASTERSLAVEsyncstarted

[14796]06Sep17:36:20.636*NonblockingconnectforSYNCfiredtheevent.

[14796]06Sep17:36:20.636*MasterrepliedtoPING,replicationcancontinue...

[14796]06Sep17:36:20.636#MASTERabortedreplicationwithanerror:ERRCan'tSYNCwhilenotconnectedwithmymaster

[14796]06Sep17:36:20.804-Accepted10.18.129.49:51034

[14796]06Sep17:36:20.805-Clientclosedconnection

[14796]06Sep17:36:21.636*ConnectingtoMASTER...

[14796]06Sep17:36:21.636*MASTERSLAVEsyncstarted

[14796]06Sep17:36:21.636*NonblockingconnectforSYNCfiredtheevent.

[14796]06Sep17:36:21.636*MasterrepliedtoPING,replicationcancontinue...

[14796]06Sep17:36:21.637#MASTERabortedreplicationwithanerror:ERRCan'tSYNCwhilenotconnectedwithmymaster

[14796]06Sep17:36:21.804-Accepted10.18.129.49:51036

[14796]06Sep17:36:21.805-Clientclosedconnection

[14796]06Sep17:36:22.636-DB0:20keys(0volatile)in32slotsHT.

[14796]06Sep17:36:22.636-0clientsconnected(0slaves),801176bytesinuse

[14796]06Sep17:36:22.636*ConnectingtoMASTER...

[14796]06Sep17:36:22.636*MASTERSLAVEsyncstarted

[14796]06Sep17:36:22.636*NonblockingconnectforSYNCfiredtheevent.

[14796]06Sep17:36:22.636*MasterrepliedtoPING,replicationcancontinue..

两个redis就这样都进入SYNC失败的死循环状态。

我想到的疑问是:为什么原来的从库redis2会重新执行SYNC命令?

从上面的redis2的log第一行可以看到原先的主从连接断开了。

看了执行主从设置的源码replication.c,下面是redis1执行slaveof命令的代码,它在中间执行disconnectSlaves()导致原来的主从连接断开:

voidslaveofCommand(redisClient*c){

if(!strcasecmp(c->argv[1]->ptr,"no")&&!strcasecmp(c->argv[2]->ptr,"one")){

//省略了

}else{

//省略了

/*Therewasnopreviousmasterortheuserspecifiedadifferentone,

*wecancontinue.*/

sdsfree(server.masterhost);

server.masterhost=sdsdup(c->argv[1]->ptr);

server.masterport=port;

if(server.master)freeClient(server.master);

disconnectSlaves();/*Forceourslavestoresyncwithusaswell.*/

cancelReplicationHandshake();

server.repl_state=REDIS_REPL_CONNECT;

redisLog(REDIS_NOTICE,"SLAVEOF%s:%denabled(userrequest)",

server.masterhost,server.masterport);

addReply(c,shared.ok);

disconnectSlaves()旁边的注解是:Forceourslavestoresyncwithusaswell.意思类似于先把你们(redis2)断开,等我(redis1)同步我的主库搞定后你们再来向我同步。这样导致redis2和redis1断开了,而redis2一开始作为从库如果它和主库断开它会不断尝试重新连接并执行SYNC命令直到成功。

了解了为什么redis2也执行SYNC命令后,第二个疑问是为什么两个redis的SYNC操作都会一直失败,实际上原因和第一个差不多。两个redis的log异常都是:ERRCan'tSYNCwhilenotconnectedwithmymaster。这个log在代码中是:

voidsyncCommand(redisClient*c){

/*ignoreSYNCifalreadyslaveorinmonitormode*/

if(c->flags&REDIS_SLAVE)return;

/*RefuseSYNCrequestsifweareaslavebutthelinkwithourmaster

*isnotok...*/

if(server.masterhost&&server.repl_state!=REDIS_REPL_CONNECTED){

addReplyError(c,"Can'tSYNCwhilenotconnectedwithmymaster");

return;

/*SYNCcan'tbeissuedwhentheserverhaspendingdatatosendto

*theclientaboutalreadyissuedcommands.Weneedafreshreply

*bufferregisteringthedifferencesbetweentheBGSAVEandthecurrent

*dataset,sothatwecancopytootherslavesifneeded.*/

if(listLength(c->reply)!=0){

addReplyError(c,"SYNCisinvalidwithpendinginput");

return;

syncCommand函数是Redis作为主库收到从库发来的SYNC命令时的处理,看上面注释部分“RefuseSYNCrequestsifweareaslavebutthelinkwithourmasterisnotok...”。当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直接replyerror:Can'tSYNCwhilenotconnectedwithmymaster)。redis2的情况也一样,所以双方都处在Can'tSYNCwhilenotconnectedwithmymaster的状态。

redis三主三从部署在两台主机上,如何查看谁是主谁是从

解决问题的法:对master节点采用多个slave的法,直接读取slave中的数据,即可解决问题。slave要采用非集群模式即可。可以私聊我~

如何搭建redis的双主_redis双主_02

windows redis 主从是什么意思

首先说下部署方案:在两台服务器上分别部署一套Redis,两台服务器共用一个浮动IP,两套Redis实例则做Master-Slave,始终由浮动IP指向服务器上的Redis实例做Master。使用HA软件来检测Redis实例的运行情况。

如果从机出现异常,则重启从机Redis实例;

当主机出现异常,则进行如下操作:

1) Slave主动断开与Master的连接(通过HA软件调用预置脚本实现),然后HA软件将浮动IP指向备机,进行主备机切换;

2) 切换后,HA软件尝试重启现备机的Redis实例,重启成功后将其配置为现主机Redis实例的Slave,然后开始主从复制。

断开与Master连接与重启实例的命令比较简单,就不在此贴出了。

这个方案可能会对业务造成短时影响(要看HA软件的效率),但是对客户端来讲主从切换是不感知的。

~如果你认可我的回答,请及时点击【采纳为满意回答】按钮

~~手机提问的朋友在客户端右上角评价点【满意】即可。支持一下感觉挺不错的

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐

  • 浏览量 951
  • 收藏 0
  • 0

所有评论(0)

查看更多评论 
已为社区贡献37条内容