简介
- 主从服务器的功能区别。
- 主从服务器的连接建立。
- 主从服务器之间的数据同步流程。
- 连接建立时的全量数据同步。
- 主从状态同步后的增量同步更新。
主从服务器的功能
-
主服务器接受读写请求,从服务器只接受读请求。通常如果是主从模式,client会通过proxy来访问redis,proxy会对请求进行解析,如果是写请求,转发给master_redis,如果是读请求,则转发给slave_redis。
主从服务器的连接建立
前提:通过github下载了最新的redis源码,并且通过make的方式编译好了可执行文件。切到redis/src/路径下。
- 启动所有的redis服务器,包括master和slave服务器。假设以如下方式启动了3个redis-server。
./redis-server --port 6377
./redis-server --port 6378
./redis-server --port 6379
其中以6377服务器作为master。
- 通过redis-cli分别连接到从服务器6378和6379,输入以下命令。
./redis-cli -p 6378
./redis-cli -p 6379
- 在redis-cli中输入以下命令将6378和6379设为slave服务器。
slaveof 127.0.0.1 6378
slaveof 127.0.0.1 6379
此时会看到6377的master_redis服务器输出了以下日志:
- 测试主从效果,连接主redis 6377,输入set master 6377。分别连接6378和6379,输入get master可获得"6377"。
- slave服务器和主断开连接成为新的主,命令:
slaveof no one
- 总结:通过使用redis原生的主从功能,可以发现,主从机制可以有效的分散来自客户端的数据读取的压力,但是写数据依然是瓶颈并且未突破单机上限,总的存储功能受限于所在的主机的内存和磁盘。而且需要通过客户端手动配置主从,非常的落后,还需要健全的配套设施辅助主从功能。
主从服务器的数据同步流程
- 从服务器首次连到主服务器时,主服务器将数据全量的同步到从服务器中,通常使用RDB的方式,将内存数据以RDB的方式打包,然后通过网络传输到从服务器中。
- 当从服务器收到了主服务器通过过来的全量数据后,后续的数据采用增量的方式将数据同步给slave服务器。
- 主从服务器状态一致性的判定。
- 主从服务器网络波动导致状态不一致时,断线重连。
主从服务器的连接建立和同步全量数据
slave服务器:
- 连接建立。在serverCron中定期执行replicationCron,调用connectWithMaster和master服务器建立连接。
- 在syncWithMaster 刚建立连接时通过该处理函数来做一些信息同步。
- 在readSyncBulkPayload 建立连接后 首先需要同步一次全量的主的数据 通过该函数来接受master的RDB文件,之后再replicationCreateMasterClient 承接上一步在这里一路设置处理函数为下面的readQueryFromClient。
- 后续网络事件处理函数都调用readQueryFromClient进行处理。由于后续Master会把写命令同步给slave服务器,因此从服务器可以把master服务器作为客户端进行处理,处理其传输过来的每一个命令。
master服务器: - 始终使用通用的readQueryFromClient处理函数处理网络消息,将Slave服务器作为特殊的客户端进行处理。
主从服务器增量同步数据更新
- master定时发送 "REPLCONF GETACK"获取slave服务器的一些信息。
- slave服务器调用replconfCommand命令处理replconf请求,该函数会回发 "REPLCONF ACK c->reploff" 返回其已经接收到的包的字节数。
- master收到slave的ack后,修改slave服务器收到的字符的长度,后续已收到的字节将不再发送给slave。