核心知识与集群介绍(基于v21.11版本)
目录
1. 介绍
ClickHouse是一款由俄罗斯 Yandex 公司开发的用于联机分析(OLAP)的列式数据库管理系统(DBMS)。
常见的 OLAP 引擎: Hive、Spark SQL、Presto、Kylin、Impala、Druid、Clickhouse、Greeplum等。
2. 优缺点
特性:
- 真正的列式数据库管理系统
- 数据压缩
- 数据存储在磁盘.数据存储在磁盘可以降低成本,clickhouse 即使在普通磁盘上,也可以快速的查询出结果。
- 多核心并行处理
- 多服务器分布式处理.分布式表,可以利用多个服务器,并行执行查询。
- 支持 SQL
- 向量引擎
- 索引
- 适合在线查询
- 支持近似计算
- 自适应 join
- 支持数据副本机制.可以设置数据存储的备份,提高可用性。
- 角色控制
缺点:
- 没有完整的事务支持
- 不能高频、低延迟的修改或删除数据
- 不适合单行点查询
3. 表引擎
clickhouse 有多种表引擎,适用于不同的场景。建表语句如下:
- CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
- (
- name1 [type1] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|ALIAS expr1] [compression_codec] [TTL expr1],
- name2 [type2] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|ALIAS expr2] [compression_codec] [TTL expr2],
- ...
- ) ENGINE = engine
3.1 Log
- 插入数据会锁表
- 不支持索引,也就是说范围查询效率不高
- 适用于临时数据,一次性写入的表,测试表
3.1.1 TinyLog
- 最简单的引擎
- 适合一次写入,只读的场景
- 数据量在 100w 以内
- 没有并发控制,同时读写会报错,并发写入,数据不可用
3.1.2 StripeLog
- 可以并发读,写入会阻塞读操作
3.1.3 Log
- 可以并发读,性能比 StripeLog 要好一些
- 因为使用 __marks.mrk 文件记录每个数据块的偏移,写入数据出现问题,表直接报废
3.2 Engine Families MergeTree
- 使用最多的表引擎
- 支持索引、分区
3.2.1 MergeTree
- CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
- (
- name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1], -- MATERIALIZED 从别的列物化出来这一列, 用于减少查询时候的计算量
- name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2], -- ALIAS 不实际存储这一列, 在查询的时候执行
- ...
- INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1, -- 二级索引
- INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2,
- ...
- PROJECTION projection_name_1 (SELECT <COLUMN LIST EXPR> [GROUP BY] [ORDER BY]), -- 实验性功能, part 级别的物化视图, 在查询的时候会自动使用
- PROJECTION projection_name_2 (SELECT <COLUMN LIST EXPR> [GROUP BY] [ORDER BY])
- ) ENGINE = MergeTree()
- ORDER BY expr -- 排序字段
- [PARTITION BY expr] -- 分区
- [PRIMARY KEY expr] -- 主键, 默认和 order by 一致, 一般情况下不设置, 跟 order by 保持一致
- [SAMPLE BY expr] -- 抽样, 必须是主键或者排序字段包含的字段, 必须是 UInt 类型字段
- [TTL expr -- 数据过期时间
- [DELETE|TO DISK 'xxx'|TO VOLUME 'xxx' [, ...] ]
- [WHERE conditions]
- [GROUP BY key_expr [SET v1 = aggr_func(v1) [, v2 = aggr_func(v2) ...]] ] ]
- [SETTINGS name=value, ...]
使用示例:
- -- 示例1
- CREATE TABLE test.label_number_local
- (
- `tag_code` String,
- `user_id` UInt64 COMMENT '用户 id',
- `value` Float64 COMMENT '标签值'
- )
- ENGINE = MergeTree
- PARTITION BY tag_code
- ORDER BY tag_code
-
- -- 示例2, TTL
- CREATE TABLE test.dw_domestic_hotel_monitor_crm_realtime
- (
- `dt` String COMMENT '时间分区',
- `type` String COMMENT '类型',
- `hour` String COMMENT '小时',
- `hotel_seq` String COMMENT 'hotel_seq',
- `device_id` String COMMENT '设备id',
- `platform` String COMMENT '客户端',
- ......
- )
- ENGINE = MergeTree()
- PARTITION BY (dt,
- type)
- ORDER BY (dt,
- hour,
- type,
- ......)
- -- 删除 dt+2day <= today(now()) and type!='order' 的数据, 即保留最近两天(包括当天)的数据
- TTL parseDateTimeBestEffort(dt) + toIntervalDay(2) WHERE type != 'order'
-
- -- 示例3, sample
- CREATE TABLE test.clicks
- (
- `CounterID` UInt64,
- `EventDate` DATE,
- `UserID` UInt64
- )
- ENGINE = MergeTree()
- ORDER BY (CounterID, intHash32(UserID))
- SAMPLE BY intHash32(UserID)
- -- 查询, 按 intHash32(UserID) 采样, 伪随机, 相同采样率每次查询结果一致
- select * from test.clicks sample 0.2
3.2.2 ReplacingMergeTree
会自动删除具有相同 order by 字段值的重复数据。但是他只会在后台合并分区文件的时候删除,所以不可靠。适用于清除重复数据节省空间,但不保证没有重复数据。
- CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
- (
- name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
- name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
- ...
- ) ENGINE = ReplacingMergeTree([ver]) -- 带有版本号的列, 支持的数据类型 UInt*, Date, DateTime, DateTime64
- [PARTITION BY expr]
- [ORDER BY expr]
- [PRIMARY KEY expr]
- [SAMPLE BY expr]
- [SETTINGS name=value, ...]
3.2.3 SummingMergeTree
会自动合并具有相同 order by 字段值的重复数据,把其他数值类型的列加在一起。
- CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
- (
- name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
- name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
- ...
- ) ENGINE = SummingMergeTree([columns]) -- 数值类型的列, 且不在 order by 字段中, 默认值是所有不在 order by 字段的数值类型列
- [PARTITION BY expr]
- [ORDER BY expr]
- [SAMPLE BY expr]
- [SETTINGS name=value, ...]
3.2.4 AggregatingMergeTree
会自动合并具有相同 order by 字段值的重复数据,把其他列聚合到一行。
列的类型,可以指定 AggregateFunction、SimpleAggregateFunction、其他类型,指定其他类型,使用第一次插入的值。
AggregateFunction 使用示例: AggregateFunction | ClickHouse Documentation
- CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
- (
- name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
- name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
- ...
- ) ENGINE = AggregatingMergeTree()
- [PARTITION BY expr]
- [ORDER BY expr]
- [SAMPLE BY expr]
- [TTL expr]
- [SETTINGS name=value, ...]
使用示例:
- CREATE MATERIALIZED VIEW test.basic
- ENGINE = AggregatingMergeTree() PARTITION BY toYYYYMM(StartDate) ORDER BY (CounterID, StartDate)
- AS SELECT
- CounterID,
- StartDate,
- sumState(Sign) AS Visits,
- uniqState(UserID) AS Users
- FROM test.visits
- GROUP BY CounterID, StartDate;
-
- -- 查询
- SELECT
- StartDate,
- sumMerge(Visits) AS Visits,
- uniqMerge(Users) AS Users
- FROM test.basic
- GROUP BY StartDate
- ORDER BY StartDate;
3.2.5 CollapsingMergeTree
根据一个标识字段,合并 order by 相同的行。
- CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
- (
- name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
- name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
- ...
- ) ENGINE = CollapsingMergeTree(sign) -- 标识字段, 字段类型 Int8, 1 标识有效, -1 标识无效
- [PARTITION BY expr]
- [ORDER BY expr]
- [SAMPLE BY expr]
- [SETTINGS name=value, ...]
使用示例:
- -- 建表
- CREATE TABLE test.UAct
- (
- UserID UInt64,
- PageViews UInt8,
- Duration UInt8,
- Sign Int8
- )
- ENGINE = CollapsingMergeTree(Sign)
- ORDER BY UserID
-
- -- 插入数据
- INSERT INTO test.UAct VALUES (4324182021466249494, 5, 146, 1)
- INSERT INTO test.UAct VALUES (4324182021466249494, 5, 146, -1),(4324182021466249494, 6, 185, 1)
- OPTIMIZE TABLE test.UAct -- 合并 part
-
- -- 查询数据
- SELECT * FROM test.UAct
- -- 结果
- 4324182021466249494 6 185 1
3.2.6 VersionedCollapsingMergeTree
根据标识字段+version合并 order by 字段相同的行。
- CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
- (
- name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
- name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
- ...
- ) ENGINE = VersionedCollapsingMergeTree(sign, version)
- [PARTITION BY expr]
- [ORDER BY expr]
- [SAMPLE BY expr]
- [SETTINGS name=value, ...]
使用示例:
- CREATE TABLE test.UAct_VC
- (
- UserID UInt64,
- PageViews UInt8,
- Duration UInt8,
- Sign Int8,
- Version UInt8
- )
- ENGINE = VersionedCollapsingMergeTree(Sign, Version)
- ORDER BY UserID
-
- -- 插入数据
- INSERT INTO test.UAct_VC VALUES
- (4324182021466249494, 5, 146, 1, 1),
- (4324182021466249494, 5, 146, -1, 1),
- (4324182021466249494, 6, 185, 1, 2),
- (4324182021466249494, 7, 185, 1, 3),
- (4324182021466249494, 7, 185, -1, 4)
- OPTIMIZE TABLE test.UAct_VC
-
- -- 查询数据
- select * from test.UAct_VC limit 10
- -- 结果, 会把 version 相同的数据进行合并
- 4324182021466249494 6 185 1 2
- 4324182021466249494 7 185 1 3
- 4324182021466249494 7 185 -1 4
3.2.7 GraphiteMergeTree
用来保存 Graphite 数据。
- CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
- (
- Path String,
- Time DateTime,
- Value <Numeric_type>,
- Version <Numeric_type>
- ...
- ) ENGINE = GraphiteMergeTree(config_section)
- [PARTITION BY expr]
- [ORDER BY expr]
- [SAMPLE BY expr]
- [SETTINGS name=value, ...]
3.2.8 数据备份
上面的七个 MergeTree 引擎,都有对应带数据备份的引擎。
- ReplicatedMergeTree
- ReplicatedSummingMergeTree
- ReplicatedReplacingMergeTree
- ReplicatedAggregatingMergeTree
- ReplicatedCollapsingMergeTree
- ReplicatedVersionedCollapsingMergeTree
- ReplicatedGraphiteMergeTree
clickhouse 的数据备份是表级别的,一个集群中,可以既有带备份的表,也可以有不带备份的表。他的使用如下所示:
- CREATE TABLE table_name [ON CLUSTER cluster]
- (
- x UInt32
- ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/default/table_name', '{replica}')
- ORDER BY x
shard 和 replica 是配置在 clickhouse 配置文件的变量,每个 ck 节点对这两个变量都有不同的值,也可以不用变量直接写值。
下面的 sql 演示了如何创建一个1分片2备份的表。
- -- clickhouse3
- create table test.s1r2
- (
- t String
- ) engine = ReplicatedMergeTree('/clickhouse/tables/test/s1r2', 'r1')
- order by t
-
-