库引擎
一般就用默认的。其他的还在实验中。
表引擎
数据类型
-
Int8
-
Int16
-
Int32
-
Int64
-
UInt8
-
Uint16
-
Uint32
-
Uint64
-
Boolean用Uint8表示
-
Float32
-
Float64
-
Decimal(存钱):可以在加减乘除 运算过程中保持精度。对于除法,最低有效数字将被抛弃(不进行四舍五入)。通常有三种声明:
Decimal32(s),Decimal64(s),Decimal128(s)
,后面的s表示小数点后的数字位数。前面的32,64,128表示浮点精度,决定可以有多少个十进制数字(包含小数位),也就代表着不同的取值范围。官方建议使用32与64 -
String
-
FixedString(N)
-
Enum8
-
Enum16
CREATE TABLE test_enum ( x Enum8('hello' = 1, 'world' = 2) ) ENGINE = TinyLog SELECT CAST(x,'Int8') FROM test_enum;
-
array(T)
-
Date
-
DateTime
-
DateTime64
手动操作合并:optimize table t_stock final
TTL需要定义一个时间列,然后基于这个时间列开始计算TTL。
ReplacingMergeTree
数据的去重只会在数据合并期间进行。
适用于后台清楚重读的数据节省空间,但是不保证没有重复的数据出现。
ENGINE = ReplacingMergeTree([ver])
- 按照orderby指定的排序见作为判断重复的标准
- 它的去重只限定在一个分区中,不能跨区去重。
- 对于判断为重复的数据,保留版本字段最大的一条数据,如果没有指定版本(ver)值或者版本值也有重复的,就会保留最后插入的一条数据。
- 并不能始终保证数据是完全去重的。数据去重只会发生在同一批插入数据以及后台数据合并这两个时间。
SummingMergeTree
当合并SummingMergeTree表的数据片段时,ck会把所有具有相同主键的行合并为一行,该行包含了被合并的行中具有数值数据类型的列的汇总值。
ENGINE = SummingMergeTree([columns])
生产中并不多。orderby可不加。就是说没索引了。
数据查询
函数
对具体的列进行操作。
- 支持子查询
- 支持各种JOIN查询。但不建议使用。因为JOIN操作无法使用缓存。并且CK执行JOIN操作的方式是将后面的表全部加载到内存中执行,优化不是很好。表很大时性能影响非常明显。
- 支持WITH语句创建一个临时的表。
表函数
表函数是CK非常有特色的一类函数。就是可以像表一样使用的函数。例如numbers()
。
聚合函数
- 计算留存
集群机制
主要作用:
- 数据副本
- 分布式表:将一个表的数据分散到多个节点上保存
数据副本
使用Zookeeper同步。不建议在使用CK的服务器上使用ZK。不低于3.4.5。
ENGINE = ReplcatedMergeTree('/clickhouse/tables/t_stock','hadoop03')
在这个过程中,你基本不需要担心ZK的性能问题。一个ZK集群能给整个CK集群支持协调每秒几百个INSERT,数据的吞吐量可以跟不用复制的数据一样高。
分布式表
数据副本仍然是每台服务器存全部的数据。
在CK可以通过水平切分的方式,将完整的数据集切分成不同的分片。这些分片只保存一部分数据,分布在不同的节点上。
然后再通过Distributed
表引擎实现。
每个分片shard分配一个权重weight,默认是1。
internal_replication
默认为false,生产使用true。一个分片下多个副本。
分片键。
- 优先选择errors_count小的副本
- errors_count先沟通的有随机、顺序、随机(优先第一顺位)、host名称近似等四种选择方式
config.xml users.xml
使用分布式表需要先配置ZK。
<remote_servers>配置集群。
CREATE TABLE t_table on cluster logs(
)
ENGINE = MergeTree() -- ReplactedMergeTree('','')
-- /clickhouse/target/{shard}/
<macros>
<shard>01</shard>
<replica>example01</replica>
</macros>
在创建的Replicated表的基础上再创建Distributed
表。
CREATE TABLE t_logs on cluster logs (
)
ENGINE = Distrited(logs,default,t_table_local,hiveHash(sku_id))
通常只建议只使用数据副本,不建议使用分布式表。
配置优化
CK最重要的是使用CPU。
- users.xml
- session配置
- 查询时指定
官方文档:服务器设置、设置
查询优化
查看执行计划
EXPLAN [] SEELCT
- SYNTAX
- AST
- PLAN
- PIPELINE
CK内置的优化规则
- count优化
- 聚合计算外推
- 谓词下推:例如先过滤,再聚合 // 需要set 配置
- 三元运算转换成multiif // 需要 set 配置
- 聚合优化
高性能查询优化
- 选择合适的表引擎
- 建表时不要使用Nullable
- 合适的划分分区和索引
- 数据变更优化:对CK数据的增删改操作都会产生新的临时分区,会给MergeTree
- 使用Prewhere替代where
- 指定列和分区
- 避免构建虚拟列
- 用IN代替JOIN
生产常见问题
CK的数据一致性问题
CK只能保证最终一致性,而不能保证强一致性。
_sign
_version
-- 自己实现乐观锁
多副本表,尽量固定写入的节点
恢复方式:将主节点的metadata和data目录全部清空,然后将副节点的metadata和data目录拷贝过来,重启数据库即可。
ZK数据丢失导致副本表无法启动
需要重建ZK里的信息。首先移除问题节点上的metadata中对应表的结构文件,将CK服务启动起来。启动后,重新创建对应的表。建表语句可以从metadata中的表结构文件中获取,也可以从其他正常节点上执行show create table
语句获取。
而CK中对应的表数据,会在表重建后重新下载。这样过一段时间再来验证一下数据是否一致就可以了。
总结
类似LSM树。即新的数据并不会影响原有的数据,而实会记录在一个新开辟的临时数据块中。查询时会通过版本号查询最新的一条结果。新开辟的数据需要等到后台进行数据合并时,才会进入主数据中。数据合并是在后台某个不确定的时间点进行的,当然也可以手动触发数据合并。
扩展MergeTree在合并的时候定制数据合并的逻辑。