ClickHouse 使用介绍

1 CK 介绍

1.1 clickhouse简介

ClickHouse 是俄罗斯的 Yandex 于 2016 年开源的用于在线分析处理查询(OLAP :Online Analytical Processing)MPP架构列式存储数据库(DBMS:Database Management System),能够使用 SQL 查询实时生成分析数据报告。ClickHouse的全称是Click Stream,Data WareHouse。

clickhouse可以做用户行为分析,流批一体

线性扩展和可靠性保障能够原生支持 shard + replication

clickhouse没有走hadoop生态,采用 Local attached storage 作为存储

1.2 clickhouse特点

1、列式存储:

行式存储的好处:

想查找某个人所有的属性时,可以通过一次磁盘查找加顺序读取就可以;但是当想查所有人的年龄时,需要不停的查找,或者全表扫描才行,遍历的很多数据都是不需要的。

列式存储的好处

对于列的聚合、计数、求和等统计操作优于行式存储

由于某一列的数据类型都是相同的,针对于数据存储更容易进行数据压缩,每一列选择更优的数据压缩算法,大大提高了数据的压缩比重

数据压缩比更好,一方面节省了磁盘空间,另一方面对于cache也有了更大的发挥空间

列式存储不支持事务

2、DBMS功能:几乎覆盖了标准 SQL 的大部分语法,包括 DDL 和 DML、,以及配套的各种函数;用户管理及权限管理、数据的备份与恢复

3、多样化引擎:目前包括合并树、日志、接口和其他四大类20多种引擎。

4、高吞吐写入能力:

ClickHouse采用类LSM Tree的结构,数据写入后定期在后台Compaction。通过类 LSM tree的结构, ClickHouse在数据导入时全部是顺序append写,写入后数据段不可更改,在后台compaction时也是多个段merge sort后顺序写回磁盘。顺序写的特性,充分利用了磁盘的吞吐能力。

5、数据分区与线程及并行:

ClickHouse将数据划分为多个partition,每个partition再进一步划分为多个index granularity(索引粒度),然后通过多个CPU核心分别处理其中的一部分来实现并行数据处理。在这种设计下, 单条 Query 就能利用整机所有 CPU。 极致的并行处理能力,极大的降低了查询延时。

所以, ClickHouse 即使对于大量数据的查询也能够化整为零平行处理。但是有一个弊端就是对于单条查询使用多cpu,就不利于同时并发多条查询。所以对于高 qps 的查询业务并不是强项。

6、ClickHouse 像很多 OLAP 数据库一样,单表查询速度优于关联查询,而且 ClickHouse的两者差距更为明显。

关联查询:clickhouse会将右表加载到内存。

1.3 clickhouse为什么快?

C++可以利用硬件优势

摒弃了hadoop生态

数据底层以列式存储

利用单节点的多核并行处理

为数据建立索引一级、二级、稀疏索引

使用大量的算法处理数据

支持向量化处理

预先设计运算模型-预先计算

分布式处理数据

2 SQL语法和数据类型

和标准的sql语法部分地方差不多,但是有些地方又有较大区别

  • 支持子查询

  • 支持 CTE(Common Table Expression 公用表表达式 with 子句)

  • 支持各种JOIN,但是JOIN操作无法使用缓存,所以即使是两次相同的JOIN语句,ClickHouse 也会视为两条新 SQL

  • 窗口函数(官方正在测试中...)

  • 不支持自定义函数

  • GROUP BY 操作增加了 with rollup\with cube\with total 用来计算小计和总计。

  • Delete 和 Update 的能力很重,一般不要这样操作

数据类型没什么特别的,不过支持enum是和其他大数据不一样的地方

  • 整形 INT:Int8 、Int16 、Int32、 Int64

  • 浮点型 :Float32 - float 和 Float64 – double,一般数据值比较小,不涉及大量的统计计算,精度要求不高的时候。比如保存商品的重量。

  • 布尔值:没有单独的类型来存储布尔值。可以使用 UInt8 类型,取值限制为 0 或 1

  • Decimal: 一般金额字段、汇率、利率等字段为了保证小数点精度,都使用 Decimal 进行存储

  • 字符串:String-任意长度、FixedString(N)-固定长度

  • 枚举enum:对一些状态、类型的字段算是一种空间优化,也算是一种数据约束

enum实际使用中往往因为一些数据内容的变化增加一定的维护成本,甚至是数据丢失问题。所以谨慎使用


创建一个待优enum字段的表
CREATE TABLE t_enum
(
    x Enum8('hello' = 1, 'world' = 2)
)
ENGINE = TinyLog;

3 引擎

引擎决定了数据的存储位置、存储结构、表的特征(是否修改操作DDL、DDL、是否支持并发操作)

3.1 数据库引擎

基本上都是默认的Ordinary,简单了解一下即可

Ordinary:默认引擎,在绝大多数情况下我们都会使用默认引擎,使用时无须刻意声明。在此数据库下可以使用任意类型的表引擎。

Dictionary:字典引擎,此类数据库会自动为所有数据字典创建它们的数据表

Memory:内存引擎,用于存放临时数据。此类数据库下的数据表只会停留在内存中,不会涉及任何磁盘操作,当服务重启后数据会被清除

Lazy:日志引擎,此类数据库下只能使用Log系列的表引擎

MySQL:MySQL引擎,将远程的MySQL服务器中的表映射到ClickHouse中,常用语数据的合并。

MaterializeMySQL:MySQL数据同步;将MySQL数据全量或增量方式同步到clickhouse中,解决mysql服务并发访问压力过大的问题

3.2 表引擎

CK的特点,有3种大类型,每个类型又有好几个子类型

特点

优势

劣势

用途

TinyLog

列文件的形式保存在磁盘

不支持索引

没有并发控制

StripeLog

Log

TinyLog

一般练习测试用

Memory

数据直接存在内存

读写不会阻塞

简单查询性能极高

不支持索引

服务重启数据消失

一般不会用于生产

MergeTree

最常用且强大的表引擎

支持索引和分区

存储的数据按主键排序

可以使用分区

支持数据副本

支持数据采样

MergeTree

ReplacingMergeTree

SummingMergeTree

AggregatingMergeTree

CollapsingMergeTree

VersionedCollapsingMergeTree

GraphiteMergeTree

及其子引擎常用于生产环境

MergeTree

核心参数:

分区

partition by

降低扫描的范围,优化查询速度

对涉及跨分区的查询统计,ClickHouse 会以分区为单位并行处理

任何一个批次的数据写入都会产生一个临时分区,不会纳入任何一个已有的分区。写入后的15分钟左右,ClickHouse 会自动执行合并操作(可手动通过 optimize 执行),把临时分区的数据,合并到已有分区中

CREATE TABLE table_with_where

(

id UInt32,

date DateTime,

name Int TTL date + INTERVAL 1 MONTH

)

ENGINE = MergeTree

PARTITION BY toYYYYMM(date)

ORDER BY id

TTL date + INTERVAL 1 MONTH

DELETE WHERE toDayOfWeek(date) = 1;

主键

primary key

数据的一级索引,但是却不是唯一约束

通过稀疏索引快速查找,设置一般依据查询语句中的 where 条件

数据是可以重复的

排序,必填

order by

分区内的数据按照哪些字段顺序进行有序保存

主键必须是 order by 字段的前缀字段

二级索引

为非主键字段的查询发挥作用

INDEX a total_amount TYPE minmax GRANULARITY 5

数据 TTL

支持字段和表级别的生命周期

TTL datetime + INTERVAL 1 MONTH

稀疏索引:稀疏索引的好处就是可以用很少的索引数据,定位更多的数据,代价就是只能定位到索 引粒度的第一行,然后再进行进行一点扫描

稀疏索引图解

ReplacingMergeTree

为了解决MergeTree相同主键无法去重的问题,用来做去重。但是实际上不保证没有重复的数据出现

  1. 去重只会在分区内部进行去重,不能执行跨分区的去重

  1. 只有同一批插入(新版本)或合并分区时才会进行去重,合并会在后台一个不确定的时间进行,因此你无法预先作出计划。有一些数据可能仍未被处理

  1. 认定重复的数据保留,版本字段值最大的

  1. 如果版本字段相同则按插入顺序保留最后一笔

SummingMergeTree

和 doris 的 sum 聚合类似,支持对主键列进行预先聚合。在后台Compaction时,会将主键相同的多行进行sum求和,然后使用一行数据取而代之,从而大幅度降低存储空间占用,提升聚合计算性能

官方建议和MergeTree一起使用,将完整的数据存储在MergeTree表中,并且使用SummingMergeTree来存储聚合数据

  1. 以SummingMergeTree()中指定的列作为汇总数据列

  1. 可以填写多列必须数字列,如果不填,以所有非维度列且为数字列的字段为汇总数据列

  1. 以 order by 的列为准,作为维度列

  1. 其他的列按插入顺序保留第一行

  1. 不在一个分区的数据不会被聚合

  1. 只有在同一批次插入(新版本)或分片合并时才会进行聚合,可能会有未聚合的明细数据,所以sql还是要写sum


select total_amount from XXX where province_name=’’ and create_date=’xxx’
替换为
select sum(total_amount) from province_name=’’ and create_date=‘xxx’
AggregatingMergeTree

功能类似doris aggregate模型 ,与SummingMergeTree的区别在于:SummingMergeTree对非主键列进行sum聚合,而AggregatingMergeTree则可以指定各种聚合函数

改变了数据片段的合并逻辑。 ClickHouse 会将一个数据片段内所有具有相同主键(准确的说是排序键)的行替换成一行,这一行会存储一系列聚合函数的状态

可以使用AggregatingMergeTree表来做增量数据的聚合统计,包括物化视图的数据聚合

CollapsingMergeTree

ClickHouse实现了CollapsingMergeTree来消除ReplacingMergeTree的限制。该引擎要求在建表语句中指定一个标记列Sign,后台Compaction时会将主键相同、Sign相反的行进行折叠,也即删除。

CollapsingMergeTree将行按照Sign的值分为两类:Sign=1的行称之为状态行,Sign=-1的行称之为取消行。

每次需要新增状态时,写入一行状态行;需要删除状态时,则写入一行取消行。

在后台Compaction时,状态行与取消行会自动做折叠(删除)处理。而尚未进行Compaction的数据,状态行与取消行同时存在。

因此为了能够达到主键折叠(删除)的目的,需要业务层进行适当改造:

  1. 执行删除操作需要写入取消行,而取消行中需要包含与原始状态行一样的数据(Sign列除外)。所以在应用层需要记录原始状态行的值,或者在执行删除操作前先查询数据库获取原始状态行

  1. 由于后台Compaction时机无法预测,在发起查询时,状态行和取消行可能尚未被折叠;另外,ClickHouse无法保证primary key相同的行落在同一个节点上,不在同一节点上的数据无法折叠。因此在进行count(*)、sum(col)等聚合计算时,可能会存在数据冗余的情况。为了获得正确结果,业务层需要改写SQL,将count()、sum(col)分别改写为sum(Sign)、sum(col * Sign)

CollapsingMergeTree虽然解决了主键相同的数据即时删除的问题,但是状态持续变化且多线程并行写入情况下,状态行与取消行位置可能乱序,导致无法正常折叠。

VersionedCollapsingMergeTree

为了解决CollapsingMergeTree乱序写入情况下无法正常折叠问题,VersionedCollapsingMergeTree表引擎在建表语句中新增了一列Version,用于在乱序情况下记录状态行与取消行的对应关系。主键相同,且Version相同、Sign相反的行,在Compaction时会被删除

与CollapsingMergeTree类似, 为了获得正确结果,业务层需要改写SQL,将count()、sum(col)分别改写为sum(Sign)、sum(col * Sign)

4 其他

4.1 分片集群和副本

这两个特点或概念是大数据很常见的了,简单看一下

副本:保障数据的高可用性,即使一台 ClickHouse 节点宕机,那么也可以从 其他服务器获得相同的数据

分片集群:解决横向扩容问题,通过分片把一份完整的数据进行切 分,不同的分片分布到不同的节点上,再通过 Distributed 表引擎把数据拼接起来一同使用

但是ClickHouse 的集群是表级别的,实际企业中,大部分做了高可用,但是没有用分片,避免降低查询性能以及操作集群的复杂性

4.2 物化视图

普通视图不保存数据,保存的仅仅是查询语句,查询的时候还是从原表读取数据,可以将普通视图理解为是个子查询。物化视图则是把查询的结果根据相应的引擎存入到了磁盘或内存中,对数据重新进行了组织,你可以理解物化视图是完全的一张新表

  • 优点:查询速度快,要是把物化视图这些规则全部写好,它比原数据查询快了很多,总的行数少了,因为都预计算好了。

  • 缺点:它的本质是一个流式数据的使用场景,是累加式的技术,所以要用历史数据做去重、去核这样的分析,在物化视图里面是不太好用的。在某些场景的使用也是有限的。而且如果一张表加了好多物化视图,在写这张表的时候,就会消耗很多机器的资源,比如数据带宽占满、存储一下子增加了很多。

视图语法:


CREATE [ MATERIALIZED ] VIEW [ IF NOT EXISTS ] [ db.] table_name [ TO [ db.] name ] 
[ ENGINE = engine ] [ POPULATE ] AS
SELECT
...

4.3 CK数据一致性

4.n

EXPLAIN SYNTAX 可以查看语法优化

和Hive等不同,DateTime 不需要经过函数转换处理,执行效率高、可读性好,一般不设置类型为String或者Long

空值存储类型,CK的null影响性能且无法索引,一般设置默认值

一般按天分区,以单表一亿数据为例,分区大小控制在 10-30 个为最佳

索引查询频率大的在前原则,基数特别大的不适合做索引列, 如用户表的 userid 字段;通常筛选后的数据满足在百万以内为最佳

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

orange大数据技术探索者

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

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

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

打赏作者

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

抵扣说明:

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

余额充值