1 ClickHouse特性
OLAP数据库一般有2个要求:①容量要比关系型数据库大,②在线查询的速度要快。ClickHouse这两点都满足并且还支持标准的sql,支持比较复杂的语句,支持分布式。ClickHouse的几个显著特点如下:
(1)列式存储
列式存储的优点:①列式存储不同于行式存储,以行为单位进行存储,行式存储更变故搜索查询。列式存储以列为单位进行存储,这样更适合做聚合计算,如求和是针对一列的数据进行求和,这一列的数据又放在一起。②行式存储每个字段类型不一致,列式存储不同的类型是不在一起的,一个数据块存储的类型都是一致的,这样的话就便于压缩,类型相同压缩算法发挥的空间就比较大,压缩比高,所以海量数据的话就能对节省磁盘空间。③因为一个数据块类型相同,压缩比高,不仅节省了磁盘空间,还节省了内存空间,可以在内存中存储更多的数据。
列式存储的缺点:不支持事务
(2)支持DBMS的功能
支持的SQL和关系型数据库基本没有什么差别,支持标准SQL的大部分语法,包括DDL和DML及各种函数。虽然ClickHouse可以修改数据结构,可以删除数据,但是性能不好。
(3)支持多种引擎
ClickHouse与Mysql类型把表级别的存储引擎插件化,支持的引擎可以分为6大类,用的最多的是MegreTree家族
2 ClickHouse的写入
一般关系型数据的写入基本上是随机写,为了方便查询,要知道插入的位置,找到合适的位置插入。写入操作本事不重,但是要找到合适的位置就是个问题,随机的读写,每次写入位置不同,机械磁盘的磁头就不同的转找位置,所以写入能力比较弱。像HBASE,也是随机写入,但是采用LSM树进行是异步的写入,先把数据写到内存,就完事了,要插入的位置交给磁盘去处理。
ClickHouse也是采用了LSM Tree结构数据写入后定期在后台合并。写入操作是先写到内存,然后在写磁盘的时候不是写到对应的位置,而是直接写到一个临时的分区里面,全部都堆在内存数据量大的话很麻烦,然后会简单的做个排序,后台会异步周期性的将临时分区的数据合并到整个存储分区中
3 ClickHouse的读取
ClickHouse将数据划分为多个分区(partition),每个分区再进一步划分为多个索引段(index ganularity)。把分区里面的数据划分成细粒度的好处是可以多核并行处理。
假设一个数据有3个分区,执行一条查询SQL没有指定任何分区的话就利用多线程,把SQL提交到每个分区查询,每个CPU现成管理一个分区的数据查询,最后合并结果。这种极致的并行处理能力极大的降低了查询的延迟。但是因为查询是多线程的,所以非常消耗CPU,每条SQL都是并行的,这样的话带来的问题就是并行查询很多SQL的时候就会并发非常高,核数不够的话CPU就会不停的在线程之间来回切换。CPU在大量线程里面轮转本事就要消耗CPU,所以开销更大。
ClickHouse对一条SQL就已经是高并发,并行处理了,如果提交的SQL还是高并发就不适合使用ClickHouse。ClickHouse适合查询数据量比较大,SQL比较复杂的查询,他的单一SQL处理能力非常强,因为是并行的,如即席查询,或者像大屏这种低频的查询。不适合开发给用户,进行高QPS的查询业务,他的QPS理论上比Mysql还要低。
4 与标准SQL的区别
4.1 Insert
与标准SQL基本一致,包括标准的插入
INSERT INTO [db.]table [(c1, c2, c3)] VALUES (v11, v12, v13), (v21, v22, v23), ...
以及表到表的插入
INSERT INTO [db.]table [(c1, c2, c3)] SELECT ...
但是和hive不一样没有insert overwrite
4.2 Update,Delete
ClickHouse有Update和Delete的能力,可看做是Alter的一种,但是和一般的OLAP数据库不一样,称为Mutation查询。Mutation的语法,其实是数据结构的调整,本身不是以数据为单位的修正。
Mutation是很重的操作,因为每次修改或者删除都会导致放弃目标数据原有的分区,意味着分区会被重写,假设我们以天为分区。假设一个分区内的数据有被删除或者修改了。删除的话他是把这个分区的数据重新的再建立一个新分区,没有删除的数据就会重新复制一份,老分区的数据暂时不动,做数据合并的时候他会被删除掉。我们查的时候感觉不出,其实分区已经替换了,所以是个很重的操作,而且不支持事务。Mutation支持分为两步,同步的操作时在新增数据新增分区的时候把就分区打上逻辑上的失败标记,指导触发合并的时候才会删除就数据释放磁盘空间
所以要做Update和Delete的话尽量做批量的操作,不进行频繁的小数据操作。
删除
ALTER TABLE [db.]table [ON CLUSTER cluster] DELETE WHERE filter_expr
修改
ALTER TABLE [db.]table UPDATE column1 = expr1 [, ...] WHERE filter_expr
4.3 Select
select查询与标准SQL差别不大:①支持子查询②支持with子句③支持join(不推荐,join无法使用缓存)④但是不支持窗口函数⑤不支持自定义函数,mysql可以做个function自定义函数,还有存储过程,hive有个变相的方法语法上不支持,但是可以写代码自定义jar包发布成一个函数。ClickHouse是c++写的,只能通过改源码编译可能支持部分的,只能是常驻特别简单的,针对业务的函数不可能每次重编译,所以不行。⑥group by操作增加了按照维度来计算汇总的操作:with rollup(上卷)从右往左依次去掉维度汇总/with cube(立方体)从右边开始去完维度,从左边开始去维度;/with total(只计算合计)等操作
4.4 Alert
可以根据字段或者数据结构进行调整,这种alert都是比较重,一般都是在夜里批量的操作
ALTER TABLE [db].name [ON CLUSTER cluster] ADD|DROP|CLEAR|COMMENT|MODIFY COLUMN ...
4.5 导出数据
即席查询往往是从数据库里临时需要导出一张报表来导出execel让业务人员去用,所以导出是常用的,常用的就是csv,csvwithNames是带表头的
clickhouse-client --query="SELECT * FROM {some_table} FORMAT Avro" > file.avro
对应的插入语句为
cat file.avro | clickhouse-client --query="INSERT INTO {some_table} FORMAT Avro"