ClickHouse从入门到精通(四)

ClickHouse从入门到精通(四)

ClickHouse 高级篇

数据一致性【重点】

  • 查询 CK 手册发现,即便对数据一致性支持最好的 Mergetree,也只是保证最终一致性

在这里插入图片描述

  • 我们在使用 ReplacingMergeTree、SummingMergeTree 这类表引擎的时候,会出现短暂数据不一致的情况。
  • 在某些对一致性非常敏感的场景,通常有以下几种解决方案。
0. 准备测试数据
-- 创建表
create table t_v1(
    user_id UInt64,
    score String,
    deleted UInt8 DEFAULT 0,
    create_time DateTime DEFAULT toDateTime(0)
) engine = ReplacingMergeTree(create_time)
order by user_id;
-- user_id: 数据去重更新的标识
-- create_time: 版本号字段,每组数据中 create_time最大的一行表示最新的数据
-- deleted: 自定义的一个标志位,0 未删除,1 删除

-- 写入 1000万 测试数据
insert into table t_v1(user_id, score)
with (select ['A', 'B', 'C', 'D', 'E', 'F', 'G']) as dict
select number as user_id, dict[number % 7 + 1] from numbers(10000000);

-- 修改前 50 万 行数据,修改内容包括 name 字段和 create_time 版本号字段
insert into table t_v1(user_id, score, create_time)
with (select ['AA', 'BB', 'CC', 'DD', 'EE', 'FF', 'GG']) as dict
select number as user_id, dict[number % 7 + 1], now() as create_time from numbers(500000);

-- 统计总数
select count() from t_v1;
┌──count()─┐
│ 10500000 │
└──────────┘
1. 手动 OPTIMIZE
  • 在写入数据后,立刻执行 OPTIMIZE 强制触发新写入分区的合并动作。【不推荐】
  • 语法:https://clickhouse.com/docs/en/sql-reference/statements/optimize
OPTIMIZE TABLE [db.]name [ON CLUSTER cluster] [PARTITION partition | PARTITION ID 'partition_id'] [FINAL] [DEDUPLICATE [BY expression]]

optimize table t_v1 final;
-- 再次查询总数
select count() from t_v1;

┌──count()─┐
│ 10000000 │
└──────────┘
2. 通过 group by 去重
  • 执行去重查询
select user_id, 
argMax(score, create_time) as score, 
argMax(deleted, create_time) as deleted, 
max(create_time) as ctime from t_v1
group by user_id
having deleted = 0;
-- argMax(field1, field2): 按照 field2 的最大值取 field 的值
  • 当我们更新数据时,会写入一行新的数据,例如上面语句中,通过查询最大的create_time 得到修改后的 score 字段值。
-- 创建视图
create view v_t_v1 as 
select user_id, 
argMax(score, create_time) as score, 
argMax(deleted, create_time) as deleted, 
max(create_time) as ctime from t_v1
group by user_id
having deleted = 0;
  • 插入重复数据,再次查询
-- 再次插入一条数据
insert into table t_v1(user_id, score, create_time) values(0, 'AAAA', now());

-- 再次查询
select * from v_t_v1 where user_id = 0;
┌─user_id─┬─score─┬─deleted─┬───────────────ctime─┐
│       0 │ AAAA  │       02022-04-26 22:53:22 │
└─────────┴───────┴─────────┴─────────────────────┘

-- 再次插入一条标记为删除的数据
insert into table t_v1(user_id, score, deleted, create_time) values(0, 'AAAA', 1, now());

-- 再次查询,刚才那条数据看不到了
select * from v_t_v1 where user_id = 0;
0 rows in set.
  • 这行数据并没有被真正的删除,而是被过滤掉了。在一些合适的场景下,可以结合表级别的 TTL 最终将物理数据删除。

在这里插入图片描述

3. 通过 FINAL 查询
  • 在查询语句后增加 FINAL 修饰符,这样在查询的过程中将会执行 Merge 的特殊逻辑(例如数据去重,预聚合等)。
  • 但是这种方法在早期版本基本没有人使用,因为在增加 FINAL 之后,我们的查询将会变成一个单线程的执行过程,查询速度非常慢。
  • v20.5.2.7-stable版本中,FINAL 查询支持多线程执行,并可以通过max_final_threads参数控制单个查询的线程数。但是目前读取 part 部分的动作依然是串行的。
  • FINAL 查询最终的性能和很多因素相关,列字段的大小、分区的数量等等都会影响到最终的查询时间,所以还要结合实际场景取舍。
  • 参考连接:https://github.com/ClickHouse/ClickHouse/pull/10463
-- ① 普通语句查询
select * from datasets.visits_v1 where StartDate = '2014-03-17' limit 100 settings max_threads = 2;

--  查看执行计划
explain pipeline select * from datasets.visits_v1 where StartDate = '2014-03-17' limit 100 settings max_threads = 2;

┌─explain─────────────────────────┐
│ (Expression)                    │
│ ExpressionTransform × 2         │
│   (SettingQuotaAndLimits)       │
│     (Limit)                     │
│     Limit 22                 │
│       (ReadFromMergeTree)       │
│       MergeTreeThread × 2 01 │
└─────────────────────────────────┘    -- 明显将由 2 个线程并行读取 part 查询。

--  ② FINAL 查询
select * from datasets.visits_v1 final where StartDate = '2014-03-17' limit 100 settings max_threads = 2;

在这里插入图片描述

  • 可以明细看到查询速度没有普通的查询快,但是相比之前老版本已经有了一些提升,查看 FINAL 查询的执行计划
explain pipeline select * from datasets.visits_v1 final where StartDate = '2014-03-17' limit 100 settings max_threads = 2;

┌─explain──────────────────────────────────┐
│ (Expression)                             │
│ ExpressionTransform × 2                  │
│   (Limit)                                │
│   Limit 22                            │
│     (Filter)                             │
│     FilterTransform × 2                  │
│       (SettingQuotaAndLimits)            │
│         (ReadFromMergeTree)              │
│         ExpressionTransform × 2          │
│           CollapsingSortedTransform × 2  │
│             Copy 12                   │
│               AddingSelector             │
│                 ExpressionTransform      │
│                   MergeTreeInOrder 01 │
└──────────────────────────────────────────┘
  • 从 CollapsingSortedTransform 这一步开始已经是多线程执行,但是读取 part 部分的动作还是串行。

数据一致性总结:ReplacingMergeTree 不能保证查询时没重复,只能保证最终一致性

解决方案:
1、手动执行 optimize:生产环境不推荐
2、通过 sql 实现去重:group by ==>> 高级玩法:加标记字段
3、使用final:
20.5 之前版本,final是单线程;
20.5 之后版本,final可以是多线程,但读取是串行
4、重复一点无所谓:100万日活,统计出来100万零1千

物化视图

  • ClickHouse 的物化视图是一种查询结果的持久化,它确实是给我们带来了查询效率的提升。用户查起来跟表没有区别,它就是一张表,它也像是一张时刻在预计算的表,创建的过程它是用了一个特殊引擎,加上后来 as select,就是 create 一个 table as select 的写法。
  • “查询结果集”的范围很宽泛,可以是基础表中部分数据的一份简单拷贝,也可以是多表 join 之后产生的结果或其子集,或者原始数据的聚合指标等等。所以,物化视图不会随着基础表的变化而变化,所以它也称为快照(snapshot) 。
  • 参考文档:https://clickhouse.com/docs/en/sql-reference/statements/create/view#materialized
1. 概述
物化视图与普通视图的区别
  • 普通视图不保存数据,保存的仅仅是查询语句,查询的时候还是从原表读取数据,可以将普通视图理解为是个子查询。物化视图则是把查询的结果根据相应的引擎存入到了磁盘或内存中,对数据重新进行了组织,你可以理解物化视图是完全的一张新表。
优缺点
  • 优点:查询速度,要是把物化视图这些规则全部写好,它比原数据查询快了很多,总的行数少了,因为都预计算好了。
  • 缺点:它的本质是一个流式数据的使用场景,是累加式的技术,所以要用历史数据做去重、聚合这样的分析,在物化视图里面是不太好用的。在某些场景的使用也是有限的。而且如果一张表加了好多物化视图,在写这张表的时候,就会消耗很多机器的资源,比如数据带宽占满、存储一下子增加了很多。
基本语法
  • 也是 create 语法,会创建一个隐藏的目标表来保存视图数据。也可以 TO 表名,保存到一张显式的表。没有加 TO 表名,表名默认就是 .inner.物化视图名
CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER] [TO[db.]name] [ENGINE = engine] [POPULATE] AS SELECT ...
  • 一个物化视图的实现是这样的:当向SELECT中指定的表插入数据时,插入数据的一部分被这个SELECT 查询转换,结果插入到视图中。
创建物化视图的限制
  • 创建不带TO [db].[table]的物化视图时,必须指定物化视图的 engine 用于数据存储。
  • 使用TO [db].[table] 创建物化视图时,不得使用POPULATE;(因为会全量跑历史数据)。
  • ClickHouse 中的物化视图更像是插入触发器。 如果视图查询中有一些聚合,则它仅应用于一批新插入的数据。 对源表现有数据的任何更改(如更新、删除、删除分区等)都不会更改物化视图。
  • 查询语句(select) 可以包含下面的子句:distinct、group by、order by、limit、…,相应的转换是在每个插入数据块上独立执行的
    • 例如,如果设置了GROUP BY,则在插入期间聚合数据,但仅在插入数据的单个数据包内。
    • 数据不会被进一步聚合。
    • 例外情况是使用独立执行数据聚合的ENGINE,例如SummingMergeTree
  • 物化视图的 alter 操作有些限制,操作起来不大方便:如果物化视图使用构造TO [db.]name,你可以DETACH 视图,为目标表运行ALTER,然后ATTACH先前分离的(DETACH)视图。
  • 注意,物化视图受 optimize_on_insert 设置的影响: 在插入视图之前合并数据。
  • 物化视图是一种特殊的数据表,可以用 show tables 查看。
物化视图的数据更新
  • 物化视图创建好之后,若源表被写入新数据则物化视图也会同步更新。
  • POPULATE 关键字决定了物化视图的更新策略:
    • 若有 POPULATE,则在创建视图的过程会将源表已经存在的数据一并导入,类似于 create table ... as
    • 若无 POPULATE,则物化视图在创建之后没有数据,只会在创建同步之后写入源表的数据;
    • ClickHouse 官方并不推荐使用 POPULATE,因为在创建物化视图的过程中同时写入的数据不能被插入物化视图。
  • 物化视图不支持同步删除,若源表的数据不存在(删除了)则物化视图的数据仍然保留;
  • 删除视图,使用DROP VIEWDROP TABLE也适用于视图。
2. 案例实操
  • 对于一些确定的数据模型,可将统计指标通过物化视图的方式进行构建,这样可避免查询时重复计算的过程,物化视图会在有新数据插入时进行更新。
准备测试数据
-- 建表语句
create table t_hits(
    EventDate Date,
    CounterID UInt32,
    UserID UInt64,
    URL String,
    Income UInt8
) engine = MergeTree()
partition by toYYYYMM(EventDate)
order by (CounterID, EventDate, intHash32(UserID))
sample by intHash32(UserID)
settings index_granularity = 8192;

-- 导入一些数据
insert into t_hits select EventDate, CounterID, UserID, URL, Income from datasets.hits_v1 limit 10000;
创建物化视图
-- 创建物化视图语句
create materialized view mv_hits engine = SummingMergeTree
partition by toYYYYMM(EventDate) order by (EventDate, intHash32(UserID))
as select UserID, EventDate, count(URL) as ClickCount, sum(Income) as IncomeSum from t_hits 
where EventDate >= '2014-03-20' -- 设置更新点,该时间点之前的数据可以另外通过 insert into select …… 的方式进行插入
group by UserID, EventDate;

在这里插入图片描述

  • 或者可以用下列语法,表 A 可以是一张 MergeTree 表
CREATE MATERIALIZED VIEW 物化视图名 TO 表 A
AS SELECT FROM 表 B;
  • 不建议添加 populate 关键字进行全量更新
    在这里插入图片描述
导入增量数据
  • 原表导入增量数据,会触发物化视图表的数据更新
insert into t_hits 
select EventDate, CounterID, UserID, URL, Income from datasets.hits_v1 
where EventDate >= '2014-03-23' limit 10;

-- 查询物化视图
select * from mv_hits;

在这里插入图片描述

导入历史数据
  • 对于存量的历史数据,可以直接向物化视图表导入增量数据
insert into mv_hits
select UserID, EventDate, count(URL) as ClickCount, sum(Income) as IncomeSum from t_hits 
where EventDate = '2014-03-20'
group by UserID, EventDate;

-- 查询物化视图
select * from mv_hits;

在这里插入图片描述

MaterializedMySQL 引擎

1. 概述
  • MySQL 的用户群体很大,为了能够增强数据的实时性,很多解决方案会利用 binlog 将数据写入到 ClickHouse。为了能够监听 binlog 事件,我们需要用到类似 canal 这样的第三方中间件,这无疑增加了系统的复杂度。
  • ClickHouse 20.8.2.3 版本新增加了 MaterializedMySQL 的 database 引擎,该 database 能映射到 MySQL 中的某个 database,并自动在 ClickHouse 中创建对应的 ReplacingMergeTree。ClickHouse 服务做为 MySQL 副本,读取 Binlog 并执行 DDL 和 DML 请求,实现了基于 MySQL Binlog 机制的业务数据库实时同步功能。
特点
  • MaterializeMySQL 同时支持全量增量同步,在 database 创建之初会全量同步 MySQL 中的表和数据,之后则会通过 binlog 进行增量同步。
  • MaterializedMySQL database 为其所创建的每张 ReplacingMergeTree 自动增加了 _sign_version 字段。
    • 其中,_version 用作 ReplacingMergeTree 的 ver 版本参数,每当监听到 insert、update 和 delete 事件时,在 databse 内全局自增。
    • 而 _sign 则用于标记是否被删除,取值 1 或者 -1。
  • 目前 MaterializedMySQL 支持如下几种 binlog 事件:
    • MYSQL_WRITE_ROWS_EVENT:_sign = 1,_version ++
    • MYSQL_DELETE_ROWS_EVENT:_sign = -1,_version ++
    • MYSQL_UPDATE_ROWS_EVENT:新数据 _sign = 1
    • MYSQL_QUERY_EVENT:支持 CREATE TABLE 、DROP TABLE 、RENAME TABLE 等。
使用细则
  • DDL查询
    • MySQL DDL 查询被转换成相应的 ClickHouse DDL 查询(ALTER、CREATE、DROP、RENAME)。
  • 数据复制:MaterializeMySQL 不支持直接插入、删除和更新查询,而是将 DDL 语句进行相应转换:
    • MySQL INSERT 查询被转换为 INSERT with _sign = 1;
    • MySQL DELETE 查询被转换为 INSERT with _sign = -1;
    • MySQL UPDATE 查询被转换成 INSERT with _sign = 1 和 INSERT with _sign = -1。
  • SELECT查询
    • 如果在 SELECT 查询中没有指定_version,则使用 FINAL 修饰符,返回 _version 的最大值对应的数据,即最新版本的数据。
    • 如果在 SELECT 查询中没有指定 _sign,则默认使用 WHERE _sign=1,即返回未删除状态(_sign=1)的数据。
  • 索引转换
    • ClickHouse 数据库表会自动将 MySQL 主键和索引子句转换为 ORDER BY 元组。
    • ClickHouse 只有一个物理顺序,由 ORDER BY 子句决定。如果需要创建新的物理顺序,请使用物化视图。
2. 案例实操
MySQL 开启 binlog 和 GTID 模式
  • 确保 MySQL 开启了 binlog 功能,且格式为 ROW
server-id=1
log-bin=mysql-bin
binlog_format=ROW
  • 开启 GTID 模式:如果 clickhouse 使用的是 20.8 prestable 之后发布的版本,那么 MySQL 还需要配置开启 GTID 模式, 这种方式在 mysql 主从模式下可以确保数据同步的一致性(主从切换时)。
gtid-mode=on
enforce-gtid-consistency=1	# 设置为主从强一致性
log-slave-updates=1			# 记录日志
  • GTID 是 MySQL 复制增强版,从 MySQL 5.6 版本开始支持,目前已经是 MySQL 主流复制模式。它为每个 event 分配一个全局唯一 ID 和序号,我们可以不用关心 MySQL 集群主从拓扑结构,直接告诉 MySQL 这个 GTID 即可。
  • 重启 MySQL
sudo systemctl restart mysqld
准备MySQL表和数据
  • 在 MySQL 中创建表并写入数据
create database db_ck_test;

create table `db_ck_test`.`t_dept` (
	`id` int(11) not null auto_increment,
    `code` int not null,
    `name` text default null,
    `update_time` datetime default null,
    primary key (`id`),
    unique key (`code`)
) engine = InnoDB;

insert into `db_ck_test`.`t_dept` (`code`, `name`, `update_time`) values (1000, 'Realinsight', now()), (1001, 'Realindex', now()), (1002, 'EDT', now());
  • 再创建一张表
create table `db_ck_test`.`t_user` (
	`id` int(11) not null auto_increment,
    `code` int,
    primary key (`id`)
) engine = InnoDB;

insert into `db_ck_test`.`t_user` (code) values(1);
开启 ClickHouse 物化引擎
set allow_experimental_database_materialized_mysql = 1;
创建复制管道
  • ClickHouse 中创建 MaterializeMySQL 数据库
create database test_binlog engine = MaterializedMySQL('192.168.254.132:3306', 'db_ck_test', 'root', '123456');
-- 其中 4 个参数分别是 MySQL 地址、databse、username 和 password
  • 查看 ClickHouse 中的数据:
show databases;
use test_binlog;
show tables;
select * from t_dept;
select * from t_user;

在这里插入图片描述

修改、删除数据
  • 在 MySQL 中修改数据,并在 ClickHouse 日志中查看 binlog 监听时间,并查询 ClickHouse中数据
-- 修改 MySQL 中的数据
update t_dept set name = CONCAT(name,'-v1') where id = 1;
-- 查询ClickHouse
select * from t_dept;

-- 删除 MySQL 中的数据
delete from t_dept where id = 2;
-- 查询ClickHouse
select * from t_dept;
  • 在刚才的查询中增加 _sign 和 _version 虚拟字段
select *, _sign, _version from t_dept order by _sign desc, _version desc;

在这里插入图片描述

  • 在查询时,对于已经被删除的数据,_sign=-1,ClickHouse 会自动重写 SQL,将 _sign = -1 的数据过滤掉。
  • 对于修改的数据,则自动重写 SQL,为其增加 FINAL 修饰符。
select * from t_dept;
-- 等价于
select * from t_dept final where _sign = 1;
删除表
  • 在 MySQL执行删除表,此时在 clickhouse 处会同步删除对应表,如果查询会报错
-- 在 MySQL 删除表
drop table t_user;
-- 在 ClickHouse 查询
show tables;
select * from t_user;

-- mysql 新建表,clickhouse 可以查询到
create table `db_ck_test`.`t_user` (
	`id` int(11) not null auto_increment,
    `code` int,
    primary key (`id`)
) engine = InnoDB;
insert into `db_ck_test`.`t_user` (code) values(1);
-- 在 ClickHouse 查询
show tables;
select * from t_user;

常见问题排查

1. 分布式 DDL 某数据节点的副本不执行
  • 问题:使用分布式 ddl 执行命令 create table on cluster xxxx 某个节点上没有创建表,但是 client 返回正常,查看日志有如下报错。

    <Error> xxx.xxx: Retrying createReplica(), because some other replicas were created at the same time

  • 解决办法:重启该不执行的节点

2. 数据副本表和数据不一致
  • 问题:由于某个数据节点副本异常,导致两数据副本表不一致,某个数据副本缺少表,需要将两个数据副本调整一致。
  • 解决办法:在缺少表的数据副本节点上创建缺少的表,创建为本地表,表结构可以在其他数据副本通过 show crete table xxxx 获取。
    • 表结构创建后,clickhouse 会自动从其他副本同步该表数据,验证数据量是否一致即可。
3. 副本节点全量恢复
  • 问题:某个数据副本异常无法启动,需要重新搭建副本。
  • 解决办法:清空异常副本节点的 metadata 和 data 目录。从另一个正常副本将 metadata 目录拷贝过来(这一步之后可以启动数据库,但是只有表结构没有数据)。
    • 执行 sudo -u clickhouse touch /data/clickhouse/flags/force_restore_data
    • 启动数据库
4. 数据副本启动缺少 zk 表
  • 问题:某个数据副本表在 zk 上丢失数据,或者不存在,但是 metadata 元数据里存在,导致启动异常,报错:

    Can’t get data for node /clickhouse/tables/01-02/xxxxx/xxxxxxx/replicas/xxx/metadata: node doesn’t exist (No node): Cannot attach table xxxxxxx

  • 解决办法:metadata 中移除该表的结构文件,如果多个表报错都移除

    • mv metadata/xxxxxx/xxxxxxxx.sql /tmp/
    • 启动数据库
    • 手工创建缺少的表,表结构从其他节点 show create table 获取。
    • 创建后会自动同步数据,验证数据是否一致。
5. ZK table replicas数据未删除,导致重建表报错
  • 问题:重建表过程中,先使用 drop table xxx on cluster xxx,各节点在 clickhouse 上table 已物理删除,但是 zk 里面针对某个 clickhouse 节点的 table meta 信息未被删除(低概率事件),因 zk 里仍存在该表的 meta 信息,导致再次创建该表 create table xxx on cluster,该节点无法创建表(其他节点创建表成功),报错:

    Replica /clickhouse/tables/01-03/xxxxxx/xxx/replicas/xxx already exists.

  • 解决办法:从其他数据副本 cp 该 table 的 metadata sql 过来。重启节点

6. ClickHouse 节点意外关闭
  • 问题:模拟其中一个节点意外宕机,在大量 insert 数据的情况下,关闭某个节点。

  • 现象:数据写入不受影响、数据查询不受影响、建表 DDL 执行到异常节点会卡住,报错:

    Code: 159. DB::Exception: Received from localhost:9000. DB::Exception: Watching task /clickhouse/task_queue/ddl/query-0000565925 is executing longer than distributed_ddl_task_timeout (=180) seconds. There are 1 unfinished hosts (0 of them are currently active), they are going to execute the query in background.

  • 解决办法:启动异常节点,期间其他副本写入数据会自动同步过来,其他副本的建表 DDL 也会同步。

7. 其它问题参考
  • https://help.aliyun.com/document_detail/162815.html?spm=a2c4g.11186623.6.652.312e79bd17U8IO

ClickHouse 监控及备份

  • ClickHouse 运行时会将一些个自身的运行状态记录到众多系统表中( system.*)。所以我们对于 CK 自身的一些运行指标的监控数据,也主要来自这些系统表。
  • 但是直接查询这些系统表会有一些不足之处:
    • 这种方式太过底层,不够直观,我们还需要在此之上实现可视化展示;
    • 系统表只记录了CH自己的运行指标,有些时候我们需要外部系统的指标进行关联分析,例如 ZooKeeper、服务器 CPU、IO 等等。
  • 现在 Prometheus + Grafana 的组合比较流行,安装简单易上手,可以集成很多框架,包括服务器的负载, 其中 Prometheus 负责收集各类系统的运行指标; Grafana 负责可视化的部分。
  • ClickHouse 从 v20.1.2.4 开始,内置了对接 Prometheus 的功能,配置的方式也很简单,可以将其作为 Prometheus 的 Endpoint 服务,从而自动的将 metrics、events 和 asynchronous_metrics 三张系统的表的数据发送给 Prometheus。

Prometheus & Grafana 的安装

  • Prometheus 下载地址:https://prometheus.io/download/
  • Grafana 下载地址:https://grafana.com/grafana/download
1. 安装 Prometheus
  • Prometheus 基于 Golang 编写,编译后的软件包,不依赖于任何的第三方依赖。只需要下载对应平台的二进制包,解压并且添加基本的配置即可正常启动 Prometheus Server。
# 下载安装包
wget https://github.com/prometheus/prometheus/releases/download/v2.35.0/prometheus-2.35.0.linux-amd64.tar.gz
# 解压缩
tar -zxvf prometheus-2.35.0.linux-amd64.tar.gz -C /bigdata/install/
cd /bigdata/install/prometheus-2.35.0.linux-amd64
  • 修改配置文件:vim prometheus.yml,在 scrape_configs 配置项下添加配置
scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["node01:9090"]
  # 添加 ClickHouse 监控配置
  - job_name: "clickhouse-1"
    static_configs:
      - targets: ["node01:9363"]

在这里插入图片描述

  • 配置说明:
    • global 配置块:控制 Prometheus 服务器的全局配置
      • scrape_interval:拉取数据的时间间隔,默认为 1 分钟。
      • evaluation_interval:规则验证(生成 alert)的时间间隔,默认为 1 分钟。
    • rule_files 配置块:规则配置文件
    • scrape_configs 配置块:配置采集目标相关, prometheus 监视的目标。Prometheus 自身的运行信息可以通过 HTTP 访问,所以 Prometheus 可以监控自己的运行数据。
      • job_name:监控作业的名称
      • static_configs:表示静态目标配置,就是固定从某个 target 拉取数据
      • targets: 指定监控的目标,其实就是从哪儿拉取数据。Prometheus 会从 http://node01:9090/metrics 上拉取数据。
  • Prometheus 是可以在运行时自动加载配置的,启动时需要添加:–web.enable-lifecycle
  • 启动 Prometheus Server
# pwd
/bigdata/install/prometheus-2.35.0.linux-amd64

nohup ./prometheus --config.file=prometheus.yml > ./prometheus.log 2>&1 &
  • 浏览器访问:http://node01:9090

在这里插入图片描述

  • 点击 Status,选择 Targets:clickhouse 还没有配置监控,所以状态 State 还是 DOWN 的,后面会进行配置。

在这里插入图片描述

2. 安装 Grafana
# 下载安装包
wget https://dl.grafana.com/oss/release/grafana-8.5.2.linux-amd64.tar.gz
# 解压缩
tar -zxvf grafana-8.5.2.linux-amd64.tar.gz -C /bigdata/install/
cd /bigdata/install/grafana-8.5.2
# 启动
nohup ./bin/grafana-server web > ./grafana.log 2>&1 &
  • 浏览器访问:http://node01:3000,默认用户名和密码:admin

在这里插入图片描述

ClickHouse 配置

1. 修改配置文件
  • vim /etc/clickhouse-server/config.xml,开启 prometheus 监控,其它CK节点也需要开启
<prometheus>
    <endpoint>/metrics</endpoint>
    <port>9363</port>

    <metrics>true</metrics>
    <events>true</events>
    <asynchronous_metrics>true</asynchronous_metrics>
    <status_info>true</status_info>
</prometheus>
2. 重启 ClickHouse,并访问
sudo clickhouse restart
  • 浏览器访问:http://node01:9363/metrics,能看到如下信息,说明 ClickHouse 开启 Metrics 服务成功。

在这里插入图片描述

  • 此时访问 prometheus,状态就是 UP 了

在这里插入图片描述

Grafana 集成 Prometheus

1. 添加数据源 Prometheus
  • 点击配置,选择 Data sources

在这里插入图片描述

  • 点击添加按钮,并找到 Prometheus,并选择

在这里插入图片描述

  • 配置 Prometheus Server 地址,并点击下方的 Save&Test

在这里插入图片描述

  • 出现绿色的提示框,表示与 Prometheus 正常连通

在这里插入图片描述

2. 添加监控
  • 点击左侧”+“号,选择 Dashboard,选择Add a new panel

在这里插入图片描述

  • 创建自定义的监控页面

在这里插入图片描述

  • 手动一个个添加 Dashboard 比较繁琐,Grafana 社区鼓励用户分享 Dashboard,通过 https://grafana.com/dashboards 网站,可以找到大量可直接使用的 Dashboard 模板。

在这里插入图片描述

  • 搜索 ClickHouse 选择自己想要的模板,这里笔者选用的是这个:https://grafana.com/grafana/dashboards/14432

在这里插入图片描述

  • Grafana 中所有的 Dashboard 通过 JSON 进行共享,下载并且导入这些 JSON 文件,就可以直接使用这些已经定义好的 Dashboard。
  • 点击左侧”+“号,选择 import

在这里插入图片描述

  • 导入配置模板

在这里插入图片描述

  • 选择监控来源,并 Import

在这里插入图片描述

  • 查看监控界面

在这里插入图片描述

备份及恢复

  • 官方文档:https://clickhouse.com/docs/en/operations/backup/
1. 手动实现备份及恢复
  • ClickHouse 允许使用 ALTER TABLE ... FREEZE PARTITION ... 查询以创建表分区的本地副本。这是利用硬链接(hardlink)到 /var/lib/clickhouse/shadow/ 文件夹中实现的,所以它通常不会因为旧数据而占用额外的磁盘空间。 创建的文件副本不由 ClickHouse 服务器处理,所以不需要任何额外的外部系统就有一个简单的备份。防止硬件问题,最好将它们远程复制到另一个位置,然后删除本地副本。
  • 创建备份路径:
# 创建用于存放备份数据的目录 shadow,如果目录存在,先清空目录下的数据
sudo mkdir -p /var/lib/clickhouse/shadow
chown -R clickhouse:clickhouse shadow/
  • 执行备份命令:
echo -n 'alter table test.t_order_mt freeze' | clickhouse-client --password
Password for user (default): 输入密码

在这里插入图片描述

  • 将备份数据保存到其它路径:
# 创建备份存储路径
sudo mkdir -p /var/lib/clickhouse/backup

# 拷贝数据到备份路径
sudo cp -r /var/lib/clickhouse/shadow/ /var/lib/clickhouse/backup/test.t_order_mt.bak

# 为下次备份准备,删除 shadow 下的数据
sudo rm -rf /var/lib/clickhouse/shadow/*
  • 恢复数据:
# 删除备份过的表
echo 'drop table test.t_order_mt' | clickhouse-client --password
Password for user (default): 输入密码

# 重新创建表
cat test.t_order_mt.sql | clickhouse-client --password

# 将备份复制到 detach 目录
sudo cp -rl /var/lib/clickhouse/backup/test.t_order_mt.bak/1/store/c1d/c1d638d1-0fe4-4a9e-b00c-fc7a0b0a1f6a/* /var/lib/clickhouse/data/test/t_order_mt/detached/
chown -R clickhouse:clickhouse /var/lib/clickhouse/data/test/t_order_mt/detached/
  • ClickHouse 使用文件系统硬链接来实现即时备份,而不会导致 ClickHouse 服务停机(或锁定)。这些硬链接可以进一步用于有效的备份存储。在支持硬链接的文件系统(例如本地文件系统或 NFS)上,将 cp 与-l 标志一起使用(或将 rsync 与–hard-links 和–numeric-ids 标志一起使用)以避免复制数据。
    • 注意:仅拷贝分区目录,目录所属的用户要是 clickhouse。
  • 执行 attach:
echo 'alter table test.t_order_mt attach partition 20220415' | clickhouse-client --password
  • 查看数据:
echo 'select * from test.t_order_mt' | clickhouse-client --password

在这里插入图片描述

2. 使用 clickhouse-backup
  • 上面的过程,我们可以使用 Clickhouse 的备份工具 clickhouse-backup 帮我们自动化实现。
  • 下载安装:
# 下载最新版 rpm 包
wget https://github.com/AlexAkulov/clickhouse-backup/releases/download/v1.3.2/clickhouse-backup-1.3.2-1.x86_64.rpm
# 安装
sudo rpm -ivh clickhouse-backup-1.3.2-1.x86_64.rpm
  • 修改配置文件:修改下默认用户登录密码,其它的都不用改
cd /etc/clickhouse-backup/
cp config.yml.example config.yml

vim config.yml

在这里插入图片描述

  • 查看 clickhouse-backup 命令:
# 查看可用命令
clickhouse-backup help

NAME:
   clickhouse-backup - Tool for easy backup of ClickHouse with cloud support

USAGE:
   clickhouse-backup <command> [-t, --tables=<db>.<table>] <backup_name>

VERSION:
   1.3.2

DESCRIPTION:
   Run as 'root' or 'clickhouse' user

COMMANDS:
   tables          Print list of tables				# 显示要备份的表
   create          Create new backup				# 创建新的备份
   create_remote   Create and upload
   upload          Upload backup to remote storage
   list            Print list of backups			# 查看现有的本地备份
   download        Download backup from remote storage
   restore         Create schema and restore data from backup
   restore_remote  Download and restore
   delete          Delete specific backup
   default-config  Print default config
   print-config    Print current config
   clean           Remove data in 'shadow' folder from all `path` folders available from `system.disks`
   server          Run API server
   help, h         Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --config FILE, -c FILE  Config FILE name. (default: "/etc/clickhouse-backup/config.yml") [$CLICKHOUSE_BACKUP_CONFIG]
   --help, -h              show help
   --version, -v           print the version

在这里插入图片描述

  • 创建备份:
    • 备份存储在中 /var/lib/clickhouse/backup/BACKUPNAME。备份名称默认为时间戳,但是可以选择使用 –name 标志指定备份名称。
    • 备份包含两个目录:
      • 一个 metadata 目录,其中包含重新创建架构所需的 DDL SQL 语句
      • 以及一个 shadow 目录,其中包含作为 ALTER TABLE … FREEZE 操作结果的数据。
# 先将原来手动备份的数据删掉
rm -rf /var/lib/clickhouse/backup/*

# 执行创建备份
clickhouse-backup create

在这里插入图片描述

  • 从备份恢复数据:
    • –schema 参数:只还原表结构。
    • –data 参数:只还原数据。
    • –table 参数:备份(或还原)特定表。也可以使用一个正则表达式,例如,针对特定的数据库:–table=dbname.*。
# 删除备份过的表
echo 'drop table test.t_order_mt' | clickhouse-client --password
Password for user (default): 输入密码
# 从备份还原
clickhouse-backup restore 2022-05-06T22-55-20clickhouse-backup restore 2022-05-06T22-55-20 --table test.t_order_mt
  • 其它说明:
    • API 文档:https : //github.com/AlexAkulov/clickhouse-backup#api
    • 注意事项:切勿更改文件夹/var/lib/clickhouse/backup 的权限,可能会导致数据损坏。
    • 远程备份:
      • 较新版本才支持,需要设置 config 里的 s3 相关配置
      • 上传到远程存储:sudo clickhouse-backup upload xxxx
      • 从远程存储下载:sudo clickhouse-backup download xxxx
      • 保存周期:
        • backups_to_keep_local,本地保存周期,单位天
        • backups_to_keep_remote,远程存储保存周期,单位天
        • 0 均表示不删除
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

讲文明的喜羊羊拒绝pua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值