You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by hx...@apache.org on 2021/03/10 08:08:50 UTC

[iotdb] branch seperate_thrift created (now 1f5e7b2)

This is an automated email from the ASF dual-hosted git repository.

hxd pushed a change to branch seperate_thrift
in repository https://gitbox.apache.org/repos/asf/iotdb.git.


      at 1f5e7b2  seperate thrift module into 3 parts; extract Node Serialization from Server module into Cluster module

This branch includes the following new commits:

     new 1f5e7b2  seperate thrift module into 3 parts; extract Node Serialization from Server module into Cluster module

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[iotdb] 01/01: seperate thrift module into 3 parts; extract Node Serialization from Server module into Cluster module

Posted by hx...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

hxd pushed a commit to branch seperate_thrift
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 1f5e7b2bda07e8c4d653e5fa327755c8606daeff
Author: xiangdong huang <sa...@gmail.com>
AuthorDate: Wed Mar 10 16:08:16 2021 +0800

    seperate thrift module into 3 parts; extract Node Serialization from Server module into Cluster module
---
 cluster/pom.xml                                    |  15 ++
 .../apache/iotdb/cluster/RemoteTsFileResource.java |   5 +-
 .../org/apache/iotdb/cluster/log/HardState.java    |   6 +-
 .../iotdb/cluster/log/logtypes/AddNodeLog.java     |   6 +-
 .../iotdb/cluster/log/logtypes/RemoveNodeLog.java  |   6 +-
 .../log/snapshot/PullSnapshotTaskDescriptor.java   |   6 +-
 .../iotdb/cluster/partition/slot/SlotManager.java  |   6 +-
 .../cluster/partition/slot/SlotPartitionTable.java |   5 +-
 .../iotdb/cluster/utils/NodeSerializeUtils.java    |  90 ++++++++++
 .../iotdb/cluster/utils/SerializeUtilTest.java     |  13 ++
 grafana/pom.xml                                    |   4 +
 jdbc/pom.xml                                       |   5 -
 pom.xml                                            |   2 +
 server/pom.xml                                     |   5 +
 .../org/apache/iotdb/db/utils/SerializeUtils.java  |  62 -------
 .../apache/iotdb/db/utils/SerializeUtilsTest.java  |  13 --
 service-rpc/pom.xml                                |   7 +
 session/pom.xml                                    |   5 -
 thrift-cluster/README.md                           |  22 +++
 thrift-cluster/pom.xml                             |  44 +++++
 thrift-cluster/rpc-changelist.md                   | 181 +++++++++++++++++++++
 .../src/main/thrift/cluster.thrift                 |   0
 thrift-sync/README.md                              |  22 +++
 thrift-sync/pom.xml                                |  44 +++++
 thrift-sync/rpc-changelist.md                      | 181 +++++++++++++++++++++
 .../src/main/thrift/sync.thrift                    |   0
 thrift/README.md                                   |  22 +++
 27 files changed, 673 insertions(+), 104 deletions(-)

diff --git a/cluster/pom.xml b/cluster/pom.xml
index 1d29693..7347a3c 100644
--- a/cluster/pom.xml
+++ b/cluster/pom.xml
@@ -76,6 +76,21 @@
                     <artifactId>libthrift</artifactId>
                 </exclusion>
             </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.iotdb</groupId>
+            <artifactId>iotdb-thrift-cluster</artifactId>
+            <version>0.12.0-SNAPSHOT</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.thrift</groupId>
+                    <artifactId>libthrift</artifactId>
+                </exclusion>
+            </exclusions>
             <scope>compile</scope>
         </dependency>
         <dependency>
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/RemoteTsFileResource.java b/cluster/src/main/java/org/apache/iotdb/cluster/RemoteTsFileResource.java
index fdf492a..04fb776 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/RemoteTsFileResource.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/RemoteTsFileResource.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.cluster;
 
 import org.apache.iotdb.cluster.rpc.thrift.Node;
+import org.apache.iotdb.cluster.utils.NodeSerializeUtils;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
 import org.apache.iotdb.db.utils.SerializeUtils;
@@ -82,7 +83,7 @@ public class RemoteTsFileResource extends TsFileResource {
   }
 
   public void serialize(DataOutputStream dataOutputStream) {
-    SerializeUtils.serialize(source, dataOutputStream);
+    NodeSerializeUtils.serialize(source, dataOutputStream);
     try {
       // the path here is only for the remote node to get a download link, so it does not matter
       // if it is absolute
@@ -102,7 +103,7 @@ public class RemoteTsFileResource extends TsFileResource {
 
   public void deserialize(ByteBuffer buffer) {
     source = new Node();
-    SerializeUtils.deserialize(source, buffer);
+    NodeSerializeUtils.deserialize(source, buffer);
     setFile(new File(SerializeUtils.deserializeString(buffer)));
 
     timeIndex =
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/log/HardState.java b/cluster/src/main/java/org/apache/iotdb/cluster/log/HardState.java
index 03e12fc..2e9e172 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/log/HardState.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/log/HardState.java
@@ -20,7 +20,7 @@
 package org.apache.iotdb.cluster.log;
 
 import org.apache.iotdb.cluster.rpc.thrift.Node;
-import org.apache.iotdb.db.utils.SerializeUtils;
+import org.apache.iotdb.cluster.utils.NodeSerializeUtils;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import org.apache.commons.lang3.builder.EqualsBuilder;
@@ -46,7 +46,7 @@ public class HardState {
     int isNull = buffer.get();
     if (isNull == 1) {
       Node node = new Node();
-      SerializeUtils.deserialize(node, buffer);
+      NodeSerializeUtils.deserialize(node, buffer);
       res.setVoteFor(node);
     } else {
       res.setVoteFor(null);
@@ -63,7 +63,7 @@ public class HardState {
         dataOutputStream.writeByte(0);
       } else {
         dataOutputStream.writeByte(1);
-        SerializeUtils.serialize(voteFor, dataOutputStream);
+        NodeSerializeUtils.serialize(voteFor, dataOutputStream);
       }
     } catch (IOException e) {
       // unreachable
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/log/logtypes/AddNodeLog.java b/cluster/src/main/java/org/apache/iotdb/cluster/log/logtypes/AddNodeLog.java
index 75bb8f5..ea41685 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/log/logtypes/AddNodeLog.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/log/logtypes/AddNodeLog.java
@@ -21,7 +21,7 @@ package org.apache.iotdb.cluster.log.logtypes;
 
 import org.apache.iotdb.cluster.log.Log;
 import org.apache.iotdb.cluster.rpc.thrift.Node;
-import org.apache.iotdb.db.utils.SerializeUtils;
+import org.apache.iotdb.cluster.utils.NodeSerializeUtils;
 
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
@@ -50,7 +50,7 @@ public class AddNodeLog extends Log {
       dataOutputStream.writeLong(getCurrLogIndex());
       dataOutputStream.writeLong(getCurrLogTerm());
 
-      SerializeUtils.serialize(newNode, dataOutputStream);
+      NodeSerializeUtils.serialize(newNode, dataOutputStream);
     } catch (IOException e) {
       // ignored
     }
@@ -67,7 +67,7 @@ public class AddNodeLog extends Log {
     setCurrLogTerm(buffer.getLong());
 
     newNode = new Node();
-    SerializeUtils.deserialize(newNode, buffer);
+    NodeSerializeUtils.deserialize(newNode, buffer);
   }
 
   @Override
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/log/logtypes/RemoveNodeLog.java b/cluster/src/main/java/org/apache/iotdb/cluster/log/logtypes/RemoveNodeLog.java
index 19359c2..8a84023 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/log/logtypes/RemoveNodeLog.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/log/logtypes/RemoveNodeLog.java
@@ -21,7 +21,7 @@ package org.apache.iotdb.cluster.log.logtypes;
 
 import org.apache.iotdb.cluster.log.Log;
 import org.apache.iotdb.cluster.rpc.thrift.Node;
-import org.apache.iotdb.db.utils.SerializeUtils;
+import org.apache.iotdb.cluster.utils.NodeSerializeUtils;
 
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
@@ -41,7 +41,7 @@ public class RemoveNodeLog extends Log {
       dataOutputStream.writeLong(getCurrLogIndex());
       dataOutputStream.writeLong(getCurrLogTerm());
 
-      SerializeUtils.serialize(removedNode, dataOutputStream);
+      NodeSerializeUtils.serialize(removedNode, dataOutputStream);
     } catch (IOException e) {
       // ignored
     }
@@ -54,7 +54,7 @@ public class RemoveNodeLog extends Log {
     setCurrLogTerm(buffer.getLong());
 
     removedNode = new Node();
-    SerializeUtils.deserialize(removedNode, buffer);
+    NodeSerializeUtils.deserialize(removedNode, buffer);
   }
 
   public Node getRemovedNode() {
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/log/snapshot/PullSnapshotTaskDescriptor.java b/cluster/src/main/java/org/apache/iotdb/cluster/log/snapshot/PullSnapshotTaskDescriptor.java
index b811f1f..a2216fd 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/log/snapshot/PullSnapshotTaskDescriptor.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/log/snapshot/PullSnapshotTaskDescriptor.java
@@ -21,7 +21,7 @@ package org.apache.iotdb.cluster.log.snapshot;
 
 import org.apache.iotdb.cluster.partition.PartitionGroup;
 import org.apache.iotdb.cluster.rpc.thrift.Node;
-import org.apache.iotdb.db.utils.SerializeUtils;
+import org.apache.iotdb.cluster.utils.NodeSerializeUtils;
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
@@ -77,7 +77,7 @@ public class PullSnapshotTaskDescriptor {
 
     dataOutputStream.writeInt(previousHolders.size());
     for (Node previousHolder : previousHolders) {
-      SerializeUtils.serialize(previousHolder, dataOutputStream);
+      NodeSerializeUtils.serialize(previousHolder, dataOutputStream);
     }
 
     dataOutputStream.writeBoolean(requireReadOnly);
@@ -94,7 +94,7 @@ public class PullSnapshotTaskDescriptor {
     previousHolders = new PartitionGroup();
     for (int i = 0; i < holderSize; i++) {
       Node node = new Node();
-      SerializeUtils.deserialize(node, dataInputStream);
+      NodeSerializeUtils.deserialize(node, dataInputStream);
       previousHolders.add(node);
     }
 
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/partition/slot/SlotManager.java b/cluster/src/main/java/org/apache/iotdb/cluster/partition/slot/SlotManager.java
index 37cc0f2..528119f 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/partition/slot/SlotManager.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/partition/slot/SlotManager.java
@@ -6,8 +6,8 @@ package org.apache.iotdb.cluster.partition.slot;
 
 import org.apache.iotdb.cluster.config.ClusterDescriptor;
 import org.apache.iotdb.cluster.rpc.thrift.Node;
+import org.apache.iotdb.cluster.utils.NodeSerializeUtils;
 import org.apache.iotdb.db.exception.StorageEngineException;
-import org.apache.iotdb.db.utils.SerializeUtils;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -298,7 +298,7 @@ public class SlotManager {
     private void serialize(DataOutputStream outputStream) throws IOException {
       outputStream.writeInt(slotStatus.ordinal());
       if (slotStatus == SlotStatus.PULLING || slotStatus == SlotStatus.PULLING_WRITABLE) {
-        SerializeUtils.serialize(source, outputStream);
+        NodeSerializeUtils.serialize(source, outputStream);
       } else if (slotStatus == SlotStatus.SENDING) {
         outputStream.writeInt(snapshotReceivedCount);
       }
@@ -310,7 +310,7 @@ public class SlotManager {
       if (descriptor.slotStatus == SlotStatus.PULLING
           || descriptor.slotStatus == SlotStatus.PULLING_WRITABLE) {
         descriptor.source = new Node();
-        SerializeUtils.deserialize(descriptor.source, buffer);
+        NodeSerializeUtils.deserialize(descriptor.source, buffer);
       } else if (descriptor.slotStatus == SlotStatus.SENDING) {
         descriptor.snapshotReceivedCount = buffer.getInt();
       }
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/partition/slot/SlotPartitionTable.java b/cluster/src/main/java/org/apache/iotdb/cluster/partition/slot/SlotPartitionTable.java
index 8c25a63..469e84d 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/partition/slot/SlotPartitionTable.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/partition/slot/SlotPartitionTable.java
@@ -12,6 +12,7 @@ import org.apache.iotdb.cluster.partition.PartitionGroup;
 import org.apache.iotdb.cluster.partition.PartitionTable;
 import org.apache.iotdb.cluster.partition.slot.SlotStrategy.DefaultStrategy;
 import org.apache.iotdb.cluster.rpc.thrift.Node;
+import org.apache.iotdb.cluster.utils.NodeSerializeUtils;
 import org.apache.iotdb.db.utils.SerializeUtils;
 
 import org.slf4j.Logger;
@@ -310,7 +311,7 @@ public class SlotPartitionTable implements PartitionTable {
       dataOutputStream.writeInt(totalSlotNumbers);
       dataOutputStream.writeInt(nodeSlotMap.size());
       for (Entry<Node, List<Integer>> entry : nodeSlotMap.entrySet()) {
-        SerializeUtils.serialize(entry.getKey(), dataOutputStream);
+        NodeSerializeUtils.serialize(entry.getKey(), dataOutputStream);
         SerializeUtils.serializeIntList(entry.getValue(), dataOutputStream);
       }
 
@@ -341,7 +342,7 @@ public class SlotPartitionTable implements PartitionTable {
     for (int i = 0; i < size; i++) {
       Node node = new Node();
       List<Integer> slots = new ArrayList<>();
-      SerializeUtils.deserialize(node, buffer);
+      NodeSerializeUtils.deserialize(node, buffer);
       SerializeUtils.deserializeIntList(slots, buffer);
       nodeSlotMap.put(node, slots);
       idNodeMap.put(node.getNodeIdentifier(), node);
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/utils/NodeSerializeUtils.java b/cluster/src/main/java/org/apache/iotdb/cluster/utils/NodeSerializeUtils.java
new file mode 100644
index 0000000..6e14cc3
--- /dev/null
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/utils/NodeSerializeUtils.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.cluster.utils;
+
+import org.apache.iotdb.cluster.rpc.thrift.Node;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class NodeSerializeUtils {
+
+  public static void serialize(Node node, DataOutputStream dataOutputStream) {
+    try {
+      byte[] internalIpBytes = node.internalIp.getBytes();
+      dataOutputStream.writeInt(internalIpBytes.length);
+      dataOutputStream.write(internalIpBytes);
+      dataOutputStream.writeInt(node.metaPort);
+      dataOutputStream.writeInt(node.nodeIdentifier);
+      dataOutputStream.writeInt(node.dataPort);
+      dataOutputStream.writeInt(node.clientPort);
+      byte[] clientIpBytes = node.clientIp.getBytes();
+      dataOutputStream.writeInt(clientIpBytes.length);
+      dataOutputStream.write(clientIpBytes);
+    } catch (IOException e) {
+      // unreachable
+    }
+  }
+
+  public static void deserialize(Node node, ByteBuffer buffer) {
+    int internalIpLength = buffer.getInt();
+    byte[] internalIpBytes = new byte[internalIpLength];
+    buffer.get(internalIpBytes);
+    node.setInternalIp(new String(internalIpBytes));
+    node.setMetaPort(buffer.getInt());
+    node.setNodeIdentifier(buffer.getInt());
+    node.setDataPort(buffer.getInt());
+    node.setClientPort(buffer.getInt());
+    int clientIpLength = buffer.getInt();
+    byte[] clientIpBytes = new byte[clientIpLength];
+    buffer.get(clientIpBytes);
+    node.setClientIp(new String(clientIpBytes));
+  }
+
+  public static void deserialize(Node node, DataInputStream stream) throws IOException {
+    int ipLength = stream.readInt();
+    byte[] ipBytes = new byte[ipLength];
+    int readIpSize = stream.read(ipBytes);
+    if (readIpSize != ipLength) {
+      throw new IOException(
+          String.format(
+              "No sufficient bytes read when deserializing the ip of a node: %d/%d",
+              readIpSize, ipLength));
+    }
+    node.setInternalIp(new String(ipBytes));
+    node.setMetaPort(stream.readInt());
+    node.setNodeIdentifier(stream.readInt());
+    node.setDataPort(stream.readInt());
+    node.setClientPort(stream.readInt());
+
+    int clientIpLength = stream.readInt();
+    byte[] clientIpBytes = new byte[clientIpLength];
+    int readClientIpSize = stream.read(clientIpBytes);
+    if (readClientIpSize != clientIpLength) {
+      throw new IOException(
+          String.format(
+              "No sufficient bytes read when deserializing the clientIp of a node: %d/%d",
+              readClientIpSize, clientIpLength));
+    }
+    node.setClientIp(new String(clientIpBytes));
+  }
+}
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/utils/SerializeUtilTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/utils/SerializeUtilTest.java
index 8fabcb5..0de5cbb 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/utils/SerializeUtilTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/utils/SerializeUtilTest.java
@@ -34,6 +34,7 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.iotdb.tsfile.utils.Binary;
 
+import org.junit.Assert;
 import org.junit.Test;
 
 import java.io.ByteArrayOutputStream;
@@ -178,4 +179,16 @@ public class SerializeUtilTest {
     Log parsed = LogParser.getINSTANCE().parse(serialized);
     assertEquals(log, parsed);
   }
+
+  @Test
+  public void serdesNodeTest() {
+    Node node = new Node("127.0.0.1", 6667, 1, 6535, 4678, "127.0.0.1");
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    DataOutputStream outputStream = new DataOutputStream(baos);
+    NodeSerializeUtils.serialize(node, outputStream);
+    ByteBuffer buffer = ByteBuffer.wrap(baos.toByteArray());
+    Node anotherNode = new Node("127.0.0.1", 6667, 1, 6535, 4678, "127.0.0.1");
+    NodeSerializeUtils.deserialize(anotherNode, buffer);
+    Assert.assertEquals(node, anotherNode);
+  }
 }
diff --git a/grafana/pom.xml b/grafana/pom.xml
index ac5a8e9..a24ba06 100644
--- a/grafana/pom.xml
+++ b/grafana/pom.xml
@@ -59,6 +59,10 @@
     </dependencyManagement>
     <dependencies>
         <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.apache.iotdb</groupId>
             <artifactId>iotdb-jdbc</artifactId>
             <version>${project.version}</version>
diff --git a/jdbc/pom.xml b/jdbc/pom.xml
index 41e1ffd..dd17752 100644
--- a/jdbc/pom.xml
+++ b/jdbc/pom.xml
@@ -38,11 +38,6 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.iotdb</groupId>
-            <artifactId>tsfile</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.iotdb</groupId>
             <artifactId>service-rpc</artifactId>
             <version>${project.version}</version>
         </dependency>
diff --git a/pom.xml b/pom.xml
index e249644..5cf7914 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,6 +82,8 @@
         <module>tsfile</module>
         <module>antlr</module>
         <module>thrift</module>
+        <module>thrift-cluster</module>
+        <module>thrift-sync</module>
         <module>service-rpc</module>
         <module>jdbc</module>
         <module>session</module>
diff --git a/server/pom.xml b/server/pom.xml
index a985d6a..dee952f 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -76,6 +76,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.iotdb</groupId>
+            <artifactId>iotdb-thrift-sync</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-collections4</artifactId>
         </dependency>
diff --git a/server/src/main/java/org/apache/iotdb/db/utils/SerializeUtils.java b/server/src/main/java/org/apache/iotdb/db/utils/SerializeUtils.java
index e4f3bda..cb881e0 100644
--- a/server/src/main/java/org/apache/iotdb/db/utils/SerializeUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/utils/SerializeUtils.java
@@ -19,7 +19,6 @@
 
 package org.apache.iotdb.db.utils;
 
-import org.apache.iotdb.cluster.rpc.thrift.Node;
 import org.apache.iotdb.tsfile.common.conf.TSFileConfig;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.read.TimeValuePair;
@@ -30,7 +29,6 @@ import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 import org.apache.iotdb.tsfile.utils.TsPrimitiveType;
 
 import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.nio.ByteBuffer;
@@ -119,66 +117,6 @@ public class SerializeUtils {
     }
   }
 
-  public static void serialize(Node node, DataOutputStream dataOutputStream) {
-    try {
-      byte[] internalIpBytes = node.internalIp.getBytes();
-      dataOutputStream.writeInt(internalIpBytes.length);
-      dataOutputStream.write(internalIpBytes);
-      dataOutputStream.writeInt(node.metaPort);
-      dataOutputStream.writeInt(node.nodeIdentifier);
-      dataOutputStream.writeInt(node.dataPort);
-      dataOutputStream.writeInt(node.clientPort);
-      byte[] clientIpBytes = node.clientIp.getBytes();
-      dataOutputStream.writeInt(clientIpBytes.length);
-      dataOutputStream.write(clientIpBytes);
-    } catch (IOException e) {
-      // unreachable
-    }
-  }
-
-  public static void deserialize(Node node, ByteBuffer buffer) {
-    int internalIpLength = buffer.getInt();
-    byte[] internalIpBytes = new byte[internalIpLength];
-    buffer.get(internalIpBytes);
-    node.setInternalIp(new String(internalIpBytes));
-    node.setMetaPort(buffer.getInt());
-    node.setNodeIdentifier(buffer.getInt());
-    node.setDataPort(buffer.getInt());
-    node.setClientPort(buffer.getInt());
-    int clientIpLength = buffer.getInt();
-    byte[] clientIpBytes = new byte[clientIpLength];
-    buffer.get(clientIpBytes);
-    node.setClientIp(new String(clientIpBytes));
-  }
-
-  public static void deserialize(Node node, DataInputStream stream) throws IOException {
-    int ipLength = stream.readInt();
-    byte[] ipBytes = new byte[ipLength];
-    int readIpSize = stream.read(ipBytes);
-    if (readIpSize != ipLength) {
-      throw new IOException(
-          String.format(
-              "No sufficient bytes read when deserializing the ip of a node: %d/%d",
-              readIpSize, ipLength));
-    }
-    node.setInternalIp(new String(ipBytes));
-    node.setMetaPort(stream.readInt());
-    node.setNodeIdentifier(stream.readInt());
-    node.setDataPort(stream.readInt());
-    node.setClientPort(stream.readInt());
-
-    int clientIpLength = stream.readInt();
-    byte[] clientIpBytes = new byte[clientIpLength];
-    int readClientIpSize = stream.read(clientIpBytes);
-    if (readClientIpSize != clientIpLength) {
-      throw new IOException(
-          String.format(
-              "No sufficient bytes read when deserializing the clientIp of a node: %d/%d",
-              readClientIpSize, clientIpLength));
-    }
-    node.setClientIp(new String(clientIpBytes));
-  }
-
   public static void serializeBatchData(BatchData batchData, DataOutputStream outputStream) {
     try {
       int length = batchData.length();
diff --git a/server/src/test/java/org/apache/iotdb/db/utils/SerializeUtilsTest.java b/server/src/test/java/org/apache/iotdb/db/utils/SerializeUtilsTest.java
index ba91d9f..5924589 100644
--- a/server/src/test/java/org/apache/iotdb/db/utils/SerializeUtilsTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/utils/SerializeUtilsTest.java
@@ -18,7 +18,6 @@
  */
 package org.apache.iotdb.db.utils;
 
-import org.apache.iotdb.cluster.rpc.thrift.Node;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.read.TimeValuePair;
 import org.apache.iotdb.tsfile.read.common.BatchData;
@@ -85,18 +84,6 @@ public class SerializeUtilsTest {
   }
 
   @Test
-  public void serdesNodeTest() {
-    Node node = new Node("127.0.0.1", 6667, 1, 6535, 4678, "127.0.0.1");
-    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-    DataOutputStream outputStream = new DataOutputStream(baos);
-    SerializeUtils.serialize(node, outputStream);
-    ByteBuffer buffer = ByteBuffer.wrap(baos.toByteArray());
-    Node anotherNode = new Node("127.0.0.1", 6667, 1, 6535, 4678, "127.0.0.1");
-    SerializeUtils.deserialize(anotherNode, buffer);
-    Assert.assertEquals(node, anotherNode);
-  }
-
-  @Test
   public void serdesINT32BatchDataTest() {
     BatchData batchData = new BatchData(TSDataType.INT32);
     int ivalue = 0;
diff --git a/service-rpc/pom.xml b/service-rpc/pom.xml
index 83995c8..8c34872 100644
--- a/service-rpc/pom.xml
+++ b/service-rpc/pom.xml
@@ -40,6 +40,13 @@
             <groupId>org.apache.iotdb</groupId>
             <artifactId>tsfile</artifactId>
             <version>${project.version}</version>
+            <!-- we want to reduce the size of JDBC -->
+            <exclusions>
+                <exclusion>
+                    <groupId>*</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
         <dependency>
             <groupId>org.apache.iotdb</groupId>
diff --git a/session/pom.xml b/session/pom.xml
index 3e3bb71..bd02c26 100644
--- a/session/pom.xml
+++ b/session/pom.xml
@@ -73,11 +73,6 @@
         </dependency>
         <dependency>
             <groupId>org.apache.iotdb</groupId>
-            <artifactId>tsfile</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.iotdb</groupId>
             <artifactId>iotdb-server</artifactId>
             <version>${project.version}</version>
             <type>test-jar</type>
diff --git a/thrift-cluster/README.md b/thrift-cluster/README.md
new file mode 100644
index 0000000..b83e1e1
--- /dev/null
+++ b/thrift-cluster/README.md
@@ -0,0 +1,22 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+
+This modules maintains all RPC interfaces among servers for the cluster module.
\ No newline at end of file
diff --git a/thrift-cluster/pom.xml b/thrift-cluster/pom.xml
new file mode 100644
index 0000000..c1c49a3
--- /dev/null
+++ b/thrift-cluster/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.iotdb</groupId>
+        <artifactId>iotdb-parent</artifactId>
+        <version>0.12.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <artifactId>iotdb-thrift-cluster</artifactId>
+    <name>rpc-thrift-cluster</name>
+    <description>RPC (Thrift) framework among servers.</description>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.thrift</groupId>
+            <artifactId>libthrift</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.iotdb</groupId>
+            <artifactId>iotdb-thrift</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/thrift-cluster/rpc-changelist.md b/thrift-cluster/rpc-changelist.md
new file mode 100644
index 0000000..797c0b6
--- /dev/null
+++ b/thrift-cluster/rpc-changelist.md
@@ -0,0 +1,181 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+        http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+# 0.11.x(version-2) -> 0.12.x(version-1)
+
+Last Updated on 2021.01.19 by Xiangwei Wei.
+
+
+## 1. Delete Old
+
+| Latest Changes                     | Related Committers |
+| ---------------------------------- | ------------------ |
+
+
+## 2. Add New
+
+| Latest Changes                                               | Related Committers     |
+| ------------------------------------------------------------ | ---------------------- |
+| Add timeout in TSFetchResultsReq and TSExecuteStatementReq | Xiangwei Wei | 
+
+
+## 3. Update
+
+| Latest Changes                                               | Related Committers     |
+| ------------------------------------------------------------ | ---------------------- |
+
+
+# 0.10.x (version-2) -> 0.11.x (version-3)
+
+Last Updated on 2020-10-27 by Xiangwei Wei.
+
+
+## 1. Delete Old
+
+| Latest Changes                     | Related Committers |
+| ---------------------------------- | ------------------ |
+| Remove TSBatchExecuteStatementResp            | Tian Jiang         |
+
+
+## 2. Add New
+
+| Latest Changes                                               | Related Committers     |
+| ------------------------------------------------------------ | ---------------------- |
+| set the input/output as TFramedTransport      |  Tian Jiang        |
+| Add timeout(optional) in TSFetchResultsReq and TSExecuteStatementReq | Xiangwei Wei | 
+
+
+## 3. Update
+
+| Latest Changes                                               | Related Committers     |
+| ------------------------------------------------------------ | ---------------------- |
+| Add sub-status in TSStatus  | Tian Jiang  |
+| Change the result of executeBatchStatement  as   TSStatus    | Tian Jiang  |
+| Change TSDeleteDataReq, delete timestamp and add startTime and endTime   | Wei Shao   |
+| Add zoneId in TSOpenSessionReq | Xiangwei Wei |
+
+
+# 0.9.x (version-1) -> 0.10.x (version-2)
+
+Last Updated on 2020-5-25 by Kaifeng Xue.
+
+
+## 1. Delete Old
+
+| Latest Changes                     | Related Committers |
+| ---------------------------------- | ------------------ |
+| Remove TS_SessionHandle,TSHandleIdentifier            | Tian Jiang         |
+| Remove TSStatus,TSExecuteInsertRowInBatchResp            | Jialin Qiao|
+
+
+## 2. Add New
+
+| Latest Changes                                               | Related Committers                 |
+| ------------------------------------------------------------ | ---------------------------------- |
+| Add parameter sessionId in getTimeZone, getProperties, setStorageGroup, createTimeseries... | Tian Jiang|
+| Add struct TSQueryNonAlignDataSet                            | Haonan Hou|
+| Add struct TSInsertTabletsReq                            | Jialin Qiao|
+| Add method insertTablets                            | Jialin Qiao|
+| Add method testInsertTablets                            | Xiangdong Huang |
+| add new field `inferType` in TSInsertRecordReq  | Jialin Qiao      |
+
+## 3. Update
+
+| Latest Changes                                               | Related Committers     |
+| ------------------------------------------------------------ | ---------------------- |
+| Replace TS_SessionHandles with SessionIds, TSOperationHandle with queryIds  | Tian Jiang  |
+| Add optional TSQueryNonAlignDataSet in TSExecuteStatementResp, TSFetchResultsResp and required bool isAlign in TSFetchResultsReq | Haonan Hou |
+| Rename TSStatusType to TSStatus   | Jialin Qiao   |
+| Remove sessionId in TSExecuteBatchStatementResp   | Jialin Qiao   |
+| Rename insertRows to insertReords, insert to insertRecord, insertBatch to insertTablet   | Jialin Qiao   |
+| Use TsDataType and binary rather than string in TSInsertInBatchReq and TSInsertReq  | Kaifeng Xue  |
+
+
+
+# 0.8.x -> 0.9.x (version-1)
+
+Last Updated on 2019-10-27 by Lei Rui.
+
+
+## 1. Delete Old
+
+| Latest Changes                     | Related Committers |
+| ---------------------------------- | ------------------ |
+| Delete struct TSSetStorageGroupReq | Jialin Qiao        |
+| Remove struct TSDataValue          | Lei Rui            |
+| Remove struct TSRowRecord          | Lei Rui            |
+| Remove optional string version in TSFetchMetadataResp | Genius_pig |
+| Remove optional set<string> childPaths, nodesList, storageGroups, devices in TSFetchMetadataResp | Genius_pig |
+| Remove optional map<string, string> nodeTimeseriesNum in TSFetchMetadataResp | Genius_pig |
+| Remove optional list<list<string>> timeseriesList in TSFetchMetadataResp | Genius_pig |
+| Remove optinoal optional i32 timeseriesNum in TSFetchMetadataResp | Genius_pig |
+| Remove optional i32 nodeLevel in TSFetchMetadataReq | Genius_pig |
+
+
+## 2. Add New
+
+| Latest Changes                                               | Related Committers                 |
+| ------------------------------------------------------------ | ---------------------------------- |
+| Add struct TSBatchInsertionReq                               | qiaojialin                         |
+| Add method TSExecuteBatchStatementResp insertBatch(1:TSBatchInsertionReq req) | qiaojialin                         |
+| Add Struct TSStatusType                                      | Zesong Sun                         |
+| Add TSCreateTimeseriesReq                                    | Zesong Sun                         |
+| Add method TSStatus setStorageGroup(1:string storageGroup)   | Zesong Sun, Jialin Qiao            |
+| Add method TSStatus createTimeseries(1:TSCreateTimeseriesReq req) | Zesong Sun                         |
+| Add struct TSInsertReq                                       | qiaojialin                         |
+| Add method TSRPCResp insertRow(1:TSInsertReq req)            | qiaojialin                         |
+| Add struct TSDeleteDataReq                                   | Jack Tsai, qiaojialin              |
+| Add method TSStatus deleteData(1:TSDeleteDataReq req)        | Jack Tsai, Jialin Qiao, qiaojialin |
+| Add method TSStatus deleteTimeseries(1:list\<string> path)   | qiaojialin                         |
+| Add method TSStatus deleteStorageGroups(1:list\<string> storageGroup) | Yi Tao                             |
+| Add Struct TSExecuteInsertRowInBatchResp                     | Kaifeng Xue |
+| Add method insertRowInBatch(1:TSInsertInBatchReq req);       | Kaifeng Xue |
+| Add method testInsertRowInBatch(1:TSInsertInBatchReq req);   | Kaifeng Xue |
+| Add method testInsertRow(1:TSInsertReq req);                 | Kaifeng Xue |
+| Add method testInsertBatch(1:TSBatchInsertionReq req);       | Kaifeng Xue |
+| Add struct TSCreateMultiTimeseriesReq                        | qiaojialin |
+| Add method createMultiTimeseries(1:TSCreateMultiTimeseriesReq req);       | qiaojialin |
+
+
+## 3. Update
+
+| Latest Changes                                               | Related Committers     |
+| ------------------------------------------------------------ | ---------------------- |
+| Add required string timestampPrecision in ServerProperties   | 1160300922             |
+| Add optional list\<string\> dataTypeList in TSExecuteStatementResp | suyue                  |
+| Update TSStatus to use TSStatusType, instead of using ~~TS_StatusCode, errorCode and errorMessage~~ | Zesong Sun             |
+| Rename item in enum TSProtocolVersion from ~~TSFILE_SERVICE_PROTOCOL_V1~~ to IOTDB_SERVICE_PROTOCOL_V1 | qiaojialin             |
+| Rename method name from ~~TSExecuteStatementResp executeInsertion(1:TSInsertionReq req)~~ to TSExecuteStatementResp insert(1:TSInsertionReq req) | qiaojialin             |
+| Add required i32 compressor in TSCreateTimeseriesReq         | Jialin Qiao            |
+| Add optional list\<string> nodesList, optional map\<string, string> nodeTimeseriesNum in TSFetchMetadataResp | jack870131             |
+| Add optional i32 nodeLevel in TSFetchMetadataReq             | jack870131, Zesong Sun |
+| Change the following methods' returned type to be TSStatus: <br />TSStatus closeSession(1:TSCloseSessionReq req), <br />TSStatus cancelOperation(1:TSCancelOperationReq req), <br />TSStatus closeOperation(1:TSCloseOperationReq req), <br />TSStatus setTimeZone(1:TSSetTimeZoneReq req), <br />TSStatus setStorageGroup(1:string storageGroup), <br />TSStatus createTimeseries(1:TSCreateTimeseriesReq req), <br />TSStatus insertRow(1:TSInsertReq req), <br />TSStatus deleteData(1:TSDeleteDataReq  [...]
+| Change from ~~required string path~~ to required list\<string> paths in TSDeleteDataReq | qiaojialin             |
+| Add optional set\<string> devices in TSFetchMetadataResp     | Zesong Sun             |
+| Rename some fields in TSFetchMetadataResp: ~~ColumnsList~~ to columnsList, ~~showTimeseriesList~~ to timeseriesList, ~~showStorageGroups~~ to storageGroups | Zesong Sun             |
+| Change struct TSQueryDataSet to eliminate row-wise rpc writing | Lei Rui                |
+| Add optional i32 timeseriesNum in TSFetchMetadataResp        | Jack Tsai              |
+| Add required i64 queryId in TSHandleIdentifier               | Yuan Tian    |
+| Add optional set\<string> childPaths in TSFetchMetadataResp     | Haonan Hou             |
+| Add optional string version in TSFetchMetadataResp           | Genius_pig             |
+| Add required i64 statementId in TSExecuteStatementReq        | Yuan Tian |
+| Add required binary time, required list<binary> valueList, required list<binary> bitmapList and remove required binary values, required i32 rowCount in TSQueryDataSet| Yuan Tian |
+| Add optional i32 fetchSize in TSExecuteStatementReq,<br />Add optional TSQueryDataSet in TSExecuteStatementResp| liutaohua |
+| Add optional map<string, string> props, optional map<string, string> tags, optional map<string, string> attributes and optional string aliasPath in TSCreateTimeseriesReq | Yuan Tian | 
diff --git a/thrift/src/main/thrift/cluster.thrift b/thrift-cluster/src/main/thrift/cluster.thrift
similarity index 100%
rename from thrift/src/main/thrift/cluster.thrift
rename to thrift-cluster/src/main/thrift/cluster.thrift
diff --git a/thrift-sync/README.md b/thrift-sync/README.md
new file mode 100644
index 0000000..94c1de6
--- /dev/null
+++ b/thrift-sync/README.md
@@ -0,0 +1,22 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+
+This modules maintains all RPC interfaces for data synchronization among servers.
\ No newline at end of file
diff --git a/thrift-sync/pom.xml b/thrift-sync/pom.xml
new file mode 100644
index 0000000..2108734
--- /dev/null
+++ b/thrift-sync/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.iotdb</groupId>
+        <artifactId>iotdb-parent</artifactId>
+        <version>0.12.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <artifactId>iotdb-thrift-sync</artifactId>
+    <name>rpc-thrift-sync</name>
+    <description>RPC (Thrift) framework among servers for data synchronization.</description>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.thrift</groupId>
+            <artifactId>libthrift</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.iotdb</groupId>
+            <artifactId>iotdb-thrift</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/thrift-sync/rpc-changelist.md b/thrift-sync/rpc-changelist.md
new file mode 100644
index 0000000..797c0b6
--- /dev/null
+++ b/thrift-sync/rpc-changelist.md
@@ -0,0 +1,181 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+        http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+# 0.11.x(version-2) -> 0.12.x(version-1)
+
+Last Updated on 2021.01.19 by Xiangwei Wei.
+
+
+## 1. Delete Old
+
+| Latest Changes                     | Related Committers |
+| ---------------------------------- | ------------------ |
+
+
+## 2. Add New
+
+| Latest Changes                                               | Related Committers     |
+| ------------------------------------------------------------ | ---------------------- |
+| Add timeout in TSFetchResultsReq and TSExecuteStatementReq | Xiangwei Wei | 
+
+
+## 3. Update
+
+| Latest Changes                                               | Related Committers     |
+| ------------------------------------------------------------ | ---------------------- |
+
+
+# 0.10.x (version-2) -> 0.11.x (version-3)
+
+Last Updated on 2020-10-27 by Xiangwei Wei.
+
+
+## 1. Delete Old
+
+| Latest Changes                     | Related Committers |
+| ---------------------------------- | ------------------ |
+| Remove TSBatchExecuteStatementResp            | Tian Jiang         |
+
+
+## 2. Add New
+
+| Latest Changes                                               | Related Committers     |
+| ------------------------------------------------------------ | ---------------------- |
+| set the input/output as TFramedTransport      |  Tian Jiang        |
+| Add timeout(optional) in TSFetchResultsReq and TSExecuteStatementReq | Xiangwei Wei | 
+
+
+## 3. Update
+
+| Latest Changes                                               | Related Committers     |
+| ------------------------------------------------------------ | ---------------------- |
+| Add sub-status in TSStatus  | Tian Jiang  |
+| Change the result of executeBatchStatement  as   TSStatus    | Tian Jiang  |
+| Change TSDeleteDataReq, delete timestamp and add startTime and endTime   | Wei Shao   |
+| Add zoneId in TSOpenSessionReq | Xiangwei Wei |
+
+
+# 0.9.x (version-1) -> 0.10.x (version-2)
+
+Last Updated on 2020-5-25 by Kaifeng Xue.
+
+
+## 1. Delete Old
+
+| Latest Changes                     | Related Committers |
+| ---------------------------------- | ------------------ |
+| Remove TS_SessionHandle,TSHandleIdentifier            | Tian Jiang         |
+| Remove TSStatus,TSExecuteInsertRowInBatchResp            | Jialin Qiao|
+
+
+## 2. Add New
+
+| Latest Changes                                               | Related Committers                 |
+| ------------------------------------------------------------ | ---------------------------------- |
+| Add parameter sessionId in getTimeZone, getProperties, setStorageGroup, createTimeseries... | Tian Jiang|
+| Add struct TSQueryNonAlignDataSet                            | Haonan Hou|
+| Add struct TSInsertTabletsReq                            | Jialin Qiao|
+| Add method insertTablets                            | Jialin Qiao|
+| Add method testInsertTablets                            | Xiangdong Huang |
+| add new field `inferType` in TSInsertRecordReq  | Jialin Qiao      |
+
+## 3. Update
+
+| Latest Changes                                               | Related Committers     |
+| ------------------------------------------------------------ | ---------------------- |
+| Replace TS_SessionHandles with SessionIds, TSOperationHandle with queryIds  | Tian Jiang  |
+| Add optional TSQueryNonAlignDataSet in TSExecuteStatementResp, TSFetchResultsResp and required bool isAlign in TSFetchResultsReq | Haonan Hou |
+| Rename TSStatusType to TSStatus   | Jialin Qiao   |
+| Remove sessionId in TSExecuteBatchStatementResp   | Jialin Qiao   |
+| Rename insertRows to insertReords, insert to insertRecord, insertBatch to insertTablet   | Jialin Qiao   |
+| Use TsDataType and binary rather than string in TSInsertInBatchReq and TSInsertReq  | Kaifeng Xue  |
+
+
+
+# 0.8.x -> 0.9.x (version-1)
+
+Last Updated on 2019-10-27 by Lei Rui.
+
+
+## 1. Delete Old
+
+| Latest Changes                     | Related Committers |
+| ---------------------------------- | ------------------ |
+| Delete struct TSSetStorageGroupReq | Jialin Qiao        |
+| Remove struct TSDataValue          | Lei Rui            |
+| Remove struct TSRowRecord          | Lei Rui            |
+| Remove optional string version in TSFetchMetadataResp | Genius_pig |
+| Remove optional set<string> childPaths, nodesList, storageGroups, devices in TSFetchMetadataResp | Genius_pig |
+| Remove optional map<string, string> nodeTimeseriesNum in TSFetchMetadataResp | Genius_pig |
+| Remove optional list<list<string>> timeseriesList in TSFetchMetadataResp | Genius_pig |
+| Remove optinoal optional i32 timeseriesNum in TSFetchMetadataResp | Genius_pig |
+| Remove optional i32 nodeLevel in TSFetchMetadataReq | Genius_pig |
+
+
+## 2. Add New
+
+| Latest Changes                                               | Related Committers                 |
+| ------------------------------------------------------------ | ---------------------------------- |
+| Add struct TSBatchInsertionReq                               | qiaojialin                         |
+| Add method TSExecuteBatchStatementResp insertBatch(1:TSBatchInsertionReq req) | qiaojialin                         |
+| Add Struct TSStatusType                                      | Zesong Sun                         |
+| Add TSCreateTimeseriesReq                                    | Zesong Sun                         |
+| Add method TSStatus setStorageGroup(1:string storageGroup)   | Zesong Sun, Jialin Qiao            |
+| Add method TSStatus createTimeseries(1:TSCreateTimeseriesReq req) | Zesong Sun                         |
+| Add struct TSInsertReq                                       | qiaojialin                         |
+| Add method TSRPCResp insertRow(1:TSInsertReq req)            | qiaojialin                         |
+| Add struct TSDeleteDataReq                                   | Jack Tsai, qiaojialin              |
+| Add method TSStatus deleteData(1:TSDeleteDataReq req)        | Jack Tsai, Jialin Qiao, qiaojialin |
+| Add method TSStatus deleteTimeseries(1:list\<string> path)   | qiaojialin                         |
+| Add method TSStatus deleteStorageGroups(1:list\<string> storageGroup) | Yi Tao                             |
+| Add Struct TSExecuteInsertRowInBatchResp                     | Kaifeng Xue |
+| Add method insertRowInBatch(1:TSInsertInBatchReq req);       | Kaifeng Xue |
+| Add method testInsertRowInBatch(1:TSInsertInBatchReq req);   | Kaifeng Xue |
+| Add method testInsertRow(1:TSInsertReq req);                 | Kaifeng Xue |
+| Add method testInsertBatch(1:TSBatchInsertionReq req);       | Kaifeng Xue |
+| Add struct TSCreateMultiTimeseriesReq                        | qiaojialin |
+| Add method createMultiTimeseries(1:TSCreateMultiTimeseriesReq req);       | qiaojialin |
+
+
+## 3. Update
+
+| Latest Changes                                               | Related Committers     |
+| ------------------------------------------------------------ | ---------------------- |
+| Add required string timestampPrecision in ServerProperties   | 1160300922             |
+| Add optional list\<string\> dataTypeList in TSExecuteStatementResp | suyue                  |
+| Update TSStatus to use TSStatusType, instead of using ~~TS_StatusCode, errorCode and errorMessage~~ | Zesong Sun             |
+| Rename item in enum TSProtocolVersion from ~~TSFILE_SERVICE_PROTOCOL_V1~~ to IOTDB_SERVICE_PROTOCOL_V1 | qiaojialin             |
+| Rename method name from ~~TSExecuteStatementResp executeInsertion(1:TSInsertionReq req)~~ to TSExecuteStatementResp insert(1:TSInsertionReq req) | qiaojialin             |
+| Add required i32 compressor in TSCreateTimeseriesReq         | Jialin Qiao            |
+| Add optional list\<string> nodesList, optional map\<string, string> nodeTimeseriesNum in TSFetchMetadataResp | jack870131             |
+| Add optional i32 nodeLevel in TSFetchMetadataReq             | jack870131, Zesong Sun |
+| Change the following methods' returned type to be TSStatus: <br />TSStatus closeSession(1:TSCloseSessionReq req), <br />TSStatus cancelOperation(1:TSCancelOperationReq req), <br />TSStatus closeOperation(1:TSCloseOperationReq req), <br />TSStatus setTimeZone(1:TSSetTimeZoneReq req), <br />TSStatus setStorageGroup(1:string storageGroup), <br />TSStatus createTimeseries(1:TSCreateTimeseriesReq req), <br />TSStatus insertRow(1:TSInsertReq req), <br />TSStatus deleteData(1:TSDeleteDataReq  [...]
+| Change from ~~required string path~~ to required list\<string> paths in TSDeleteDataReq | qiaojialin             |
+| Add optional set\<string> devices in TSFetchMetadataResp     | Zesong Sun             |
+| Rename some fields in TSFetchMetadataResp: ~~ColumnsList~~ to columnsList, ~~showTimeseriesList~~ to timeseriesList, ~~showStorageGroups~~ to storageGroups | Zesong Sun             |
+| Change struct TSQueryDataSet to eliminate row-wise rpc writing | Lei Rui                |
+| Add optional i32 timeseriesNum in TSFetchMetadataResp        | Jack Tsai              |
+| Add required i64 queryId in TSHandleIdentifier               | Yuan Tian    |
+| Add optional set\<string> childPaths in TSFetchMetadataResp     | Haonan Hou             |
+| Add optional string version in TSFetchMetadataResp           | Genius_pig             |
+| Add required i64 statementId in TSExecuteStatementReq        | Yuan Tian |
+| Add required binary time, required list<binary> valueList, required list<binary> bitmapList and remove required binary values, required i32 rowCount in TSQueryDataSet| Yuan Tian |
+| Add optional i32 fetchSize in TSExecuteStatementReq,<br />Add optional TSQueryDataSet in TSExecuteStatementResp| liutaohua |
+| Add optional map<string, string> props, optional map<string, string> tags, optional map<string, string> attributes and optional string aliasPath in TSCreateTimeseriesReq | Yuan Tian | 
diff --git a/thrift/src/main/thrift/sync.thrift b/thrift-sync/src/main/thrift/sync.thrift
similarity index 100%
rename from thrift/src/main/thrift/sync.thrift
rename to thrift-sync/src/main/thrift/sync.thrift
diff --git a/thrift/README.md b/thrift/README.md
new file mode 100644
index 0000000..1d105e8
--- /dev/null
+++ b/thrift/README.md
@@ -0,0 +1,22 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+
+This modules maintains all RPC interfaces between clients and the server.
\ No newline at end of file