返回

Zookeeper源码篇14:集群数据同步(广播模式)建立通信连接原理源码分析

后端

Zookeeper是一个分布式协调服务,它为分布式应用提供了一系列功能,包括配置管理、命名服务、分布式锁等。Zookeeper采用集群模式,由多个服务器组成,其中一个服务器作为Leader,其他服务器作为Follower。Leader负责处理客户端的请求并维护数据的一致性,Follower则负责同步Leader的数据并提供冗余。

在Zookeeper集群中,Leader和Follower之间需要建立通信连接以进行数据同步。Zookeeper使用TCP协议进行通信,Leader和Follower通过TCP连接交换数据。Leader将数据变更广播给Follower,Follower收到数据变更后将其应用到本地。

Zookeeper集群数据同步(广播模式)建立通信连接的原理如下:

  1. Leader启动时,首先会创建一个TCP服务端,并监听一个端口(默认端口为2181)。
  2. Follower启动时,首先会创建一个TCP客户端,并连接到Leader的TCP服务端。
  3. Leader和Follower建立TCP连接成功后,Leader会向Follower发送一个连接请求。
  4. Follower收到连接请求后,会向Leader发送一个连接响应。
  5. Leader收到连接响应后,会将Follower添加到其连接列表中。
  6. 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之间就建立了通信连接。