Zookeeper源码篇14:集群数据同步(广播模式)建立通信连接原理源码分析
2023-10-03 14:40:52
Zookeeper是一个分布式协调服务,它为分布式应用提供了一系列功能,包括配置管理、命名服务、分布式锁等。Zookeeper采用集群模式,由多个服务器组成,其中一个服务器作为Leader,其他服务器作为Follower。Leader负责处理客户端的请求并维护数据的一致性,Follower则负责同步Leader的数据并提供冗余。
在Zookeeper集群中,Leader和Follower之间需要建立通信连接以进行数据同步。Zookeeper使用TCP协议进行通信,Leader和Follower通过TCP连接交换数据。Leader将数据变更广播给Follower,Follower收到数据变更后将其应用到本地。
Zookeeper集群数据同步(广播模式)建立通信连接的原理如下:
- Leader启动时,首先会创建一个TCP服务端,并监听一个端口(默认端口为2181)。
- Follower启动时,首先会创建一个TCP客户端,并连接到Leader的TCP服务端。
- Leader和Follower建立TCP连接成功后,Leader会向Follower发送一个连接请求。
- Follower收到连接请求后,会向Leader发送一个连接响应。
- Leader收到连接响应后,会将Follower添加到其连接列表中。
- Follower收到Leader的连接响应后,也会将Leader添加到其连接列表中。
至此,Leader和Follower之间就建立了通信连接。Leader可以将数据变更广播给Follower,Follower可以收到数据变更并将其应用到本地。
下面我们通过源码分析来详细了解一下Leader和Follower是如何建立通信连接的。
在Leader端,建立TCP服务端并监听端口的代码位于ZooKeeperServer类中:
public void start() {
// 创建TCP服务端
serverSocket = new ServerSocket(port);
// 监听端口
serverSocket.setSoTimeout(500);
// 启动TCP服务端
startServerLoop();
}
在Follower端,创建TCP客户端并连接到Leader的TCP服务端的代码位于ClientCnxn类中:
public ClientCnxn(String host, int port) {
// 创建TCP客户端
clientCnxnSocket = new Socket();
// 连接到Leader的TCP服务端
clientCnxnSocket.connect(new InetSocketAddress(host, port), connectTimeout);
}
Leader向Follower发送连接请求的代码位于ZooKeeperServer类中:
public void sendConnectRequest(PrintWriter pw) {
// 发送连接请求
pw.println("stat req");
pw.flush();
}
Follower收到连接请求后,向Leader发送连接响应的代码位于ClientCnxn类中:
public void sendConnectResponse() {
// 发送连接响应
output.write(0);
output.writeInt(sessionId);
output.writeInt(passwd == null ? 0 : passwd.length);
if (passwd != null) {
output.write(passwd);
}
output.flush();
}
Leader收到连接响应后,将Follower添加到其连接列表中的代码位于ZooKeeperServer类中:
public void addConnection(int sock, ZooKeeperServerConnection cnxn) {
// 将Follower添加到连接列表中
connections.add(sock, cnxn);
}
Follower收到Leader的连接响应后,将Leader添加到其连接列表中的代码位于ClientCnxn类中:
public void updateNow() {
// 将Leader添加到连接列表中
sessions.add(zkSessionId);
}
至此,Leader和Follower之间就建立了通信连接。