You need to enable JavaScript to run this app.
导航

集群健康度

最近更新时间2023.05.29 10:13:50

首次发布时间2023.04.28 18:14:02

健康度定义

集群健康度通过多个维度的健康指标得出的参考性结论。是评判集群的运行状况、出现问题风险的重要风向标。相比监控指标,健康度指标的实时性偏低(每小时采集过去一小时的最大值),反映的问题更偏长期治理解决。

说明

一个类比:监控是体征检测仪,健康度是体检报告。

  • 健康度指标:

    • 评判健康度的各维度指标,包括硬件与系统健康度,ClickHouse 健康度,查询健康度三个大类,9个具体指标(详见下文:指标含义与优化建议)
    • 根据阈值,每项监控指标会定4个不同档位:危险,不及格,及格,良好
  • 健康度等级:

    • 作为集群的整体概览,抽象反映整体健康情况。

    • 有以下四个等级,和健康度指标的档位有对应关系:

      • 危险:有 1 项危险指标;

      • 不及格:没有危险指标,且 1 项以上指标为不及格指标;

      • 及格:没有危险和不及格,且 1 项以上指标为及格;

      • 良好:每一项都是良好。

查看步骤

前提条件:

  • 操作用户是当前集群的 ClusterAdmin 角色,或 SystemAdmin 角色。
  • 集群为“正在运行”状态。

操作步骤

  1. 进入 ByteHouse 企业版,默认进入集群列表页面;
  2. 如在其他页面,可选择 (右上角切换)运维与权限管理 > 集群管理 > 集群列表;
  3. 单击集群名称,进入集群详情,选择“健康度” TAB。

指标含义与优化建议

最大磁盘占用率

指标含义: 数据盘(ByteHouse 目录所在磁盘)的占用率。磁盘使用率过高会影响后续的数据导入。

评分阈值:

健康及格不及格危险
(0,60](60,80](80,95](95,100]

优化建议:

  • 删除不必要的表。可以通过select database, name, total_bytes from system.tables order by total_bytes desc limit 100查看系统中较大的表。
  • 按需调整表的 TTL。
  • 通过界面上方“更改规格”按钮操作,扩容磁盘。
  • 严重时,请先停止所有导入任务。

最大文件数占比

指标含义: 指操作系统的 inode 使用率。过高时会影响集群数据导入和查询。通常是由写入的 Part 太碎,不能及时 Merge 造成的。

评分阈值:

健康及格不及格危险
(0,60](60,80](80,90](90,100]

优化建议:

1. 检查表定义:

如果表定义里面 partition-key 过多,那么就会造成过多的分区。

select database, table, countDistinct(partition_id) as partition_num from system.parts where active group by database, table order by partition_num desc limit 10

通过这个 SQL 对分区特别多的表进行查询。如果存在这种分区极多的表(e.g. >1万),可以考虑让表的责任人调整表结构。

2. 限制导入的频次:

对于 Parts 多的另一个情况就是导入太碎,造成了比较多的零碎 parts,可以通过以下 SQL 查看:

select database, table, count() as partition_num, sum(rows) as total_rows from system.parts where active group by database, table order by partition_num desc limit 10

如果可以看到每个 Partition 所拥有的 Rows 比较少,那么可以确定导入时落盘太频繁;若是 Insert Into 导入,建议每次写一万行以上,若是 Kafka 导入,建议配置 stream_flush_interval_ms 为 8000,即 8 秒攒一批数据写入。

3. 关注 MAP 引起的 Part 过多:

ByteMap 默认为隐式列设计,即每个 key 为 1 列,key 的数量增多可能引起 Parts 过多。

若使用默认多隐式列 MAP ,建议设置 max_map_key_num 参数为 3000,即每个 Map 最多导入 3000 个 key。若超过 3000,则建议使用单隐式列 MAP 和 KV map,可认为无需刻意限制 key 上限。

节点宕机率

指标含义: 无法联通节点 / 全部节点数。

评分阈值:

健康及格不及格危险
0%(0,20](20,50](50,100]

优化建议:

  • ByteHouse 企业版(火山引擎)基于公有云的 ECS 产品,底层资源保持 99.95% 的可用性。如果持续宕机率高,建议提交工单,更换底层设施。
  • ByteHouse 企业版(私有化部署)的底层可能基于任意设施,如果持续宕机率高,可采用“节点替换”功能(支持版本:2.4.1 及以上),更换节点服务器。

集群表个数

指标含义: 集群 *MergeTree 表的总数量。表数量越多,可能会导致 Zookeeper 压力大,导致数据同步问题。

评分阈值:

健康及格不及格危险
[0,500](500,1000](1000,5000]> 5000

优化建议:

  • 删除一些不必要的表,如果确有千张表的需求,建议用多个集群承载。

Kafka 表个数

指标含义: 集群 HaKafka 表的总数量。表数量越多,可能会导致集群的资源均用于写入,无资源查询。

评分阈值:

健康及格不及格危险
[0,20](20,50](50,90]> 90

优化建议:

  • 删除一些不必要的导入任务,如果确有超过50个导入任务的需求,建议用多个集群承载。

单表最大主备同步延迟

指标含义: HaMergeTree/HaUniqueMergeTree 引擎的主备同步日志记录在系统表 ha_queue 中,这个指标标识了 ha_queue 中未处理日志最多的一张表的剩余日志数量,代表这张表的主备同步发生了一些问题,很可能只有一个节点数据完整,在承担查询工作,导致负载不均。

评分阈值:

健康及格不及格危险
[0,100](100,1000](1000,10000]> 10000

处理步骤:

1. 查看是什么表什么类型的 ha_queue 最多

在每个节点上执行:

select database, table, type, count()  from system.ha_queue  group by  database,table, type order by count()

通过此 SQL 可以获得 Part 异常的表。后面的排查操作都是基于对异常表进行。

2. 先确认是否是这些表 Part 过多导致的:

针对ha_queue 剩余日志最多的表,建议根据 最大文件数占比 章节的 “优化建议”,确认当前表是否存在 Part 过多的问题,以及分区键设置是否合理。

3. 判断异常表的 Type,快速清理存量日志

3.1. 主要 Type 为 MERGE_PARTS

可以直接清理。系统会自动生成。

SYSTEM SKIP LOG db.table where type = 'MERGE_PARTS';

该命令暂时跳过了 Merge 命令,让后续日志继续执行。但是,由于分区键设置不合理,合并任务不进行等问题导致的 MERGE_PARTS 阻塞仍会再次发生。如果问题再次发生,建议根据”最大文件数占比”章节的“优化建议”再进行一些优化。

3.2. 主要 Type 为 GET_PART

则表示有大量 Part 同步任务受阻。需要分析如下:

2.2.1. (针对私有化部署)本节点磁盘是不是有损坏等硬件问题;如果有,直接替换这个节点;

2.2.2. 检查本节点上表是否是 leader?

在本节点上执行:

SELECT
    is_leader,
    absolute_delay
FROM system.ha_replicas
WHERE table = 'xxx_local'

如果 is_leader= 1 则是 leader,否则则不是 leader。

2.2.2.1. 如果本节点是 leader:

促进本节点数据拉全:

SYSTEM EXECUTE LOG db.table where type ='GET_PART';

2.2.2.2. 如果本节点不是 leader:

检查本节点的同 Shard 的另一个节点(以下简称备节点) 数据是否完整,在备节点上执行:

SELECT
    is_leader,
    absolute_delay
FROM system.ha_replicas
WHERE table = 'xxx_local'

情况1:如果输出是 is_leader: 1 , absolute_delay: 0

表示备节点数据全,则问题原因是产生 log 太频繁,本节点拉取跟不上。可以将本节点 log 清理掉从最新的状态再拉取。

在本节点上执行(注意,一定是在异常节点上,不是在数据完整的备节点上):

SYSTEM SKIP LOG db.table_local where 1;
SYSTEM MARK lost db.table;
DETACH table db.table;
ATTACH table db.table;

情况2:如果输出is_leader:1 ,absolute_delay:<>0

表示备节点数据更多,但是也不全。

那先促进备节点获得所有数据,在备节点上执行:

SYSTEM EXECUTE LOG db.table where type ='GET_PART';

等备节点数据同步完,再处理主节点:

SYSTEM SKIP LOG db.table_local where 1;
SYSTEM MARK lost db.table_local;
DETACH table db.table_local;
ATTACH table db.table_local;

2.3. 如果同时含有 GET_PARTDROP_RANGE

这种一般是因为过多的过期的小 Part 积压,正在等待被缓慢删除。

select name,min_time,max_time,rows from system.parts where table='xxx_local';

如果上面列出的 part 日期都在 TTL 之外,那就符合本条件。
原因是导入了太多 TTL 之外的历史数据或异常值,来不及 Drop。

  • 如果是 Insert Into 或批式导入方式,则需要上游尽可能清洗数据,不导入超过 TTL 的数据。

  • 如果是 Kafka 方式导入,则可以通过在消费时候设置过滤解决,例如:

ALTER TABLE db.CONSUMER_table_local ADD CONSTRAINT callTimes_constraint CHECK toDate(generate_time) <  today()  + 10 and  toDate(generate_time)  >  today()  - 10
--CONSUMER_table_local 是导入任务创建的 HaKafka 表,例如 ttl 为 10 天
--同时增加 toDate(generate_time) < today() + 10 则为了清洗异常时间值

3. 以上都无法解决

联系表的所有者,确认可以丢数据的前提下,执行以下操作:

SYSTEM SKIP LOG db.table where type ='GET_PART';

查询并发数

指标含义: 1 小时内最高时刻的查询并发数。由于 ByteHouse 并非一个高并发数据库,对并发的承载能力通常情况下在200左右。数字越大,集群健康状况越差。

评分阈值:

健康及格不及格危险
(0,20](20,100](100,200]>200

优化建议:

  • 本指标和查询成功率 / P95 查询延时 配套查看,如查询成功率和 P95 查询延时数据相对较健康,可以暂时忽略这个指标。但建议仍暂缓下游用户的接入,限制这个指标不要继续提升。
  • 如果查询成功率和 P95 数据之一也存在不健康现象。则表明集群负荷已较高,需要减少用户使用,建议梳理接入业务,将大查询的业务和高 QPS 的业务分开,高 QPS 的业务独立创建集群承载,并用max_execution_time等限制参数,控制高并发集群禁止出现大查询。

P95 查询延时

指标含义: 集群所有查询时延的 P95 分位(单位:秒),可基本反应集群查询的返回速度。数字越大,集群健康情况越差。

评分阈值:

健康及格不及格危险
(0,1](1,5](5,10]>10

优化建议:

  • 该指标不健康表明集群的查询速度很慢,慢于一般用户对 ClickHouse 的预期。首先收集各下游业务反馈,如果本身业务查询的数据量确实很大,并且可以接受目前的查询速度,则可以暂时忽略问题,后续再持续追踪。

  • 如果下游业务反馈查询不稳定,且越来越变慢。则通过“数据管理与查询->查询管理->查询历史”功能,找到这个集群对应的大查询,判断大查询是否可以被优化。判断的条件包括但不限于:

    • 使用了 Select *
    • 未合理使用重要建表字段,如
      • 未使用分区键
      • 分区建选择不当:导致每个分区 size 不同,导致查询剧烈波动。
      • 未使用排序键
    • 使用了耗时的算子。如count distinctuniqExactquantileExactcase when等。对于 CPU 的开销很大,都可能导致查询耗时久,并且某些算子的查询效率无法通过扩容集群提升。如果不需要保证结果完全精确,可以将count distinctuniqExactquantileExact 等函数替换为相应的模糊计算函数,可以牺牲 1% - 2% 的精度以显著提升查询效率:
      • count distince / uniqExact 替换为 uniq

      • quantileExact 替换为 quantile

  • 若所有大查询均无法再被优化了,则考虑让大查询的用户的数据迁移到单独集群,并在本集群设置 max_execution_time等限制参数。

查询成功率

指标含义: 集群所有查询的成功率,反映是否有大面积超时和 SQL 语法错误,越低表示健康情况越差。

评分阈值:

健康及格不及格危险
(99,100](95,99](90,95]<95

优化建议:

  • 这类问题通常是因为集群负载高而导致大量超时,或因为大量发送的查询不符合语法;通过数据管理与查询->查询管理->查询历史功能,可以找到这个集群对应的失败查询。判断主要的失败原因:
    • 超时:多为集群负载高原因,参考 P95 查询延时 的处理方法。
    • Too Many Parts:为导入不合理所致。可参考 最大文件数占比 的处理方法。
    • 其他语法错误:主要看是否有特定用户持续在发送不合语法的查询,和该用户进行沟通调整。