ON CLUSTER DDL 因 NO_ELEMENTS_IN_CONFIG 失败

症状

使用 ON CLUSTER 的任何语句都会立即失败:

Code: 139. DB::Exception: There is no Zookeeper configuration in server config.
(NO_ELEMENTS_IN_CONFIG)

普通的单主机 DDL 可以正常工作。CREATE TABLE ... ENGINE = ReplicatedMergeTree(...) 也会因相同原因失败。

原因

ON CLUSTER 会通过协调仲裁来广播语句,因此服务器需要在其配置中包含协调元素。只有当实例声明了协调节点时,operator 才会写入该元素。未声明节点时,不会写入任何内容,服务器也就没有可用于广播的目标。

标准服务器配置本身已启用分布式 DDL,因此无需额外打开某个设置。缺失的部分始终是协调元素。

确认

检查实例是否声明了节点:

kubectl -n <namespace> get chi <instance> \
  -o jsonpath='{.spec.configuration.zookeeper}{"\n"}'

输出为空即表示未声明节点。

检查服务器实际接收到的内容:

kubectl -n <namespace> exec <pod> -c clickhouse -- \
  grep -rl zookeeper /etc/clickhouse-server/config.d /etc/clickhouse-server/conf.d

并直接向服务器查询:

SELECT name FROM system.zookeeper WHERE path = '/';

此处失败表示服务器未配置协调功能,或无法访问已配置的协调服务。

修复

声明仲裁。operator 不会部署仲裁,因此仲裁必须已经存在。

spec:
  configuration:
    zookeeper:
      nodes:
        - host: keeper-0.keeper-headless.<quorum-namespace>
        - host: keeper-1.keeper-headless.<quorum-namespace>
        - host: keeper-2.keeper-headless.<quorum-namespace>

port 默认为 2181,对于标准仲裁可以省略。相同配置块中还提供其他可调参数,包括会话和操作超时、根路径,以及用于身份验证仲裁的身份标识。

实例中的单个集群也可以使用自己的 zookeeper 配置块覆盖实例级设置。

应用更改。operator 会重新渲染主机配置,并逐个滚动重启主机。

验证

SELECT name FROM system.zookeeper WHERE path = '/';

CREATE DATABASE IF NOT EXISTS probe ON CLUSTER '{cluster}';
DROP DATABASE IF EXISTS probe ON CLUSTER '{cluster}';

如果已声明节点但仍然失败

元素虽然存在,但不可用。请按以下顺序检查:

  1. 从服务器 pod 到每个声明的地址和端口的名称解析和可达性

  2. 仲裁健康状况。 未选出 leader 的仲裁无法提供有用响应。检查仲裁自身的状态。

  3. 根路径。 如果设置了根路径,该路径必须已存在于仲裁中;服务器不会创建它。

  4. 配置是否已到达 pod。 配置通过挂载的 ConfigMap 交付,而挂载的 ConfigMap 更新不会立即生效。operator 提供了可配置的传播超时,正是出于这一原因。如果 pod 中的内容较旧,请等待下一次 reconcile,或检查 operator 日志。

    kubectl -n <namespace> exec <pod> -c clickhouse -- getent hosts keeper-0.keeper-headless.<quorum-namespace>
    kubectl -n <operator-namespace> logs deploy/clickhouse-operator -c clickhouse-operator | tail -50

ClickHouse 是 ClickHouse, Inc. 的注册商标。https://clickhouse.com

Alauda 是独立供应商。本产品与 ClickHouse, Inc. 不存在关联,也未获得其认可或赞助。所有商标均归其各自所有者所有,此处仅用于标识目的。