> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ClickHouse 集群发现文档

# 集群发现

<div id="overview">
  ## 概述
</div>

ClickHouse 的 集群发现 功能可让节点自动发现并注册自身，无需在配置文件中逐一定义，从而简化集群配置。在必须手动定义每个节点时，这项功能尤其有用。

<Note>
  集群发现 是一项 Experimental 功能，未来版本中可能会发生变更或被移除。
  要启用该功能，请在配置文件中加入 `allow_experimental_cluster_discovery` 设置：

  ```xml theme={null}
  <clickhouse>
      <!-- ... -->
      <allow_experimental_cluster_discovery>1</allow_experimental_cluster_discovery>
      <!-- ... -->
  </clickhouse>
  ```
</Note>

<div id="remote-servers-configuration">
  ## 远程服务器配置
</div>

<div id="traditional-manual-configuration">
  ### 传统的手动配置
</div>

以往，在 ClickHouse 中，集群中的每个分片和副本都需要在配置中手动指定：

```xml theme={null}
<remote_servers>
    <cluster_name>
        <shard>
            <replica>
                <host>node1</host>
                <port>9000</port>
            </replica>
            <replica>
                <host>node2</host>
                <port>9000</port>
            </replica>
        </shard>
        <shard>
            <replica>
                <host>node3</host>
                <port>9000</port>
            </replica>
            <replica>
                <host>node4</host>
                <port>9000</port>
            </replica>
        </shard>
    </cluster_name>
</remote_servers>

```

<div id="using-cluster-discovery">
  ### 使用集群发现
</div>

使用 Cluster Discovery 时，无需逐个显式定义节点，只需在 ZooKeeper 中指定一个 path。所有在 ZooKeeper 中注册到该 path 下的节点都会被自动发现并添加到 cluster 中。

```xml theme={null}
<remote_servers>
    <cluster_name>
        <discovery>
            <path>/clickhouse/discovery/cluster_name</path>

            <!-- # 可选配置参数： -->

            <!-- ## 访问集群中其他节点所需的身份验证凭据： -->
            <!-- <user>user1</user> -->
            <!-- <password>pass123</password> -->
            <!-- ### 也可使用节点间 secret 代替密码： -->
            <!-- <secret>secret123</secret> -->

            <!-- ## 当前节点的分片（见下文）： -->
            <!-- <shard>1</shard> -->

            <!-- ## 观察者模式（见下文）： -->
            <!-- <observer/> -->
        </discovery>
    </cluster_name>
</remote_servers>
```

如果你想为某个节点指定分片编号，可以在 `<discovery>` 部分内添加 `<shard>` 标签：

对于 `node1` 和 `node2`：

```xml theme={null}
<discovery>
    <path>/clickhouse/discovery/cluster_name</path>
    <shard>1</shard>
</discovery>
```

对于 `node3` 和 `node4`：

```xml theme={null}
<discovery>
    <path>/clickhouse/discovery/cluster_name</path>
    <shard>2</shard>
</discovery>
```

<div id="observer-mode">
  ### 观察者模式
</div>

配置为观察者模式的节点不会将自己注册为副本。
它们只会观察并发现集群中其他处于活动状态的副本，而不会主动参与。
要启用观察者模式，请在 `<discovery>` 部分中添加 `<observer/>` 标签：

```xml theme={null}
<discovery>
    <path>/clickhouse/discovery/cluster_name</path>
    <observer/>
</discovery>
```

<div id="discovery-of-clusters">
  ### 集群发现
</div>

有时，您可能不仅需要添加和移除集群中的主机，还需要添加和移除集群本身。您可以使用 `<multicluster_root_path>` 节点，为多个集群指定根路径：

```xml theme={null}
<remote_servers>
    <some_unused_name>
        <discovery>
            <multicluster_root_path>/clickhouse/discovery</multicluster_root_path>
            <observer/>
        </discovery>
    </some_unused_name>
</remote_servers>
```

在这种情况下，当其他主机通过路径 `/clickhouse/discovery/some_new_cluster` 注册自身时，就会添加一个名为 `some_new_cluster` 的集群。

你可以同时使用这两种功能：主机既可以在集群 `my_cluster` 中注册自身，也可以发现其他任意集群：

```xml theme={null}
<remote_servers>
    <my_cluster>
        <discovery>
            <path>/clickhouse/discovery/my_cluster</path>
        </discovery>
    </my_cluster>
    <some_unused_name>
        <discovery>
            <multicluster_root_path>/clickhouse/discovery</multicluster_root_path>
            <observer/>
        </discovery>
    </some_unused_name>
</remote_servers>
```

限制：

* 不能在同一个 `remote_servers` 子树中同时使用 `<path>` 和 `<multicluster_root_path>`。
* `<multicluster_root_path>` 只能与 `<observer/>` 搭配使用。
* 集群名称使用 Keeper 中路径的最后一部分；而在注册时，该名称取自 XML 标签。

<div id="use-cases-and-limitations">
  ## 用例和限制
</div>

当节点被添加到指定的 ZooKeeper 路径或从中移除时，无需更改配置或重启服务器，系统就会自动发现这些节点，或将其从集群中移除。

但是，这些变更只会影响集群配置，不会影响数据或现有的数据库和表。

请考虑以下一个包含 3 个节点的集群示例：

```xml theme={null}
<remote_servers>
    <default>
        <discovery>
            <path>/clickhouse/discovery/default_cluster</path>
        </discovery>
    </default>
</remote_servers>
```

```sql theme={null}
SELECT * EXCEPT (default_database, errors_count, slowdowns_count, estimated_recovery_time, database_shard_name, database_replica_name)
FROM system.clusters WHERE cluster = 'default';

┌─cluster─┬─shard_num─┬─shard_weight─┬─replica_num─┬─host_name────┬─host_address─┬─port─┬─is_local─┬─user─┬─is_active─┐
│ default │         1 │            1 │           1 │ 92d3c04025e8 │ 172.26.0.5   │ 9000 │        0 │      │      ᴺᵁᴸᴸ │
│ default │         1 │            1 │           2 │ a6a68731c21b │ 172.26.0.4   │ 9000 │        1 │      │      ᴺᵁᴸᴸ │
│ default │         1 │            1 │           3 │ 8e62b9cb17a1 │ 172.26.0.2   │ 9000 │        0 │      │      ᴺᵁᴸᴸ │
└─────────┴───────────┴──────────────┴─────────────┴──────────────┴──────────────┴──────┴──────────┴──────┴───────────┘
```

```sql theme={null}
CREATE TABLE event_table ON CLUSTER default (event_time DateTime, value String)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/event_table', '{replica}')
ORDER BY event_time PARTITION BY toYYYYMM(event_time);

INSERT INTO event_table ...
```

然后，我们向集群中添加一个新节点：在配置文件的 `remote_servers` 部分中为其使用相同的条目来启动该新节点：

```response theme={null}
┌─cluster─┬─shard_num─┬─shard_weight─┬─replica_num─┬─host_name────┬─host_address─┬─port─┬─is_local─┬─user─┬─is_active─┐
│ default │         1 │            1 │           1 │ 92d3c04025e8 │ 172.26.0.5   │ 9000 │        0 │      │      ᴺᵁᴸᴸ │
│ default │         1 │            1 │           2 │ a6a68731c21b │ 172.26.0.4   │ 9000 │        1 │      │      ᴺᵁᴸᴸ │
│ default │         1 │            1 │           3 │ 8e62b9cb17a1 │ 172.26.0.2   │ 9000 │        0 │      │      ᴺᵁᴸᴸ │
│ default │         1 │            1 │           4 │ b0df3669b81f │ 172.26.0.6   │ 9000 │        0 │      │      ᴺᵁᴸᴸ │
└─────────┴───────────┴──────────────┴─────────────┴──────────────┴──────────────┴──────┴──────────┴──────┴───────────┘
```

第四个节点已加入集群，但表 `event_table` 仍然只存在于前三个节点上：

```sql theme={null}
SELECT hostname(), database, table FROM clusterAllReplicas(default, system.tables) WHERE table = 'event_table' FORMAT PrettyCompactMonoBlock

┌─hostname()───┬─database─┬─table───────┐
│ a6a68731c21b │ default  │ event_table │
│ 92d3c04025e8 │ default  │ event_table │
│ 8e62b9cb17a1 │ default  │ event_table │
└──────────────┴──────────┴─────────────┘
```

如果您需要在所有节点上复制表，可使用 [Replicated](/docs/zh/reference/engines/database-engines/replicated) 数据库引擎，作为集群发现的替代方案。
