This is an automated email from the ASF dual-hosted git repository.
qiaojialin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iotdb-docs.git
The following commit(s) were added to refs/heads/main by this push:
new 65bb127 Update the partitioning & load balance doc (#375)
65bb127 is described below
commit 65bb127b2002660b46b0cef399e8e3de07dcf876
Author: Yongzao <[email protected]>
AuthorDate: Fri Oct 4 08:18:32 2024 +0800
Update the partitioning & load balance doc (#375)
---
.../Basic-Concept/Cluster-data-partitioning.md | 90 +++++++++++++++++-----
.../Basic-Concept/Cluster-data-partitioning.md | 90 +++++++++++++++++-----
.../Basic-Concept/Cluster-data-partitioning.md | 90 +++++++++++++++++-----
.../Basic-Concept/Cluster-data-partitioning.md | 90 +++++++++++++++++-----
4 files changed, 280 insertions(+), 80 deletions(-)
diff --git a/src/UserGuide/Master/Basic-Concept/Cluster-data-partitioning.md
b/src/UserGuide/Master/Basic-Concept/Cluster-data-partitioning.md
index 030f86e..a9c6e9b 100644
--- a/src/UserGuide/Master/Basic-Concept/Cluster-data-partitioning.md
+++ b/src/UserGuide/Master/Basic-Concept/Cluster-data-partitioning.md
@@ -19,42 +19,92 @@
-->
-# Data Partitioning & Load Balancing
+# Load Balance
+This document introduces the partitioning strategies and load balance
strategies in IoTDB. According to the characteristics of time series data,
IoTDB partitions them by series and time dimensions. Combining a series
partition with a time partition creates a partition, the unit of division. To
enhance throughput and reduce management costs, these partitions are evenly
allocated to RegionGroups, which serve as the unit of replication. The
RegionGroup's Regions then determine the storage l [...]
-IoTDB manages metadata and data based on data partitions (DataRegion),
dividing the data from both the sequence and time dimensions.
+## Partitioning Strategy & Partition Allocation
+IoTDB implements tailored partitioning algorithms for time series data.
Building on this foundation, the partition information cached on both
ConfigNodes and DataNodes is not only manageable in size but also clearly
differentiated between hot and cold. Subsequently, balanced partitions are
evenly allocated across the cluster's RegionGroups to achieve storage balance.
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/upload/data-region.jpg">
+### Partitioning Strategy
+IoTDB maps each sensor in the production environment to a time series. The
time series are then partitioned using the series partitioning algorithm to
manage their schema, and combined with the time partitioning algorithm to
manage their data. The following figure illustrates how IoTDB partitions time
series data.
-## Partition Slots
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/partition_table_en.png?raw=true">
-A sequence partition slot combined with a time partition slot can generate a
data partition (when the sequence slot has corresponding data under that time
slot).
+#### Partitioning Algorithm
+Because numerous devices and sensors are commonly deployed in production
environments, IoTDB employs a series partitioning algorithm to ensure the size
of partition information is manageable. Since the generated time series
associated with timestamps, IoTDB uses a time partioning algorithm to clearly
distinguish between hot and cold partitions.
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/SeriesPartitionSlot.png?raw=true">
+##### Series Partitioning Algorithm
+By default, IoTDB limits the number of series partitions to 1000 and
configures the series partitioning algorithm to use a hash partitioning
algorithm. This leads to the following outcomes:
++ Since the number of series partitions is a fixed constant, the mapping
between series and series partitions remains stable. As a result, IoTDB does
not require frequent data migrations.
++ The load across series partitions is relatively balanced because the number
of series partitions is much smaller than the number of sensors deployed in the
production environment.
-### Sequence Partition Slots
+Furthermore, if a more accurate estimate of the actual load in the production
environment is available, the series partitioning algorithm can be configured
to use a customized hash partitioning or a list partitioning to achieve a more
uniform load distribution across all series partitions.
-Each database holds a fixed number of sequence partition slots, with the
default set to 1000. Every time series managed by the database is allocated to
a unique sequence partition slot using a partitioning algorithm (usually some
hash method).
+##### Time Partitioning Algorithm
+The time partitioning algorithm converts a given timestamp to the
corresponding time partition by
-### Time Partition Slots
+$$\left\lfloor\frac{\text{Timestamp}-\text{StartTimestamp}}{\text{TimePartitionInterval}}\right\rfloor.$$
-Every time series will continuously produce data. If all the data from a time
series is stored on one node continuously, the newly added DataNode in the
cluster might not be effectively utilized.
+In this equation, both $\text{StartTimestamp}$ and
$\text{TimePartitionInterval}$ are configurable parameters to accommodate
various production environments. The $\text{StartTimestamp}$ represents the
starting time of the first time partition, while the
$\text{TimePartitionInterval}$ defines the duration of each time partition. By
default, the $\text{TimePartitionInterval}$ is set to one day.
-Time partition slots slice the time-series data from the time dimension
(typically, one time partition per day), making the time-series data storage in
the cluster easy to manage.
+#### Schema Partitioning
+Since the series partitioning algorithm evenly partitions the time series,
each series partition corresponds to a schema partition. These schema
partitions are then evenly allocated across the SchemaRegionGroups to achieve a
balanced schema distribution.
-## Metadata Partitioning
+#### Data Partitioning
+Combining a series partition with a time partition creates a data partition.
Since the series partitioning algorithm evenly partitions the time series, the
load of data partitions within a specified time partition remains balanced.
These data partitions are then evenly allocated across the DataRegionGroups to
achieve balanced data distribution.
-The metadata partition management of a single database, following a specific
load balancing strategy, assigns all sequence slots to the corresponding
SchemaRegionGroup, further horizontally scaling within the cluster.
+### Partition Allocation
+IoTDB uses RegionGroups to enable elastic storage of time series, with the
number of RegionGroups in the cluster determined by the total resources
available across all DataNodes. Since the number of RegionGroups is dynamic,
IoTDB can easily scale out. Both the SchemaRegionGroup and DataRegionGroup
follow the same partition allocation algorithm, which evenly splits all series
partitions. The following figure demonstrates the partition allocation process,
where the dynamic RegionGroups mat [...]
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/SchemaRegion.png?raw=true">
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/partition_allocation_en.png?raw=true">
-## Data Partitioning
+#### RegionGroup Expansion
+The number of RegionGroups is given by
-It follows a certain load balancing strategy, dividing time and sequence
partition slots, and allocating them to the relevant DataRegionGroup, further
allowing horizontal scaling in the cluster.
+$$\text{RegionGroupNumber}=\left\lfloor\frac{\sum_{i=1}^{DataNodeNumber}\text{RegionNumber}_i}{\text{ReplicationFactor}}\right\rfloor.$$
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/DataRegion.png?raw=true">
+In this equation, $\text{RegionNumber}_i$ represents the number of Regions
expected to be hosted on the $i$-th DataNode, while $\text{ReplicationFactor}$
denotes the number of Regions within each RegionGroup. Both
$\text{RegionNumber}_i$ and $\text{ReplicationFactor}$ are configurable
parameters. The $\text{RegionNumber}_i$ can be determined by the available
hardware resources---such as CPU cores, memory sizes, etc.---on the $i$-th
DataNode to accommodate different physical servers. The [...]
-## Load Balancing
+#### Allocation Algorithm
+Both the SchemaRegionGroup and the DataRegionGroup follow the same allocation
algorithm--splitting all series partitions evenly. As a result, each
SchemaRegionGroup holds the same number of schema partitions, ensuring balanced
schema storage. Similarly, for each time partition, each DataRegionGroup
acquires the data partitions corresponding to the series partitions it holds.
Consequently, the data partitions within a time partition are evenly
distributed across all DataRegionGroups, ensu [...]
-When the cluster's capacity remains unchanged, data will be evenly distributed
across all nodes to utilize storage and computational resources effectively.
+Notably, IoTDB effectively leverages the characteristics of time series data.
When the TTL (Time to Live) is configured, IoTDB enables migration-free elastic
storage for time series data. This feature facilitates cluster expansion while
minimizing the impact on online operations. The figures above illustrate an
instance of this feature: newborn data partitions are evenly allocated to each
DataRegion, and expired data are automatically archived. As a result, the
cluster's storage will eve [...]
-Also, during cluster expansion, the system automatically increases the number
of regions to fully exploit the computational resources of all nodes without
manual intervention. Such dynamic expansion enhances the cluster's performance
and scalability, making the system more flexible and efficient.
\ No newline at end of file
+## Balance Strategy
+To enhance the cluster's availability and performance, IoTDB employs
sophisticated storage load and computing load balance algorithms.
+
+### Storage Load Balance
+The number of Regions held by a DataNode reflects its storage load. If the
difference in the number of Regions across DataNodes is relatively large, the
DataNode with more Regions is likely to become a storage bottleneck. Although a
straightforward Round Robin placement algorithm can achieve storage balance by
ensuring that each DataNode hosts an equal number of Regions, it compromises
the cluster's fault tolerance, as illustrated below:
+
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/placement_en.png?raw=true">
+
++ Assume the cluster has 4 DataNodes, 4 RegionGroups and a replication factor
of 2.
++ Place RegionGroup $r_1$'s 2 Regions on DataNodes $n_1$ and $n_2$.
++ Place RegionGroup $r_2$'s 2 Regions on DataNodes $n_3$ and $n_4$.
++ Place RegionGroup $r_3$'s 2 Regions on DataNodes $n_1$ and $n_3$.
++ Place RegionGroup $r_4$'s 2 Regions on DataNodes $n_2$ and $n_4$.
+
+In this scenario, if DataNode $n_2$ fails, the load previously handled by
DataNode $n_2$ would be transferred solely to DataNode $n_1$, potentially
overloading it.
+
+To address this issue, IoTDB employs a Region placement algorithm that not
only evenly distributes Regions across all DataNodes but also ensures that each
DataNode can offload its storage to sufficient other DataNodes in the event of
a failure. As a result, the cluster achieves balanced storage distribution and
a high level of fault tolerance, ensuring its availability.
+
+### Computing Load Balance
+The number of leader Regions held by a DataNode reflects its Computing load.
If the difference in the number of leaders across DataNodes is relatively
large, the DataNode with more leaders is likely to become a Computing
bottleneck. If the leader selection process is conducted using a transparent
Greedy algorithm, the result may be an unbalanced leader distribution when the
Regions are fault-tolerantly placed, as demonstrated below:
+
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/selection_en.png?raw=true">
+
++ Assume the cluster has 4 DataNodes, 4 RegionGroups and a replication factor
of 2.
++ Select RegionGroup $r_5$'s Region on DataNode $n_5$ as the leader.
++ Select RegionGroup $r_6$'s Region on DataNode $n_7$ as the leader.
++ Select RegionGroup $r_7$'s Region on DataNode $n_7$ as the leader.
++ Select RegionGroup $r_8$'s Region on DataNode $n_8$ as the leader.
+
+Please note that all the above steps strictly follow the Greedy algorithm.
However, by Step 3, selecting the leader of RegionGroup $r_7$ on either
DataNode $n_5$ or $n_7$ results in an unbalanced leader distribution. The
rationale is that each greedy step lacks a global perspective, leading to a
locally optimal solution.
+
+To address this issue, IoTDB employs a leader selection algorithm that can
consistently balance the cluster's leader distribution. Consequently, the
cluster achieves balanced Computing load distribution, ensuring its performance.
+
+## Source Code
++ [Data
Partitioning](https://github.com/apache/iotdb/tree/master/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition)
++ [Partition
Allocation](https://github.com/apache/iotdb/tree/master/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/balancer/partition)
++ [Region
Placement](https://github.com/apache/iotdb/tree/master/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/balancer/region)
++ [Leader
Selection](https://github.com/apache/iotdb/tree/master/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/balancer/router/leader)
\ No newline at end of file
diff --git a/src/UserGuide/latest/Basic-Concept/Cluster-data-partitioning.md
b/src/UserGuide/latest/Basic-Concept/Cluster-data-partitioning.md
index 030f86e..a9c6e9b 100644
--- a/src/UserGuide/latest/Basic-Concept/Cluster-data-partitioning.md
+++ b/src/UserGuide/latest/Basic-Concept/Cluster-data-partitioning.md
@@ -19,42 +19,92 @@
-->
-# Data Partitioning & Load Balancing
+# Load Balance
+This document introduces the partitioning strategies and load balance
strategies in IoTDB. According to the characteristics of time series data,
IoTDB partitions them by series and time dimensions. Combining a series
partition with a time partition creates a partition, the unit of division. To
enhance throughput and reduce management costs, these partitions are evenly
allocated to RegionGroups, which serve as the unit of replication. The
RegionGroup's Regions then determine the storage l [...]
-IoTDB manages metadata and data based on data partitions (DataRegion),
dividing the data from both the sequence and time dimensions.
+## Partitioning Strategy & Partition Allocation
+IoTDB implements tailored partitioning algorithms for time series data.
Building on this foundation, the partition information cached on both
ConfigNodes and DataNodes is not only manageable in size but also clearly
differentiated between hot and cold. Subsequently, balanced partitions are
evenly allocated across the cluster's RegionGroups to achieve storage balance.
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/upload/data-region.jpg">
+### Partitioning Strategy
+IoTDB maps each sensor in the production environment to a time series. The
time series are then partitioned using the series partitioning algorithm to
manage their schema, and combined with the time partitioning algorithm to
manage their data. The following figure illustrates how IoTDB partitions time
series data.
-## Partition Slots
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/partition_table_en.png?raw=true">
-A sequence partition slot combined with a time partition slot can generate a
data partition (when the sequence slot has corresponding data under that time
slot).
+#### Partitioning Algorithm
+Because numerous devices and sensors are commonly deployed in production
environments, IoTDB employs a series partitioning algorithm to ensure the size
of partition information is manageable. Since the generated time series
associated with timestamps, IoTDB uses a time partioning algorithm to clearly
distinguish between hot and cold partitions.
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/SeriesPartitionSlot.png?raw=true">
+##### Series Partitioning Algorithm
+By default, IoTDB limits the number of series partitions to 1000 and
configures the series partitioning algorithm to use a hash partitioning
algorithm. This leads to the following outcomes:
++ Since the number of series partitions is a fixed constant, the mapping
between series and series partitions remains stable. As a result, IoTDB does
not require frequent data migrations.
++ The load across series partitions is relatively balanced because the number
of series partitions is much smaller than the number of sensors deployed in the
production environment.
-### Sequence Partition Slots
+Furthermore, if a more accurate estimate of the actual load in the production
environment is available, the series partitioning algorithm can be configured
to use a customized hash partitioning or a list partitioning to achieve a more
uniform load distribution across all series partitions.
-Each database holds a fixed number of sequence partition slots, with the
default set to 1000. Every time series managed by the database is allocated to
a unique sequence partition slot using a partitioning algorithm (usually some
hash method).
+##### Time Partitioning Algorithm
+The time partitioning algorithm converts a given timestamp to the
corresponding time partition by
-### Time Partition Slots
+$$\left\lfloor\frac{\text{Timestamp}-\text{StartTimestamp}}{\text{TimePartitionInterval}}\right\rfloor.$$
-Every time series will continuously produce data. If all the data from a time
series is stored on one node continuously, the newly added DataNode in the
cluster might not be effectively utilized.
+In this equation, both $\text{StartTimestamp}$ and
$\text{TimePartitionInterval}$ are configurable parameters to accommodate
various production environments. The $\text{StartTimestamp}$ represents the
starting time of the first time partition, while the
$\text{TimePartitionInterval}$ defines the duration of each time partition. By
default, the $\text{TimePartitionInterval}$ is set to one day.
-Time partition slots slice the time-series data from the time dimension
(typically, one time partition per day), making the time-series data storage in
the cluster easy to manage.
+#### Schema Partitioning
+Since the series partitioning algorithm evenly partitions the time series,
each series partition corresponds to a schema partition. These schema
partitions are then evenly allocated across the SchemaRegionGroups to achieve a
balanced schema distribution.
-## Metadata Partitioning
+#### Data Partitioning
+Combining a series partition with a time partition creates a data partition.
Since the series partitioning algorithm evenly partitions the time series, the
load of data partitions within a specified time partition remains balanced.
These data partitions are then evenly allocated across the DataRegionGroups to
achieve balanced data distribution.
-The metadata partition management of a single database, following a specific
load balancing strategy, assigns all sequence slots to the corresponding
SchemaRegionGroup, further horizontally scaling within the cluster.
+### Partition Allocation
+IoTDB uses RegionGroups to enable elastic storage of time series, with the
number of RegionGroups in the cluster determined by the total resources
available across all DataNodes. Since the number of RegionGroups is dynamic,
IoTDB can easily scale out. Both the SchemaRegionGroup and DataRegionGroup
follow the same partition allocation algorithm, which evenly splits all series
partitions. The following figure demonstrates the partition allocation process,
where the dynamic RegionGroups mat [...]
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/SchemaRegion.png?raw=true">
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/partition_allocation_en.png?raw=true">
-## Data Partitioning
+#### RegionGroup Expansion
+The number of RegionGroups is given by
-It follows a certain load balancing strategy, dividing time and sequence
partition slots, and allocating them to the relevant DataRegionGroup, further
allowing horizontal scaling in the cluster.
+$$\text{RegionGroupNumber}=\left\lfloor\frac{\sum_{i=1}^{DataNodeNumber}\text{RegionNumber}_i}{\text{ReplicationFactor}}\right\rfloor.$$
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/DataRegion.png?raw=true">
+In this equation, $\text{RegionNumber}_i$ represents the number of Regions
expected to be hosted on the $i$-th DataNode, while $\text{ReplicationFactor}$
denotes the number of Regions within each RegionGroup. Both
$\text{RegionNumber}_i$ and $\text{ReplicationFactor}$ are configurable
parameters. The $\text{RegionNumber}_i$ can be determined by the available
hardware resources---such as CPU cores, memory sizes, etc.---on the $i$-th
DataNode to accommodate different physical servers. The [...]
-## Load Balancing
+#### Allocation Algorithm
+Both the SchemaRegionGroup and the DataRegionGroup follow the same allocation
algorithm--splitting all series partitions evenly. As a result, each
SchemaRegionGroup holds the same number of schema partitions, ensuring balanced
schema storage. Similarly, for each time partition, each DataRegionGroup
acquires the data partitions corresponding to the series partitions it holds.
Consequently, the data partitions within a time partition are evenly
distributed across all DataRegionGroups, ensu [...]
-When the cluster's capacity remains unchanged, data will be evenly distributed
across all nodes to utilize storage and computational resources effectively.
+Notably, IoTDB effectively leverages the characteristics of time series data.
When the TTL (Time to Live) is configured, IoTDB enables migration-free elastic
storage for time series data. This feature facilitates cluster expansion while
minimizing the impact on online operations. The figures above illustrate an
instance of this feature: newborn data partitions are evenly allocated to each
DataRegion, and expired data are automatically archived. As a result, the
cluster's storage will eve [...]
-Also, during cluster expansion, the system automatically increases the number
of regions to fully exploit the computational resources of all nodes without
manual intervention. Such dynamic expansion enhances the cluster's performance
and scalability, making the system more flexible and efficient.
\ No newline at end of file
+## Balance Strategy
+To enhance the cluster's availability and performance, IoTDB employs
sophisticated storage load and computing load balance algorithms.
+
+### Storage Load Balance
+The number of Regions held by a DataNode reflects its storage load. If the
difference in the number of Regions across DataNodes is relatively large, the
DataNode with more Regions is likely to become a storage bottleneck. Although a
straightforward Round Robin placement algorithm can achieve storage balance by
ensuring that each DataNode hosts an equal number of Regions, it compromises
the cluster's fault tolerance, as illustrated below:
+
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/placement_en.png?raw=true">
+
++ Assume the cluster has 4 DataNodes, 4 RegionGroups and a replication factor
of 2.
++ Place RegionGroup $r_1$'s 2 Regions on DataNodes $n_1$ and $n_2$.
++ Place RegionGroup $r_2$'s 2 Regions on DataNodes $n_3$ and $n_4$.
++ Place RegionGroup $r_3$'s 2 Regions on DataNodes $n_1$ and $n_3$.
++ Place RegionGroup $r_4$'s 2 Regions on DataNodes $n_2$ and $n_4$.
+
+In this scenario, if DataNode $n_2$ fails, the load previously handled by
DataNode $n_2$ would be transferred solely to DataNode $n_1$, potentially
overloading it.
+
+To address this issue, IoTDB employs a Region placement algorithm that not
only evenly distributes Regions across all DataNodes but also ensures that each
DataNode can offload its storage to sufficient other DataNodes in the event of
a failure. As a result, the cluster achieves balanced storage distribution and
a high level of fault tolerance, ensuring its availability.
+
+### Computing Load Balance
+The number of leader Regions held by a DataNode reflects its Computing load.
If the difference in the number of leaders across DataNodes is relatively
large, the DataNode with more leaders is likely to become a Computing
bottleneck. If the leader selection process is conducted using a transparent
Greedy algorithm, the result may be an unbalanced leader distribution when the
Regions are fault-tolerantly placed, as demonstrated below:
+
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/selection_en.png?raw=true">
+
++ Assume the cluster has 4 DataNodes, 4 RegionGroups and a replication factor
of 2.
++ Select RegionGroup $r_5$'s Region on DataNode $n_5$ as the leader.
++ Select RegionGroup $r_6$'s Region on DataNode $n_7$ as the leader.
++ Select RegionGroup $r_7$'s Region on DataNode $n_7$ as the leader.
++ Select RegionGroup $r_8$'s Region on DataNode $n_8$ as the leader.
+
+Please note that all the above steps strictly follow the Greedy algorithm.
However, by Step 3, selecting the leader of RegionGroup $r_7$ on either
DataNode $n_5$ or $n_7$ results in an unbalanced leader distribution. The
rationale is that each greedy step lacks a global perspective, leading to a
locally optimal solution.
+
+To address this issue, IoTDB employs a leader selection algorithm that can
consistently balance the cluster's leader distribution. Consequently, the
cluster achieves balanced Computing load distribution, ensuring its performance.
+
+## Source Code
++ [Data
Partitioning](https://github.com/apache/iotdb/tree/master/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition)
++ [Partition
Allocation](https://github.com/apache/iotdb/tree/master/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/balancer/partition)
++ [Region
Placement](https://github.com/apache/iotdb/tree/master/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/balancer/region)
++ [Leader
Selection](https://github.com/apache/iotdb/tree/master/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/balancer/router/leader)
\ No newline at end of file
diff --git a/src/zh/UserGuide/Master/Basic-Concept/Cluster-data-partitioning.md
b/src/zh/UserGuide/Master/Basic-Concept/Cluster-data-partitioning.md
index 943659c..a221fe4 100644
--- a/src/zh/UserGuide/Master/Basic-Concept/Cluster-data-partitioning.md
+++ b/src/zh/UserGuide/Master/Basic-Concept/Cluster-data-partitioning.md
@@ -19,42 +19,92 @@
-->
-# 数据分区与负载均衡
+# 分区与负载均衡
+本文档介绍 IoTDB 中的分区策略和负载均衡策略。根据时序数据的特性,IoTDB
按序列和时间维度对其进行分区。结合序列分区与时间分区创建一个分区,作为划分的基本单元。为了提高吞吐量并降低管理成本,这些分区被均匀分配到分片(Region)中,分片是复制的基本单元。分片的副本决定了数据的存储位置,主副本负责主要负载的管理。在此过程中,副本放置算法决定哪些节点将持有分片副本,而主副本选择算法则指定哪个副本将成为主副本。
-IoTDB 以数据分区(DataRegion)为单位对元数据和数据进行管理,从序列和时间两个维度进行数据划分。
+## 分区策略和分区分配
+IoTDB
为时间序列数据实现了量身定制的分区算法。在此基础上,缓存于配置节点和数据节点上的分区信息不仅易于管理,而且能够清晰区分冷热数据。随后,平衡的分区被均匀分配到集群的分片中,以实现存储均衡。
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/%E5%88%86%E5%8C%BA%E6%A7%BD%E4%B8%8E%E6%95%B0%E6%8D%AE%E5%88%86%E5%8C%BA.png?raw=true">
+### 分区策略
+IoTDB 将生产环境中的每个传感器映射为一个时间序列。然后,使用序列分区算法对时间序列进行分区以管理其元数据,再结合时间分区算法来管理其数据。下图展示了
IoTDB 如何对时序数据进行分区。
-## 分区槽
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/partition_table_cn.png?raw=true">
-一个序列分区槽和一个时间分区槽可以组合产生一个数据分区(当该序列分区槽在该时间分区槽下有对应数据时)。
+#### 分区策略
+由于生产环境中通常部署大量设备和传感器,IoTDB 使用序列分区算法以确保分区信息的大小可控。由于生成的时间序列与时间戳相关联,IoTDB
使用时间分区算法来清晰区分冷热分区。
-### 序列分区槽
+##### 序列分区算法
+默认情况下,IoTDB 将序列分区的数量限制为 1000,并将序列分区算法配置为哈希分区算法。这带来以下收益:
++ 由于序列分区的数量是固定常量,序列与序列分区之间的映射保持稳定。因此,IoTDB 不需要频繁进行数据迁移。
++ 序列分区的负载相对均衡,因为序列分区的数量远小于生产环境中部署的传感器数量。
-每个数据库持有固定数量的序列分区槽,默认为1000个。该数据库管理的每个时间序列都将通过序列分区算法(通常为某种哈希算法)被分配给唯一的序列分区槽管理。
+更进一步,如果能够更准确地估计生产环境中的实际负载情况,序列分区算法可以配置为自定义的哈希分区或列表分区,以在所有序列分区中实现更均匀的负载分布。
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/SeriesPartitionSlot.png?raw=true">
+##### 时间分区算法
+时间分区算法通过下式将给定的时间戳转换为相应的时间分区
-### 时间分区槽
+$$\left\lfloor\frac{\text{Timestamp}-\text{StartTimestamp}}{\text{TimePartitionInterval}}\right\rfloor。$$
-每个时间序列都将持续产生数据,如果一个时间序列产生的全部数据持续存储于一个节点,那么集群新增的 DataNode 可能无法得到有效利用。
+在此式中,$\text{StartTimestamp}$ 和 $\text{TimePartitionInterval}$
都是可配置参数,以适应不同的生产环境。$\text{StartTimestamp}$ 表示第一个时间分区的起始时间,而
$\text{TimePartitionInterval}$
定义了每个时间分区的持续时间。默认情况下,$\text{TimePartitionInterval}$ 设置为一天。
-时间分区槽从时间维度对时序数据进行分片(默认为每 7 天一个时间分区),使得集群时序数据的存储易于规划。
+#### 元数据分区
+由于序列分区算法对时间序列进行了均匀分区,每个序列分区对应一个元数据分区。这些元数据分区随后被均匀分配到 元数据分片 中,以实现元数据的均衡分布。
-## 元数据分区
+#### 数据分区
+结合序列分区与时间分区创建数据分区。由于序列分区算法对时间序列进行了均匀分区,特定时间分区内的数据分区负载保持均衡。这些数据分区随后被均匀分配到数据分片中,以实现数据的均衡分布。
-单个数据库的元数据分区管理,会按照一定的负载均衡策略,将所有序列槽分配到相应的 SchemaRegionGroup 中,进而在集群中横向扩展。
+### 分区分配
+IoTDB 使用分片来实现时间序列的弹性存储,集群中分片的数量由所有数据节点的总资源决定。由于分片的数量是动态的,IoTDB
可以轻松扩展。元数据分片和数据分片都遵循相同的分区分配算法,即均匀划分所有序列分区。下图展示了分区分配过程,其中动态扩展的分片匹配不断扩展的时间序列和集群。
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/SchemaRegion.png?raw=true">
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/partition_allocation_cn.png?raw=true">
-## 数据分区
+#### 分片扩容
+分片的数量由下式给出
-会按照一定的负载均衡策略,进行时间分区槽和序列分区槽的划分,并分配到相应的 DataRegionGroup 中,进而在集群中横向扩展。
+$$\text{RegionGroupNumber}=\left\lfloor\frac{\sum_{i=1}^{DataNodeNumber}\text{RegionNumber}_i}{\text{ReplicationFactor}}\right\rfloor。$$
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/DataRegion.png?raw=true">
+在此式中,$\text{RegionNumber}_i$ 表示期望在第 $i$ 个数据节点上放置的副本数量,而
$\text{ReplicationFactor}$ 表示每个分片中的副本数量。$\text{RegionNumber}_i$ 和
$\text{ReplicationFactor}$ 都是可配置的参数。$\text{RegionNumber}_i$ 可以根据第 $i$
个数据节点上的可用硬件资源(如 CPU 核心数量、内存大小等)确定,以适应不同的物理服务器。$\text{ReplicationFactor}$
可以调整以确保不同级别的容错能力。
-## 负载均衡
+#### 分配策略
+元数据分片和数据分片都遵循相同的分配策略,即均匀划分所有序列分区。因此,每个元数据分片持有相同数量的元数据分区,以确保元数据存储均衡。同样,对于每个时间分区,每个数据分片
获取与其持有的序列分区对应的数据分区。因此,时间分区内的数据分区均匀分布在所有数据分片中,确保每个时间分区内的数据存储均衡。
-当集群容量保持不变时,数据会被均匀分配到各个节点,以实现存储和计算资源的均衡利用。
+值得注意的是,IoTDB 有效利用了时序数据的特性。当配置了 TTL(生存时间)时,IoTDB
可实现无需迁移的时序数据弹性存储,该功能在集群扩展时最小化了对在线操作的影响。上图展示了该功能的一个实例:新生成的数据分区被均匀分配到每个数据分片,过期数据会自动归档。因此,集群的存储最终将保持平衡。
-同时,在进行集群扩容时,系统会自动增加区域(region)的数量,以充分利用所有节点的计算资源,无需人工干预。这种动态扩展能够提高集群的性能和可扩展性,使整个系统更加灵活和高效。
+## 均衡策略
+为了提高集群的可用性和性能,IoTDB 采用了精心设计的存储均衡和计算均衡算法。
+
+### 存储均衡
+数据节点持有的副本数量反映了它的存储负载。如果数据节点之间的副本数量差异较大,拥有更多副本的数据节点可能成为存储瓶颈。尽管简单的轮询(Round
Robin)放置算法可以通过确保每个数据节点持有等量副本来实现存储均衡,但它会降低集群的容错能力,如下所示:
+
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/placement_cn.png?raw=true">
+
++ 假设集群有 4 个数据节点,4 个分片,并且副本因子为 2。
++ 将分片 $r_1$ 的 2 个副本放置在数据节点 $n_1$ 和 $n_2$ 上。
++ 将分片 $r_2$ 的 2 个副本放置在数据节点 $n_3$ 和 $n_4$ 上。
++ 将分片 $r_3$ 的 2 个副本放置在数据节点 $n_1$ 和 $n_3$ 上。
++ 将分片 $r_4$ 的 2 个副本放置在数据节点 $n_2$ 和 $n_4$ 上。
+
+在这种情况下,如果数据节点 $n_2$ 发生故障,由它先前负责的负载将只能全部转移到数据节点 $n_1$,可能导致其过载。
+
+为了解决这个问题,IoTDB 采用了一种副本放置算法,该算法不仅将副本均匀放置到所有数据节点上,还确保每个
数据节点在发生故障时,能够将其负载转移到足够多的其他数据节点。因此,集群实现了存储分布的均衡,并具备较高的容错能力,从而确保其可用性。
+
+### 计算均衡
+数据节点持有的主副本数量反映了它的计算负载。如果数据节点之间持有主副本数量差异较大,拥有更多主副本的数据节点可能成为计算瓶颈。如果主副本选择过程使用直观的贪心算法,当副本以容错算法放置时,可能会导致主副本分布不均,如下所示:
+
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/selection_cn.png?raw=true">
+
++ 假设集群有 4 个数据节点,4 个分片,并且副本因子为 2。
++ 选择分片 $r_5$ 在数据节点 $n_5$ 上的副本作为主副本。
++ 选择分片 $r_6$ 在数据节点 $n_7$ 上的副本作为主副本。
++ 选择分片 $r_7$ 在数据节点 $n_7$ 上的副本作为主副本。
++ 选择分片 $r_8$ 在数据节点 $n_8$ 上的副本作为主副本。
+
+请注意,以上步骤严格遵循贪心算法。然而,到第 3 步时,无论在数据节点 $n_5$ 或 $n_7$ 上选择分片 $r_7$
的主副本,都会导致主副本分布不均衡。根本原因在于每一步贪心选择都缺乏全局视角,最终导致局部最优解。
+
+为了解决这个问题,IoTDB 采用了一种主副本选择算法,能够持续平衡集群中的主副本分布。因此,集群实现了计算负载的均衡分布,确保了其性能。
+
+## Source Code
++
[数据分区](https://github.com/apache/iotdb/tree/master/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition)
++
[分区分配](https://github.com/apache/iotdb/tree/master/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/balancer/partition)
++
[副本放置](https://github.com/apache/iotdb/tree/master/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/balancer/副本)
++
[主副本选择](https://github.com/apache/iotdb/tree/master/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/balancer/router/主副本)
\ No newline at end of file
diff --git a/src/zh/UserGuide/latest/Basic-Concept/Cluster-data-partitioning.md
b/src/zh/UserGuide/latest/Basic-Concept/Cluster-data-partitioning.md
index 943659c..a221fe4 100644
--- a/src/zh/UserGuide/latest/Basic-Concept/Cluster-data-partitioning.md
+++ b/src/zh/UserGuide/latest/Basic-Concept/Cluster-data-partitioning.md
@@ -19,42 +19,92 @@
-->
-# 数据分区与负载均衡
+# 分区与负载均衡
+本文档介绍 IoTDB 中的分区策略和负载均衡策略。根据时序数据的特性,IoTDB
按序列和时间维度对其进行分区。结合序列分区与时间分区创建一个分区,作为划分的基本单元。为了提高吞吐量并降低管理成本,这些分区被均匀分配到分片(Region)中,分片是复制的基本单元。分片的副本决定了数据的存储位置,主副本负责主要负载的管理。在此过程中,副本放置算法决定哪些节点将持有分片副本,而主副本选择算法则指定哪个副本将成为主副本。
-IoTDB 以数据分区(DataRegion)为单位对元数据和数据进行管理,从序列和时间两个维度进行数据划分。
+## 分区策略和分区分配
+IoTDB
为时间序列数据实现了量身定制的分区算法。在此基础上,缓存于配置节点和数据节点上的分区信息不仅易于管理,而且能够清晰区分冷热数据。随后,平衡的分区被均匀分配到集群的分片中,以实现存储均衡。
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/%E5%88%86%E5%8C%BA%E6%A7%BD%E4%B8%8E%E6%95%B0%E6%8D%AE%E5%88%86%E5%8C%BA.png?raw=true">
+### 分区策略
+IoTDB 将生产环境中的每个传感器映射为一个时间序列。然后,使用序列分区算法对时间序列进行分区以管理其元数据,再结合时间分区算法来管理其数据。下图展示了
IoTDB 如何对时序数据进行分区。
-## 分区槽
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/partition_table_cn.png?raw=true">
-一个序列分区槽和一个时间分区槽可以组合产生一个数据分区(当该序列分区槽在该时间分区槽下有对应数据时)。
+#### 分区策略
+由于生产环境中通常部署大量设备和传感器,IoTDB 使用序列分区算法以确保分区信息的大小可控。由于生成的时间序列与时间戳相关联,IoTDB
使用时间分区算法来清晰区分冷热分区。
-### 序列分区槽
+##### 序列分区算法
+默认情况下,IoTDB 将序列分区的数量限制为 1000,并将序列分区算法配置为哈希分区算法。这带来以下收益:
++ 由于序列分区的数量是固定常量,序列与序列分区之间的映射保持稳定。因此,IoTDB 不需要频繁进行数据迁移。
++ 序列分区的负载相对均衡,因为序列分区的数量远小于生产环境中部署的传感器数量。
-每个数据库持有固定数量的序列分区槽,默认为1000个。该数据库管理的每个时间序列都将通过序列分区算法(通常为某种哈希算法)被分配给唯一的序列分区槽管理。
+更进一步,如果能够更准确地估计生产环境中的实际负载情况,序列分区算法可以配置为自定义的哈希分区或列表分区,以在所有序列分区中实现更均匀的负载分布。
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/SeriesPartitionSlot.png?raw=true">
+##### 时间分区算法
+时间分区算法通过下式将给定的时间戳转换为相应的时间分区
-### 时间分区槽
+$$\left\lfloor\frac{\text{Timestamp}-\text{StartTimestamp}}{\text{TimePartitionInterval}}\right\rfloor。$$
-每个时间序列都将持续产生数据,如果一个时间序列产生的全部数据持续存储于一个节点,那么集群新增的 DataNode 可能无法得到有效利用。
+在此式中,$\text{StartTimestamp}$ 和 $\text{TimePartitionInterval}$
都是可配置参数,以适应不同的生产环境。$\text{StartTimestamp}$ 表示第一个时间分区的起始时间,而
$\text{TimePartitionInterval}$
定义了每个时间分区的持续时间。默认情况下,$\text{TimePartitionInterval}$ 设置为一天。
-时间分区槽从时间维度对时序数据进行分片(默认为每 7 天一个时间分区),使得集群时序数据的存储易于规划。
+#### 元数据分区
+由于序列分区算法对时间序列进行了均匀分区,每个序列分区对应一个元数据分区。这些元数据分区随后被均匀分配到 元数据分片 中,以实现元数据的均衡分布。
-## 元数据分区
+#### 数据分区
+结合序列分区与时间分区创建数据分区。由于序列分区算法对时间序列进行了均匀分区,特定时间分区内的数据分区负载保持均衡。这些数据分区随后被均匀分配到数据分片中,以实现数据的均衡分布。
-单个数据库的元数据分区管理,会按照一定的负载均衡策略,将所有序列槽分配到相应的 SchemaRegionGroup 中,进而在集群中横向扩展。
+### 分区分配
+IoTDB 使用分片来实现时间序列的弹性存储,集群中分片的数量由所有数据节点的总资源决定。由于分片的数量是动态的,IoTDB
可以轻松扩展。元数据分片和数据分片都遵循相同的分区分配算法,即均匀划分所有序列分区。下图展示了分区分配过程,其中动态扩展的分片匹配不断扩展的时间序列和集群。
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/SchemaRegion.png?raw=true">
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/partition_allocation_cn.png?raw=true">
-## 数据分区
+#### 分片扩容
+分片的数量由下式给出
-会按照一定的负载均衡策略,进行时间分区槽和序列分区槽的划分,并分配到相应的 DataRegionGroup 中,进而在集群中横向扩展。
+$$\text{RegionGroupNumber}=\left\lfloor\frac{\sum_{i=1}^{DataNodeNumber}\text{RegionNumber}_i}{\text{ReplicationFactor}}\right\rfloor。$$
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/DataRegion.png?raw=true">
+在此式中,$\text{RegionNumber}_i$ 表示期望在第 $i$ 个数据节点上放置的副本数量,而
$\text{ReplicationFactor}$ 表示每个分片中的副本数量。$\text{RegionNumber}_i$ 和
$\text{ReplicationFactor}$ 都是可配置的参数。$\text{RegionNumber}_i$ 可以根据第 $i$
个数据节点上的可用硬件资源(如 CPU 核心数量、内存大小等)确定,以适应不同的物理服务器。$\text{ReplicationFactor}$
可以调整以确保不同级别的容错能力。
-## 负载均衡
+#### 分配策略
+元数据分片和数据分片都遵循相同的分配策略,即均匀划分所有序列分区。因此,每个元数据分片持有相同数量的元数据分区,以确保元数据存储均衡。同样,对于每个时间分区,每个数据分片
获取与其持有的序列分区对应的数据分区。因此,时间分区内的数据分区均匀分布在所有数据分片中,确保每个时间分区内的数据存储均衡。
-当集群容量保持不变时,数据会被均匀分配到各个节点,以实现存储和计算资源的均衡利用。
+值得注意的是,IoTDB 有效利用了时序数据的特性。当配置了 TTL(生存时间)时,IoTDB
可实现无需迁移的时序数据弹性存储,该功能在集群扩展时最小化了对在线操作的影响。上图展示了该功能的一个实例:新生成的数据分区被均匀分配到每个数据分片,过期数据会自动归档。因此,集群的存储最终将保持平衡。
-同时,在进行集群扩容时,系统会自动增加区域(region)的数量,以充分利用所有节点的计算资源,无需人工干预。这种动态扩展能够提高集群的性能和可扩展性,使整个系统更加灵活和高效。
+## 均衡策略
+为了提高集群的可用性和性能,IoTDB 采用了精心设计的存储均衡和计算均衡算法。
+
+### 存储均衡
+数据节点持有的副本数量反映了它的存储负载。如果数据节点之间的副本数量差异较大,拥有更多副本的数据节点可能成为存储瓶颈。尽管简单的轮询(Round
Robin)放置算法可以通过确保每个数据节点持有等量副本来实现存储均衡,但它会降低集群的容错能力,如下所示:
+
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/placement_cn.png?raw=true">
+
++ 假设集群有 4 个数据节点,4 个分片,并且副本因子为 2。
++ 将分片 $r_1$ 的 2 个副本放置在数据节点 $n_1$ 和 $n_2$ 上。
++ 将分片 $r_2$ 的 2 个副本放置在数据节点 $n_3$ 和 $n_4$ 上。
++ 将分片 $r_3$ 的 2 个副本放置在数据节点 $n_1$ 和 $n_3$ 上。
++ 将分片 $r_4$ 的 2 个副本放置在数据节点 $n_2$ 和 $n_4$ 上。
+
+在这种情况下,如果数据节点 $n_2$ 发生故障,由它先前负责的负载将只能全部转移到数据节点 $n_1$,可能导致其过载。
+
+为了解决这个问题,IoTDB 采用了一种副本放置算法,该算法不仅将副本均匀放置到所有数据节点上,还确保每个
数据节点在发生故障时,能够将其负载转移到足够多的其他数据节点。因此,集群实现了存储分布的均衡,并具备较高的容错能力,从而确保其可用性。
+
+### 计算均衡
+数据节点持有的主副本数量反映了它的计算负载。如果数据节点之间持有主副本数量差异较大,拥有更多主副本的数据节点可能成为计算瓶颈。如果主副本选择过程使用直观的贪心算法,当副本以容错算法放置时,可能会导致主副本分布不均,如下所示:
+
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://alioss.timecho.com/docs/img/selection_cn.png?raw=true">
+
++ 假设集群有 4 个数据节点,4 个分片,并且副本因子为 2。
++ 选择分片 $r_5$ 在数据节点 $n_5$ 上的副本作为主副本。
++ 选择分片 $r_6$ 在数据节点 $n_7$ 上的副本作为主副本。
++ 选择分片 $r_7$ 在数据节点 $n_7$ 上的副本作为主副本。
++ 选择分片 $r_8$ 在数据节点 $n_8$ 上的副本作为主副本。
+
+请注意,以上步骤严格遵循贪心算法。然而,到第 3 步时,无论在数据节点 $n_5$ 或 $n_7$ 上选择分片 $r_7$
的主副本,都会导致主副本分布不均衡。根本原因在于每一步贪心选择都缺乏全局视角,最终导致局部最优解。
+
+为了解决这个问题,IoTDB 采用了一种主副本选择算法,能够持续平衡集群中的主副本分布。因此,集群实现了计算负载的均衡分布,确保了其性能。
+
+## Source Code
++
[数据分区](https://github.com/apache/iotdb/tree/master/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition)
++
[分区分配](https://github.com/apache/iotdb/tree/master/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/balancer/partition)
++
[副本放置](https://github.com/apache/iotdb/tree/master/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/balancer/副本)
++
[主副本选择](https://github.com/apache/iotdb/tree/master/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/balancer/router/主副本)
\ No newline at end of file