更新时间:2024-11-29 GMT+08:00

缩容ClickHouseServer约束限制

集群规模

  • 集群只有1个shard分片,无法进行退服。
  • 同一个shard分片下的多个节点副本必须一起退服或入服。

    查询集群分片信息操作:

    1. 以客户端安装用户,登录安装客户端的节点,执行命令:

      cd {客户端安装目录}

      source bigdata_env

      安全模式:

      kinit ClickHouse组件业务用户

      clickhouse client --host ClickHouse的实例IP --port 9440--secure

      普通模式:

      clickhouse client --host ClickHouse的实例IP --user 用户名 --password --port 9000

      输入用户密码

    2. 执行如下命令查询集群分片信息:

      select cluster,shard_num,replica_num,host_name from system.clusters;

集群存储空间

集群退服操作前,集群非退服节点磁盘空间需要满足存储所有退服节点的数据,并且各非退服节点的存储空间在退服后还能有大约10%的空间冗余,保证退服后剩余实例正常运行。具体操作步骤如下:

  1. 执行此命令收集各节点磁盘空间存储情况:

    select * from system.disks;

    free_space列表示磁盘空闲空间,total_space列表示磁盘总空间,total_space-free_space大小即为磁盘已使用空间,获取的值均以字节为单位。

  2. 在退服节点执行上述命令,计算total_space-free_space磁盘已使用空间,得到退服节点数据量大小。
  3. 在非退服节点执行上述命令,计算(free_space可用空间大小-退服节点数据量)/total_space总存储空间大小,如果结果大于10%,即可正常退服。

集群状态

若集群中存在故障的ClickHouseServer实例节点(包括要退服的节点和非退服节点),则无法进行退服。登录Manager页面,选择“集群 > 服务 > ClickHouse”,单击“实例”,查看“运行状态”列,即可获得集群各节点的状态。

数据库

若某数据库只存在于待退服实例节点上,则无法进行退服。需要在集群所有ClickHouseServer实例节点上创建该数据库。具体操作步骤如下:

  1. 执行此命令收集各节点数据库列表:select * from system.databases;

    name列为数据库名,engine列为数据库引擎,默认为Atomic。若为默认引擎,建表时可不指定引擎。

  2. 对于只存在于待退服实例节点的数据库,执行此命令创建数据库:

    create database xxx engine=xxx on cluster xxx;

本地非复制表

若某本地非复制表只存在于待退服实例节点上,则无法进行退服。需要在非退服任意一个节点上创建同名的本地非复制表。

比如,当前集群2个分片,分片1下面有两个节点A和B,分片2下面有两个节点C和D。创建非复制表test的时候没有携带ON CLUSTER关键字,只在节点A上创建了该表。

当前如果要退服分片1下面的A和B节点时,则不允许退服,需要在分片2的C或者D一个节点上创建表test后才能正常退服。

使用如下命令收集各节点数据表:

select database,name,engine,create_table_query from system.tables where database != 'system';

根据结果:

  • 查看engine列,不含Replicated字段的表是本地非复制表。
  • 对于未退服节点上不存在的本地非复制表,根据create_table_query列的建表语句进行创建,建表语句样例如下:

    CREATE TABLE {database}.{table} (‘column name’ type…) ENGINE = MergeTree;

复制表

若某复制表只存在于集群的部分实例节点上,则无法对该复制表所在的实例节点进行退服。需要在集群中不存在此复制表的所有实例节点上手工创建此复制表。

比如,当前集群2个分片,分片1下面有两个节点A和B,分片2下面有两个节点C和D。创建复制表test的时候没有携带ON CLUSTER关键字,只在节点A和B上创建了该表。

当前如果要退服分片1下面的A和B节点时,则不允许退服,需要在分片2的C和D节点上同时创建复制表test后才能正常退服。

使用如下命令收集各节点数据表:

select database,name,engine,create_table_query from system.tables where database != 'system';

根据结果:

  • 查看engine列,包含Replicated字段的表即为复制表。
  • 对于未退服节点上不存在的复制表,根据create_table_query列的建表语句结果进行创建。

分布式表

退服不支持分布式表自动迁移,建议退服前在非退服节点上重建分布式表。

使用如下命令收集各节点数据表,查看engine列,engine是Distributed引擎即为分布式表:

select database,name,engine from system.tables where database != 'system';

退服前,在非退服节点不重建分布式表本身不影响退服操作,只是可能影响后续业务操作。

视图

退服不支持视图自动迁移,且视图不存储数据。可以使用如下命令收集各节点数据表,查看engine列,engine是View引擎即为视图:

select database,name,engine from system.tables where database != 'system';

再执行如下命令将视图逐个删除:

drop view {database_name}.{table_name};

物化视图

退服不支持物化视图自动迁移,建议在非退服节点上重建物化视图。若待退服节点物化视图未显示指定聚合表而是使用内嵌表的情况,无法进行退服。

执行如下命令收集各节点数据表,查看engine列,是MaterializedView即为物化视图。

select database,name,engine, create_table_query from system.tables where database != 'system';

create_table_query列含POPULATE 字段的表为内嵌表,在创建视图的时候初始化视图数据,缺点是初始化视图数据期间,新插入的数据被忽略;不含POPULATE 字段的表为聚合表,新插入的数据直接插入到视图表和支持表中,而之前的数据通过手动加载的方式插入视图和支持表。聚合表和内嵌表的建表操作需分别处理。

执行如下操作处理退服节点的物化视图:

  1. 先记录下退服节点的物化视图,并将其全部删除。

    drop view {database_name}.{table_name};

  2. 退服完成后,在非退服节点对相应的物化视图,执行删除再创建,更新为最新结果的物化视图。
  3. 聚合表的创建可以通过WHERE指定条件过滤掉历史数据,然后手动将历史数据导入物化视图。如果不指定的话,容易导致无法采用统一条件将历史数据导入物化视图,从而出现数据重复导入的情况。比如,可以设置更新点,该时间点之前的数据使用INSERT的方式手动加载旧数据。
    • 在建表语句中加入,WHERE { 时间字段(如Date)}>= toDate ({ 当前时间(如'2022-12-01 00:00:00')})
    • 加载旧数据时使用:insert into {table} select {表字段} from {源表} where {时间字段}< toDate ({当前时间})
  4. 内嵌表会丢失建表过程中的数据,也可以使用WHERE指定条件过滤掉全部历史数据,此时会建立一张空表,再将历史数据源表数据手动全量INSERT即可。

第三方引擎的表

退服目前不支持第三方引擎的表自动迁移。

使用如下命令收集各节点数据表,查看engine列,除包含MergeTree、View、MaterializedView、Distributed、Log字段外的其他数据表即为第三方引擎的表,如Memory、HDFS、MySQL等:

select database,name,engine from system.tables where database != 'system';

对于以上第三方引擎表,建议在非退服节点上重建该表,并在退服节点删除该表。

Detached数据

若待退服节点上的表进行过detach操作,在detached目录下还存在数据,则无法进行退服。需要先进行attach操作将detached目录下数据处理后再执行退服操作。

  1. 执行如下命令查看退服节点的system.detached_parts系统表:

    select * from system.detached_parts;

  2. 如果存在detached part数据,在确认这些partition都没有用的情况下,执行如下命令将part数据删除:

    ALTER TABLE {table_name} DROP DETACHED PARTITION {partition_expr} SETTINGS allow_drop_detached = 1;

  3. 执行完成后,再次查看是否system.detached_parts系统表中的数据已不存在,执行如下命令:

    select * from system.detached_parts;

    如果查询结果为空,则表示当前已不存在detached part。