你知道 Clickhouse 的这些知识吗?

868 阅读10分钟

一、介绍

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 作为存储

二、clickhouse特点

1.列式存储

在人们的印象当中,一般数据库都是行式存储,即一条事务的所有字段都是紧邻的,一行数据存一块列式存储是将数据的一列数据存一块

以下面的表road_Table为例:

TIDRoadNameLength
001中央大道2521
002育才路1655
003华盛街1844

1)采用行式存储时,数据在磁盘上的组织结构为:

image-20220409104249609.png

行式存储适合针对`行`的查询:
select * from road_Table limit 1
只需要查找到第一个就可以返回结果

当针对`列`查询时:
select RoadName from road_Table
它需要读取所有的数据
  • 行存储适合insert/update操作比较多的场景,因为只需要更改部分数据块即可

2)采用列式存储时,数据在磁盘上的组织结构为:

image-20220409104307102.png

列式存储适合针对`列`的查询:
select RoadName from road_Table
只需要查找到第一个就可以返回结果

当针对`行`查询时:
select * from road_Table limit 1
它需要读取所有的数据,然后组合进行返回
  • 不适用于insert/update操作比较多的场景,比如当插入1个row时,由于列式存储导致同一个row的数据被分散在多个数据块中,因此需要去遍历所有数据块的数据。
  • 此外由于同一个字段连续存储(同一列的内容有很多值是重复的,可以压缩),因此更加便于编码压缩。

3)采用列式存储的好处:

  • 对于列的聚合,计数,求和等统计操作原因优于行式存储。
  • 由于某一列的数据类型都是相同的,针对于数据存储更容易进行数据压缩,每一列选择更优的数据压缩算法,大大提高了数据的压缩比重。
  • 由于数据压缩比更好,一方面节省了磁盘空间,另一方面对于 cache 也有了更大的发挥空间。

2.DBMS的功能

几乎覆盖了标准 SQL 的大部分语法,包括 DDL 和 DML,以及配套的各种函数,用户管理及权限管理,数据的备份与恢复。所以对于熟悉mysql的人来说是非常容易上手的。

3.多样化引擎

ClickHouse 和 MySQL 类似,把表级的存储引擎插件化,根据表的不同需求可以设定不同的存储引擎。目前包括合并树、日志、接口和其他四大类 20 多种引擎。

4.高吞吐写入能力

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

官方公开 benchmark 测试显示能够达到 50MB-200MB/s 的写入吞吐能力,按照每行100Byte 估算,大约相当于 50W-200W 条/s 的写入速度。

5.数据分区与线程级并行

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

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

6.性能对比

1、单表查询

sq|语句(单表测试语句)Hawapresto(orc格式)Impala(parquet格式)spark- sql(orc格式)ClickHousegreenplumhive(orc格式)
sql 0112.7341.081.536.660.3079.01851.45
sql_0215.5782.14.049.620.51510.887129.78
sql_0316.7743.034.858.950.75911.247130.7
sql_0423.4695.7811.5911.060.47720.137185.38
sql_0512.5473.261.324.750.4438.69450.05
sql_0688.50629.5543.1643.4312.34189.75343.86
sql_0786.46828.8945.1641.3412.19890.318346.92
sql_08134.7268.2372.3290.2819.217154.77455.37
sql_09133.6954.1872.4598.5939.669221.7822402.521
总时间524.486196.1256.42314.6885.926616.6034096.031

2、多表查询

sq|语句(单表测试语句)Hawapresto(orc格式)Impala(parquet格式)spark- sql(orc格式)ClickHousegreenplumhive(orc格式)
sql_0113.4474.588.7327.0521.2427427.96
sql_0214.8234.387.7320.6131.3113393.45
sql_0316.1346.899.8340.9122.4119604.23
sql 0422.64834.0831.4671.1289.16381h以上
sqL_0516.4574.589.1545.7133.8313472.58
sql_0620.75210.289.1337.6535.4119527.13
sql_0726.12518.439.5341.6348.94321h以上
sql_0813.3694.9211.2925.7921.3126433.13
sql_091.0770.991.942.242.950.26456.21
sql_1048.0227.3321.4356.7544.1215553.74
sql_1121.1318.9112.2141.5534.65311h以上
sql_1216.4930.8525.1659.9448.83471h以上
sqL 1381.08132.8419.29164.32100.41211h以上
sqL1414.594.643.897.5110.1710620.35
sql 1538.49517.221.4347.6646.8220633.65
总时间364.64200.92192.2690.44591.56331.266.41h

从上面两个表可以看出,clickhouse的单表查询是比多表查询快的非常多,同时单表查询对比其他数据库也有很大的优势

三、为什么clickhouse那么快?

1、硬件方面

Clickhouse会在内存中进行Group By,并使用HashTable装载数据。与此同时,CH对于CPU L3级别的缓存也特别在意,因为一次L3级别缓存的失效都会带来70~100ns,积少成多。一个32G,则可能会浪费5亿次/秒的运算。也正是因为如此,CH能在基准查询中做到1.75亿次/秒的数据扫描能力

2、算法方面

常量方面,CH使用了Volnisky算法;非常量,则使用CPU的向量化执行SIMD来优化;正则使用re2和hyperscan算法。

3、应景优化

CH会在不同的场景使用不同的算法。例如,在去重函数uniqCombined中,会根据数据量选择不同的算法:数据量比较少的时候,会选择使用Array来保存;数据量中等的时候,使用HashSet;数据量很大的时候,会使用HyperLogLog算法。

4、向量化

CH使用向量化执行。SIMD被广泛地应用于文本转换、数据过滤、数据解压和JSON转换等场景。相对于单纯使用CPU,利用寄存器暴力优化也算是一种降维打击

5、持续测试和持续改进

一个好的产品,肯定是能很好应用于各种场景的。CH由于拥有Yandex的天然优势,经常会使用真实数据来进行测试,尝试使用于各个场景。也因此获得了快速的版本更新换代,基本维持在一个月一更新。

四、ClickHouse引擎

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

1.数据库引擎

目前支持的数据库引擎有5种:

  • Ordinary:默认引擎,在绝大多数情况下我们都会使用默认引擎,使用时无须刻意声明。在此数据库下可以使用任意类型的表引擎。
  • Dictionary:字典引擎,此类数据库会自动为所有数据字典创建它们的数据表
  • Memory:内存引擎,用于存放临时数据。此类数据库下的数据表只会停留在内存中,不会涉及任何磁盘操作,当服务重启后数据会被清除
  • Lazy:日志引擎,此类数据库下只能使用Log系列的表引擎
  • MySQL:MySQL引擎,将远程的MySQL服务器中的表映射到ClickHouse中,常用语数据的合并。
  • MaterializeMySQL:MySQL数据同步;将MySQL数据全量或增量方式同步到clickhouse中,解决mysql服务并发访问压力过大的问题

2.表引擎

表引擎(即表的类型)决定了:

  • 数据的存储方式和位置,写到哪里以及从哪里读取数据
  • 支持哪些查询以及如何支持。
  • 并发数据访问。
  • 索引的使用(如果存在)。
  • 是否可以执行多线程请求。
  • 数据复制参数。

MergeTree

(使用Replicated* 的引擎版本),分区和一些其他引擎不支持的其他功能。

该类型的引擎:

- MergeTree - ReplacingMergeTree - SummingMergeTree - AggregatingMergeTree - CollapsingMergeTree - VersionedCollapsingMergeTree - GraphiteMergeTree

日志

具有最小功能的轻量级引擎。当您需要快速写入许多小表(最多约100万行)并在以后整体读取它们时,该类型的引擎是最有效的。

该类型的引擎:

集成引擎

用于与其他的数据存储与处理系统集成的引擎。 该类型的引擎:

用于其他特定功能的引擎

该类型的引擎:

虚拟列

虚拟列是表引擎组成的一部分,它在对应的表引擎的源代码中定义。

您不能在 CREATE TABLE 中指定虚拟列,并且虚拟列不会包含在 SHOW CREATE TABLEDESCRIBE TABLE 的查询结果中。虚拟列是只读的,所以您不能向虚拟列中写入数据。

如果想要查询虚拟列中的数据,您必须在SELECT查询中包含虚拟列的名字。SELECT * 不会返回虚拟列的内容。

若您创建的表中有一列与虚拟列的名字相同,那么虚拟列将不能再被访问。我们不建议您这样做。为了避免这种列名的冲突,虚拟列的名字一般都以下划线开头。

六、副本-高可用性

写入流程:写入数据后将写入日志提交到zk,副本收到zk的写入日志后从主节点下载新数据

配置步骤:同步xml配置文件,分别建表,引擎采用ReplicatedMergeTree

参数传递:engine =ReplicatedMergeTree('/clickhouse0225/table/01/t_order_rep','rep_102')

七、分片集群

(1)解决问题:横向扩容、水平切分

(2)操作:不同分片在不同节点,使用Distributed 表引擎实现数据拼接

(3)读取流程:选择error count小的副本进行数据的读取

八、拓展:

MMP

定义

MPP (Massively Parallel Processing),大规模并行处理系统,这样的系统是由许多松耦合的处理单元组成的,要注意的是这里指的是处理单元而不是处理器。每个单元内的 CPU都有自己私有的资源,如总线,内存,硬盘等。在每个单元内都有操作系统和管理数据库的实例复本。这种结构最大的特点在于不共享资源。

特征

● 任务并行执行;

● 数据分布式存储(本地化);

● 分布式计算;

● 私有资源;

● 横向扩展;

● Shared Nothing架构。(主机,操作系统,内存,存储都是自我控制的,不存在共享。也就是每个节点都是一个单独的数据库。节点之间的信息交互是通过 节点互联网络实现。)

价值

1.技术: 基于列存储+MPP架构的新型数据库在核心技术上跟传统数据库有巨大差别,是为面向结构化数据分析设计开发的,能够有效处理PB级别的数据量。在技术上为很多行业用户解决了数据处理性能问题。

2.用户价值: 新型数据库是运行在x-86 PC服务器之上的,可以大大降低数据处理的成本(1个数量级)。

3.未来趋势: 新型数据库将逐步与Hadoop生态系统结合混搭使用,用MPP处理PB级别的、高质量的结构化数据,同时为应用提供丰富的SQL和事务支持能力;用Hadoop实现半结构化、非结构化数据处理。这样可同时满足结构化、半结构化和非结构化数据的处理需求。

参考:

clickhouse官方文档

百度百科