ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS)。
绝大多数是读请求
数据以相当大的批次(> 1000行)插入,而不是单行插入;或者根本没有插入。
已添加到数据库的数据不能修改。
对于读取,从数据库中提取相当多的行,但只提取列的一小部分。
宽表,即每个表包含着大量的列
查询相对较少(通常每台服务器每秒查询数百次或更少)
对于简单查询,允许延迟大约50毫秒
列中的数据相对较小:数字和短字符串(例如,每个URL 60个字节)
处理单个查询时需要高吞吐量(每台服务器每秒可达数十亿行)
事务不是必须的
对数据一致性要求低
每个查询有一个大表。除了他以外,其他的都很小。
查询结果明显小于源数据。换句话说,数据经过过滤或聚合,因此结果适合于单个服务器的RAM中
针对分析类查询,通常只需要读取表的一小部分列。在列式数据库中你可以只读取你需要的数据。例如,如果只需要读取100列中的5列,这将帮助你最少减少20倍的I/O消耗。
由于数据总是打包成批量读取的,所以压缩是非常容易的。同时数据按列分别存储这也更容易压缩。这进一步降低了I/O的体积。
由于I/O的降低,这将帮助更多的数据被系统缓存。
由于执行一个查询需要处理大量的行,因此在整个向量上执行所有操作将比在每一行上执行所有操作更加高效。同时这将有助于实现一个几乎没有调用成本的查询引擎。如果你不这样做,使用任何一个机械硬盘,查询引擎都不可避免的停止CPU进行等待。所以,在数据按列存储并且按列执行是很有意义的。
有两种方法可以做到这一点:
向量引擎:所有的操作都是为向量而不是为单个值编写的。这意味着多个操作之间的不再需要频繁的调用,并且调用的成本基本可以忽略不计。操作代码包含一个优化的内部循环。
代码生成(CodeGen):生成一段代码,包含查询中的所有操作。
这是不应该在一个通用数据库中实现的,因为这在运行简单查询时是没有意义的。但是也有例外,例如,MemSQL使用代码生成来减少处理SQL查询的延迟(只是为了比较,分析型数据库通常需要优化的是吞吐而不是延迟)。
向量化的执行离不开SIMD,全称single instruction multiple data,对于现代多核CPU,其都有能力用一条指令执行多条数据,用SIMD指令完成这样代码设计和执行就叫做向量化。目前主流的编译器都支持向量化,我们既可以手写SIMD指令来完成向量化,也可以让编译器帮助我们完成。
一、迭代模型/火山模型(Iterator Model)
又称 Volcano Model 或者 Pipeline Model。
二、物化模型(Materialization Model)
三、向量化/批处理模型(Vectorized / Batch Model)
1、列式数据库,字段应该是定长。
2、数据压缩
3、数据的磁盘存储,降低存储成本
4、多核心并行处理
5、多服务器分布式处理
6、支持SQL标准查询
7、向量引擎
8、实时的数据更新
9、支持索引
10、适合在线查询
11、支持近似计算
12、自适应链接算法(join)
13、支持数据复制和数据完整性
14、角色的访问控制
限制:
没有完整的事务支持。
稀疏索引使得ClickHouse不适合通过其键检索单行的点查询。
1、单节点设置
2、集群设置
ClickHouse集群是一个同质集群。 设置步骤:
在群集的所有机器上安装ClickHouse服务端
在配置文件中设置集群配置
在每个实例上创建本地表
创建一个分布式表
业务查询时,查询分布式表。会使用集群中的所有节点的分片资源(本地表)。每个实例还可以基于本地表创建多个备份副本。
表引擎(即表的类型)决定了:
数据的存储方式和位置,写到哪里以及从哪里读取数据
支持哪些查询以及如何支持。
并发数据访问。
索引的使用(如果存在)。
是否可以执行多线程请求。
数据复制参数。
MergeTree:MergeTree ReplacingMergeTree SummingMergeTree AggregatingMergeTree CollapsingMergeTree VersionedCollapsingMergeTree GraphiteMergeTree
Log: TinyLog StripeLog Log
集成引擎
用于其他特点功能的引擎
虚拟列是表引擎组成的一部分,它在对应的表引擎的源代码中定义。不能在 CREATE TABLE 中指定虚拟列,并且虚拟列不会包含在 SHOW CREATE TABLE 和 DESCRIBE TABLE 的查询结果中。虚拟列是只读的,所以不能向虚拟列中写入数据。如果想要查询虚拟列中的数据,必须在SELECT查询中包含虚拟列的名字。SELECT * 不会返回虚拟列的内容。
若创建的表中有一列与虚拟列的名字相同,那么虚拟列将不能再被访问。为了避免这种列名的冲突,虚拟列的名字一般都以下划线开头。
1、跳数索引
关系型数据库常用的复合索引(见原理)不适用于列式存储数据库。
跳数索引类型:minmax set Bloom Filter Types
2、稀疏索引 小结 带有联合主键(UserID, URL)的表的主索引对于加快UserID的查询过滤非常有用。但是,尽管URL列是联合主键的一部分,但该索引在加速URL查询过滤方面并没有提供显著的帮助。
反之亦然:具有复合主键(URL, UserID)的表的主索引加快了URL上的查询过滤,但没有为UserID上的查询过滤提供太多支持。
由于主键列UserID和URL的基数同样很高,过滤第二个键列的查询不会因为第二个键列位于索引中而受益太多。
因此,从主索引中删除第二个键列(从而减少索引的内存消耗)并使用多个主索引是有意义的。
但是,如果复合主键中的键列在基数上有很大的差异,那么查询按基数升序对主键列进行排序是有益的。