配置复制集群

本页面将构建一个包含 2 个分片 × 2 个副本的 Alauda Data Services Analytical Database E1 集群,并在其中创建一个复制表。

复制的要求

复制和集群范围的 DDL 都需要 ZooKeeper 兼容的协调仲裁集群。该仲裁集群由您提供。 operator 不会部署、扩展或管理仲裁集群,也不存在用于表示仲裁集群的自定义资源。您需要向实例提供一个已存在的仲裁集群的地址。

关于 Keeper 的具体说明:

  • 交付的服务器映像中的 clickhouse 二进制文件支持多调用,并包含 keeper 子命令,因此协调服务与运行服务器的二进制文件相同。本产品没有单独的协调映像。
  • 不存在表示协调仲裁集群的自定义资源,operator 也不会协调任何仲裁集群。如果您选择使用同一映像运行仲裁集群,则需要自行负责其工作负载、存储和配置,方式与其他有状态服务完全相同。

无论使用哪种仲裁集群,实例始终只能通过主机地址列表获知它。

实例

apiVersion: clickhouse.altinity.com/v1
kind: ClickHouseInstallation
metadata:
  name: e1-repl
spec:
  defaults:
    templates:
      dataVolumeClaimTemplate: data-volume
      podTemplate: ch-pod
  configuration:
    zookeeper:
      nodes:
        - host: keeper-0.keeper-headless.<quorum-namespace>
        - host: keeper-1.keeper-headless.<quorum-namespace>
        - host: keeper-2.keeper-headless.<quorum-namespace>
    clusters:
      - name: main
        layout:
          shardsCount: 2
          replicasCount: 2
  templates:
    podTemplates:
      - name: ch-pod
        podDistribution:
          - type: ShardAntiAffinity
        spec:
          securityContext:
            runAsUser: 101
            runAsGroup: 101
            fsGroup: 101
            runAsNonRoot: true
            seccompProfile:
              type: RuntimeDefault
          containers:
            - name: clickhouse
              resources:
                requests:
                  cpu: "2"
                  memory: 8Gi
                limits:
                  cpu: "4"
                  memory: 16Gi
              securityContext:
                allowPrivilegeEscalation: false
                readOnlyRootFilesystem: true
                capabilities:
                  drop:
                    - ALL
    volumeClaimTemplates:
      - name: data-volume
        spec:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 200Gi

注意:

  • 每个节点下的 port 默认为 2181,因此对于标准仲裁集群,您只需要设置 host
  • shardsCount: 2replicasCount: 2 配置了四个主机。每个主机都是包含一个 pod 的独立 StatefulSet,因此您将获得四个 pod 和四个数据卷。
  • 仲裁集群可以位于另一个命名空间中。如果是这样,请使用其完全限定地址。
  • 集群可以使用自己的 zookeeper 块覆盖实例范围的仲裁集群配置,这样同一实例中的两个集群就可以使用独立的仲裁集群。

应用配置并等待全部四个主机:

kubectl -n <namespace> apply -f e1-repl.yaml
kubectl -n <namespace> get statefulset -l clickhouse.altinity.com/chi=e1-repl \
  -o custom-columns=NAME:.metadata.name,DESIRED:.spec.replicas,READY:.status.readyReplicas

确认集群和仲裁集群

SELECT cluster, shard_num, replica_num, host_name
FROM system.clusters
WHERE cluster = 'main'
ORDER BY shard_num, replica_num;

四行数据,包含两个分片,每个分片有两个副本。

然后确认服务器确实可以访问仲裁集群:

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

如果该查询失败,请在创建任何复制表之前停止操作并修复协调配置。请参阅 ON CLUSTER DDL fails with NO_ELEMENTS_IN_CONFIG

operator 会将每个主机的宏写入各主机的配置中,因此只需编写一次表定义,即可将其应用到每个主机:

{installation}实例名称。
{cluster}集群名称。
{shard}此主机的分片名称。
{replica}此主机自身的主机名。

在复制路径中使用这些宏,而不是硬编码主机名。

创建复制表

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

CREATE TABLE IF NOT EXISTS analytics.events ON CLUSTER '{cluster}'
(
    ts    DateTime,
    id    UInt64,
    kind  LowCardinality(String),
    value Float64
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/analytics/events', '{replica}')
PARTITION BY toYYYYMM(ts)
ORDER BY (kind, ts, id);

两个 ReplicatedMergeTree 参数分别是协调路径和副本标识。同一分片的两个副本必须共享路径,并且使用不同的标识;宏可以确保这一点。

要跨分片查询,请在相同的架构上添加一个 Distributed 表:

CREATE TABLE IF NOT EXISTS analytics.events_all ON CLUSTER '{cluster}'
AS analytics.events
ENGINE = Distributed('{cluster}', analytics, events, rand());

在分片上写入 analytics.events,或者写入 analytics.events_all 来分发写入操作。

ON CLUSTER 需要协调元素

ON CLUSTER 并不是客户端便利功能。服务器会通过协调仲裁集群广播该语句,因此服务器配置中必须存在仲裁集群元素。

只有在实例声明了协调节点时,operator 才会生成该元素。没有 zookeeper.nodes 的实例完全不会获得协调元素,此时每条 ON CLUSTER 语句都会因 NO_ELEMENTS_IN_CONFIG 而失败——即使标准服务器配置本身已启用分布式 DDL。缺少的始终是协调元素。

如果无法使用 ON CLUSTER,请在每个主机上分别运行 CREATE 语句。协调配置就绪后,优先使用 ON CLUSTER

添加主机时的架构传播

扩展拓扑时,operator 会在 reconcile 期间将现有架构传播到新主机。它会从已经包含这些对象的主机读取对象定义,将每个 CREATE 重写为 CREATE ... IF NOT EXISTS,然后在新主机上执行。它传播的是复制对象和视图;在分片中至少有两个主机之前,没有可供复制的内容。

此行为由 schemaPolicy 控制:

spec:
  configuration:
    clusters:
      - name: main
        schemaPolicy:
          replica: All
          shard: All

replica 接受 NoneAllshard 接受 NoneAllDistributedTablesOnly。两者默认为 All。将 replica: None 设置为由你自行管理架构。

扩展

增大 replicasCount 可为每个分片添加一个从节点,增大 shardsCount 可添加分片。operator 一次协调一个主机:先将主机从集群中排除,应用更改,等待其就绪,然后再将其重新加入。添加分片不会重新分布现有数据;请单独规划此操作。

验证复制是否正常

SELECT database, table, is_readonly, absolute_delay, queue_size
FROM system.replicas
ORDER BY absolute_delay DESC;

is_readonly = 1 表示从节点已失去协调。不断增长的 queue_sizeabsolute_delay 表示某个从节点正在落后。这两项指标都值得设置告警——请参阅 监控


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

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