clickhouse系列第一篇之clickhouse的出现背景以及使用场景(6000多字总结)


一. 概念

1. 介绍

clickhouse是一个面向列的数据库管理系统(DBMS),用于查询操作的在线分析处理(OLAP)

2. 背景

2.1 行存储
在普通的行存储的DBMS中,数据的存储顺序是

RowWatchIDJavaEnableTitleGoodEventEventTime
#0893543506621Investor Relations12016-05-18 05:19:20
#1903295099580Contact us12016-05-18 08:10:20
#2899537060541Mission12016-05-18 07:38:00
#N

对于行存储,一行上面的所有的值在物理存储上都是彼此相邻的
面向行存储的DBMS有MySQL,postgres,sqlserver

2.2 列存储
在列存储的模式,数据的存储顺序是

rows#0#1#2#N
WatchID893543506629032950995889953706054
JavaEnable101
TitleInvestor RelationsContact usMission
GoodEvent111
EventTime2016-05-18 05:19:202016-05-18 08:10:202016-05-18 07:38:00

对于列存储,不同列的值是分开存储的,同一列的值是一起存储的
列式存储的DBMS有Vertica, Paraccel (Actian Matrix and Amazon Redshift), Sybase IQ, Exasol, Infobright, InfiniDB, MonetDB (VectorWise and Actian Vector), LucidDB, SAP HANA, Google Dremel, Google PowerDrill, Druid, and kdb+.

2.3 总结
数据不同的存储方式适用于不同的场景。这里的场景(数据访问场景)是指:

  • 什么时候查询,多久查询一次,查询比例是多少;
  • 每次查询读取的数据量是多少(行,列和字节);
  • 读取数据和更新数据之间的关系;
  • 数据的大小以及在本地的使用方式;
  • 是否使用事务以及他们的隔离程度;
  • 数据复制和逻辑完整性的要求;
  • 查询的延迟和吞吐量的要求等。

当系统的负载越高的时候,针对于特定使用场景对系统进行定制就显得越加重要,并且这种定制也会要求更细的粒度。没有任何的系统可以适用于所有的场景。如果是一个广泛应用于所有场景的系统,那么在高负载下,这个系统并不能很好的处理所有的情况,或者说是这个系统只能很好的适用于某几个场景。

3. OLAP场景的关键属性

  • 绝大部分的请求都是读请求
  • 数据被添加到数据库之后要不不更新,如果要更新的话都是大批量(大于1000行)的更新,而不是单行的更新
  • 读取数据的时候,都是读取数据库中大量行和很少的列
  • 宽表即意味着有很多的列
  • 查询相对来说是少的(通常每台服务每秒几百个查询或者是更少)
  • 对于一些检查的查询,允许大约50毫秒的延迟
  • 每一列的值都是很小的:数字或者是短的字符串(例如,每个 URL 60 个字节)
  • 处理单个查询需要高吞吐量(每台服务器每秒高达数10亿行)
  • 事务不是必须的
  • 对数据的一致性要求很低
  • 每一次查询都是一个大表关联多个小表的结合
  • 查询结果明显的小于源数据。换句话说,查询结果是源数据进行了过滤和聚合,因此,结果适用于单个服务的RAM

从上面的特点可以看出的是OLAP的场景和其他流行的场景(如OLTP和key-value访问)有很大的不同。因此,如果对性能有很高的要求的话,尝试使用OLTP或者键值数据库来处理分析查询是没有意义的。例如,如果使用MongoDB或是redis进行分析,与OLAP相比,将会获得非常差的性能

4. 为什么面向列的数据库在OLAP场景中可以工作的更好

面向列的数据库在处理大多数的查询的时候,可以快至少100倍

4.1 输入和输出

  • 由于是分析查询,只需要读取少量的列和大量的行。在面向列的数据库中,由于按列进行存储的,所以我们可以很快的只读取我们想要的数据。例如,如果需要100列中的5列,那么列式存储比行式存储预计可以减少20倍的IO
  • 由于数据是以包的形式读取的,所以可以更好的进行压缩。列中的数据存储在一起更容易进行压缩。这也进一步的减少了IO
  • 由于减少了IO,所以系统缓存中可以存储更多的数据

例如:“统计每一个广告平台的记录数”需要读取广告平台ID这一列,未压缩的时候占用一个字节。假设大部分的流量都不是来自于广告平台,那么预计这列就会大比例的进行压缩(数据压缩之后的大小是取决于数据有效值的多少);如果使用快速压缩算法,数据的解压速度至少在每秒几GB;换句话说,该查询在单个服务器上以每秒数十亿的速度处理。

5. CPU

因为执行一个操作需要处理大量的行,所以需要我们把所有的操作调度在整个向量上而不是单行上。如果不这样做,对于任何的半正片磁盘子系统,查询解析器都会打满CPU。所以将数据按列存储并且在可能的情况下按列进行处理是非常有意义的。

有两种方法可以实现:
1. 矢量引擎:所有的操作都是针对向量,而不是单独的值。这意味我们不需要频繁的调用操作,那么调度的成本就可以忽略不计。操作本身也包含一些优化的内部循环
2. 代码生成:为查询操作生成的代码都包含间接的调用方式

这些优化一般不用于普通的数据库,因为普通的查询调用这些没有任何的意义。但是也有例外,比如说MemSQL 使用代码生成来减少处理SQL查询时的延迟。(相比之下,分析型的DBMS需要优化吞吐量,而不是延迟)

需要注意的是:为了CPU的效率,查询语言必须是声明式的(SQL或MDX),或者至少是向量。查询应该是只包含隐式循环,允许优化。

回到顶部

二:特色

1.clickhouse是真正面向列的数据库管理系统

 1.1 在真正的列式存储的DBMS中,除了值是没有额外信息需要存储在一起的。这也意味着必须支持恒定长度值,从而避免将值的长度存储在值的旁边。例如,十亿个uint8类型的值在未压缩状态下应该消耗大约1GB,如果再大的话就会影响到CPU的使用。即使在未压缩的情况下,也应该紧凑的存储数据(没有任何的‘垃圾’),因为解压的速度(CPU的使用率)主要取决于需要解压的数据量

 1.2 有些系统是可以列式存储的,但是由于他针对于其他场景进行了优化,所以无法有效的处理分析查询。例如 HBase、BigTable、Cassandra 和 HyperTable。在这些系统中,每秒可以达到大约 10 万行的吞吐量,但没有每秒数亿行的吞吐量

 1.3 clickhouse是一个数据库管理系统,而不是单个的数据库。允许在运行的时候创建表和数据库、加载数据和运行查询而不需要重新加载配置和重启服务

2.数据压缩

一些面向列的DBMS不使用数据压缩,但是数据压缩在实现卓越性功能方面发挥了很大的作用。

  2.1 除了提供在消耗CPU和磁盘空间之间权衡取舍的高效通用的压缩编解码器之外,clickhouse还针对特定的类型的数据提供的专门的编解码器,这使得clickhouse能够和更多的小众数据库(如时间序列数据库)竞争并在性能上超过他们

3.数据的磁盘存储

  3.1 保持数据按主键物理存储可以低延迟(不到几十毫秒)提取特定值或值范围内的数据。一些面向列的DBMS(例如SAP HANA 和 Google PowerDrill)只能在RAM中工作,这种方法会比实时分析需要更大的硬件预算。

  3.2 clickhouse 设计用于常规硬盘驱动器,这意味着每GB数据存储的成本更低,但是如果可以的话,也可以充分利用 SSD 和额外的 RAM。

4.多核并行处理

大型查询自然并行化,占用当前服务器上可用的所有必要资源。

5.多台服务器上的分布式处理

上面提到的列式DBMS几乎都不支持分布式查询处理
在clickhouse中,数据可以驻留在不同的分片上,每一个分片都可以是一组可以容错的副本。所有的分片都可以用于并行运行查询,对用户透明。

6.对sql的支持

ClickHouse 支持基于 SQL的声明式查询语言,在许多情况下该语言与 ANSI SQL 标准相同。

支持的查询包括GROUP BY、ORDER BY、FROM 中的子查询、JOIN子句、IN运算符和标量子查询。

暂不支持相关(依赖)子查询和窗口函数

7.矢量计算引擎

数据不仅是按列存储,而且是通过向量(列的部分)进行处理,这样可以实现高CPU效率

8. 实时数据更新

clickhouse支持带有主键的表。为了快速的对主键范围执行查询,使用merge tree引擎对数据进行增量排序。因此,数据可以不断添加到表里面,而不需要锁

9.一级索引

通过主键对数据进行物理排序可以低延迟(不到几十毫秒)为其特定值或值范围提取数据

10. 二级索引

与其他的数据库管理系统不同,clickhouse的二级索引不指向特定的行或者是行范围。二级索引是让数据库提前标识不会匹配查询过滤条件并且根本不读取的行,因此也被称为是数据跳过索引

11. 适合在线查询

大多数的OLAP数据库管理系统并不针对亚秒级延迟的在线查询。在替代系统中,几十秒甚至几分钟的构建时间都是被允许和接受的,有时甚至需要离线准备(例如提醒:“稍后回来”这类)

在clickhouse中,低延迟意味着可以在加载用户界面页面的时候处理查询,而不需要提前准备结果,换句话说,就是在线。

12. 支持近似计算

clickhouse提供了多种方法来评估性能:
1. 用于近似计算中位数和分位数的聚合函数
2. 基于部分(样本)数据运行查询获取近似结果。在这种情况下,从磁盘中检索的数据也会按比例减少
3. 为有限数量的随机key进行聚合,而不是所有的key。在数据中key分布的特定条件下,这提供了相当准确的结果,同时也使用了较少的资源

13.自适应连接算法

clickhouse适应性的决定如果进行多个表的join,小表的话选择hash-join算法,如果有大表的话,就使用合并连接算法

14.数据的复制和完整性的支持

clickhouse使用主从异步复制,在数据写入到任何一个可用副本中后,其他的副本都会进行检索。系统在不同的副本上维护相同的数据。大部分的故障之后都是自动执行的,或者在复杂情况下是半自动执行的。

15.基于角色的访问控制

clickhouse使用sql查询来实现用户账户管理,并允许基于角色的访问控制配置,类似于 ANSI SQL 标准和流行的关系数据库管理系统中的配置。

16.缺点

16.1 不支持事务
16.2 不支持高效率低延迟的修改和删除已插入数据的功能。有批量删除和更新的功能来支持数据的清理和修改。例如,遵守GDPR
16.3. 稀疏的索引使得clickhouse对于通过键检索的点查询效率不高
回到顶部

三:表现

根据yandex的内部测试结果,在同类系统应用于同类场景的测试中表现了最佳性能(长查询的最大吞吐量和短查询的最低延迟

1. 单个大型查询的吞吐量

  吞吐量指的是每秒查询的行数或者是兆字节。如果把数据放在页面缓存中,一个不太复杂的查询在现代硬件上以单个服务器大约2-10GB/s的速度处理未压缩的数据,在最优的时候,可以达到30GB/s。如果数据没有放在页面缓存中,速度取决于磁盘子系统和磁盘的压缩率。例如,如果磁盘子系统以400M/s的速度读取数据,并且数据的压缩率为3,则速度预计在1.2G/s左右。如果要获得每秒读取行数,可以用每秒的字节数除以查询中使用的列的大小。例如,如果提取10字节的列,则速度预计在每秒100-2秒行。

对于分布式处理,处理速度是几乎呈线性增加,但前提是聚合和排序产生的行数不太大

2. 处理短查询的延迟

  如果查询使用了主键而且没有选择太多的其他列和行(数十万),那么当数据被放置在页面中时,可以预期数据延迟50毫秒(在最好的情况下为一位数的毫秒)。否则,延迟主要是由寻道次数来决定的。如果使用的是旋转磁盘驱动器,在未超载的系统中,延迟可以这个公式来估计一下:

寻道时间(10ms)* 查询的列数 * 数据量

3. 处理大量短查询的吞吐量

在相同的条件下,clickhouse可以在单个服务器上每秒处理上百个请求(在最佳的情况下可以处理上千个)。但是因为这种情况对于分析型的DBMS并不常见,因此最好每秒查询最多100次

4. 插入数据时候的性能

  建议一次插入最少1000行的数据包,或者每秒不超过一个请求。从制表符分隔的数据插入到mergetree的时候,插入速度是50到200MB/S。如果插入的行大小约为1KB,则速度在每秒 50,000 到 200,000 行之间。如果行很小,那么每秒行数的性能会更高(在banner system数据上,每秒500,000行,在Graphite 数据上,每秒1,000,000 行)。为了提高性能,可以并行执行多个 INSERT 查询,这会线性扩展。

回到顶部

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值