学习笔记(一)ClickHouse 概述(来自战斗民族的OLAP神器)
1、什么是ClickHouse
ClickHouse是俄罗斯的Yandex于2016年开源的列式存储数据库(DBMS),主要用于在线分析处理查询(OLAP),能够使用SQL查询实时生成分析数据报告。
2、ClickHouse的名称含义
ClickHouse的初始设计目的是为了服务于自己公司的一款名叫Yandex.Metrica的产品。Metrica是一款Web流量分析工具,基于前方探针采集行为数据,然后进行一系列的数据分析,类似数据仓库的OLAP分析。而在采集数据的过程中,一次页面click(点击),会产生一个event(事件)。至此,整个系统的逻辑就十分清晰了,那就是基于页面的点击事件流,面向数据仓库进行OLAP分析。所以ClickHouse的全称是Click Stream(点击流),Data WareHouse(数据仓库),简称ClickHouse。
3、什么是列式存储
在传统的行式数据库系统中,数据按如下顺序存储:
Row | name | height | age |
---|---|---|---|
#1 | 小明 | 180 | 18 |
#2 | 小红 | 168 | 16 |
#3 | 小黑 | 175 | 22 |
#n | … | … | … |
我们可以看到,处于同一行中的数据总是被物理的存储在一起。
常见的行式数据库系统有:MySQL、Postgres和MS SQL Server。
当采用行式存储的时候,数据在磁盘上的组织结构为:
小明 | 180 | 18 | 小红 | 168 | 16 | 小黑 | 175 | 22 |
---|
这样存储的好处是当你想查某个人所有的属性时,可以通过一次磁盘查找加顺序读取就可以。但是当想查所有人的身高时,需要不停的查找,或者全表扫描才行,遍历的很多数据都是不需要的。这种情况是比较浪费资源的
而在列式数据库系统中,数据按如下的顺序存储:
Row | #1 | #2 | #3 | # n |
---|---|---|---|---|
name | 小明 | 小红 | 小黑 | … |
height | 180 | 168 | 175 | … |
age | 18 | 16 | 22 | … |
我们可以看到,这个表只显示了数据的排列顺序。来自不同列的值被单独存储,来自同一列的数据被存储在一起。
常见的列式数据库有: Vertica、 Paraccel (Actian Matrix,Amazon Redshift)、 Sybase IQ、 Exasol、 Infobright、 InfiniDB、 MonetDB (VectorWise, Actian Vector)、 LucidDB、 SAP HANA、 Google Dremel、 Google PowerDrill、 Druid、 kdb+。
而采用列式存储时,数据在磁盘上的组织结构为:
小明 | 小红 | 小黑 | 180 | 168 | 175 | 18 | 16 | 22 |
---|
如果现在再想查所有人的年龄时,只需要把年龄那一列拿出来就可以了。
4、OLAP(Online Analytical Processing联机分析处理)场景的关键特征
- 绝大多数是读请求
- 数据以相当大的批次(> 1000行)更新,而不是单行更新;或者根本没有更新。
- 已添加到数据库的数据不能修改。
- 对于读取,从数据库中提取相当多的行,但只提取列的一小部分。
- 宽表,即每个表包含着大量的列
- 查询相对较少(通常每台服务器每秒查询数百次或更少)
- 对于简单查询,允许延迟大约50毫秒
- 列中的数据相对较小:数字和短字符串(例如,每个URL 60个字节)
- 处理单个查询时需要高吞吐量(每台服务器每秒可达数十亿行)
- 事务不是必须的
- 对数据一致性要求低
- 每个查询有一个大表。除了他以外,其他的都很小。
- 查询结果明显小于源数据。换句话说,数据经过过滤或聚合,因此结果适合于单个服务器的RAM中
我们可以观察到,OLAP场景与其他通常业务场景(例如,OLTP或K/V)有很大的不同, 因此想要使用OLTP或Key-Value数据库去高效的处理分析查询场景,并不是非常完美的适用方案。例如,使用OLAP数据库去处理分析请求通常要优于使用MongoDB或Redis去处理分析请求。
5、列式数据库更适合OLAP场景的原因
列式数据库更适合于OLAP场景(对于大多数查询而言,处理速度至少提高了100倍),下面我通过两个方面来介绍:
5.1、输入/输出
- 1、针对分析类查询,通常只需要读取表的一小部分列。在列式数据库中你可以只读取你需要的数据。例如,如果只需要读取100列中的5列,这将帮助你最少减少20倍的I/O消耗。
- 2、由于数据总是打包成批量读取的,所以压缩是非常容易的。同时数据按列分别存储这也更容易压缩。这进一步降低了I/O的体积。
- 3、由于I/O的降低,这将帮助更多的数据被系统缓存。
例如,查询«统计每个广告平台的记录数量»需要读取«广告平台ID»这一列,它在未压缩的情况下需要1个字节进行存储。如果大部分流量不是来自广告平台,那么这一列至少可以以十倍的压缩率被压缩。当采用快速压缩算法,它的解压速度最少在十亿字节(未压缩数据)每秒。换句话说,这个查询可以在单个服务器上以每秒大约几十亿行的速度进行处理。这实际上是当前实现的速度。
5.2、CPU
由于执行一个查询需要处理大量的行,因此在整个向量上执行所有操作将比在每一行上执行所有操作更加高效。同时这将有助于实现一个几乎没有调用成本的查询引擎。如果你不这样做,使用任何一个机械硬盘,查询引擎都不可避免的停止CPU进行等待。所以,在数据按列存储并且按列执行是很有意义的。
有两种方法可以做到这一点:
-
1、向量引擎:所有的操作都是为向量而不是为单个值编写的。这意味着多个操作之间的不再需要频繁的调用,并且调用的成本基本可以忽略不计。操作代码包含一个优化的内部循环。
-
2、代码生成:生成一段代码,包含查询中的所有操作。
这是不应该在一个通用数据库中实现的,因为这在运行简单查询时是没有意义的。但是也有例外,例如,MemSQL使用代码生成来减少处理SQL查询的延迟(只是为了比较,分析型数据库通常需要优化的是吞吐而不是延迟)。
请注意,为了提高CPU效率,查询语言必须是声明型的(SQL或MDX), 或者至少一个向量(J,K)。 查询应该只包含隐式循环,允许进行优化。
6、ClickHouse的发展历程
ClickHouse背后的研发团队是来自俄罗斯的Yandex公司。这是一家俄罗斯本土的互联网企业,于2011年在纳斯达克上市,它的核心产品是搜索引擎。根据最新的数据显示,Yandex占据了本国47%以上的搜索市场,是现今世界上最大的俄语搜索引擎。Google是它的直接竞争对手。
众所周知,在线搜索引擎的营收来源非常依赖流量和在线广告业务。所以,通常搜索引擎公司为了更好地帮助自身及用户分析网络流量,都会推出自家的在线流量分析产品,例如Google的Google Analytics、百度的百度统计。Yandex也不例外,Yandex.Metrica就是这样一款用于在线流量分析的产品(https://metrica.yandex.com)。
ClickHouse就是在这样的产品背景下诞生的,伴随着Yandex。Metrica业务的发展,其底层架构历经四个阶段,一步步最终形成大家现在所看到的ClickHouse。
发展历程 | OLAP架构 | Yandex.Metrica产品形态 |
---|---|---|
顺理成章的MySQL时期 | ROLAP | 固定报告 |
另辟蹊径的Metrage时期 | MOLAP | 固定报告 |
自我突破的OLAPServer时期 | HOLAP(Metrage+OLAPServer) | 自助报告 |
水到渠成的ClickHouse时代 | ROLAP | 自主报告 |
7、ClickHouse适用的场景
因为ClickHouse在诞生之初是为了服务Yandex自家的Web流量分析产品Yandex.Metrica,所以在存储数据超过20万亿行的情况下,ClickHouse做到了90%的查询都能够在1秒内返回的惊人之举!随后,ClickHouse进一步被应用到Yandex内部大大小小数十个其他的分析场景中。可以说,ClickHouse具备了人们对一款高性能OLAP数据库的美好向往,所以它基本能够胜任各种数据分析类的场景,并且随着数据体量的增大,它的优势也会变得越为明显。
ClickHouse非常适用于商业智能领域(也就是我们所说的BI领域),除此之外,它也能够被广泛应用于广告流量、Web、App流量、电信、金融、电子商务、信息安全、网络游戏、物联网等众多领域。
8、ClickHouse不适用的场景
ClickHouse作为一款高性能OLAP数据库,虽然足够优秀,但也不是万能的。我们不应该把它用于任何OLTP事务性操作的场景,因为它有以下几点不足。
- 不支持事务
- 不擅长根据主键按行粒度进行查询(虽然支持),故不应该把ClickHouse当作Key-Value数据库使用。
- 不擅长按行删除数据(虽然支持)。
这些弱点并不能视为ClickHouse的缺点,事实上其他同类的高性能的OLAP数据库同样也不擅长上述的这些方面。因为对于一款OLAP数据库而言,上述这些能力并不是重点,只能说这是为了极致查询性能所做的权衡。
9、ClickHouse的性能对比
9.1、多表关联查询对比测试
以下是多表关联测试结果,数据如下:
我们可以看到,presto、impala和hawq查询时间快于SparkSql和ClickHouse,性能约是SparkSql的2-3倍,其中尤其以Presto和Impala性能要好一些。greenplum在多表查询上也有不错的表现;ClickHouse对于多表join效果相比较于Presto、Impala、HAWQ不是很好,并且很多复杂语法支持的不够好,可见并不是为关联分析而设置;而hive无疑是所有组件中耗时最多的,其中部分语句查询时间超出1h的总时间按1h计算。
下面是通过图形展示来更加直观比较各组件性能。由于hive与其他相差太大,在图中不作比较。
从上面的分析结果可以看出,presto、Impala以及hawq在多表查询方面体现出了优势,虽说presto和Impala在多表查询方面的性能差别不大,但是在查询过程中却发现Impala的一些局限性,并尽量避开这些局限问题进行测试。Impala不支持的地方,例如:不支持update、delete*作,不支持Date数据类型,不支持ORC文件格式等等,而presto则基本没有这些局限问题。
9.2、单表查询对比测试
以下是单表关联测试结果,数据如下:
从结果中我们发现,对于单表测试ClickHouse要比其余几种组件查询速度表现突出,测试性能约是其余四种的3-6倍。而Presto相比于HAWQ、Impala、SparkSql、GreenPlum在单表*作方面性能也稍好些。
下面通过图来直观比较:
从图像上更加清楚地显示出五种组件在单表测试方面性能的差距,Clickhouse在性能方面体现出了足够的优势,在单大表查询方面比其余组件性能都要好;Impala和Presto相比较,在sql_01-sql_05这5条语句是简单的一些求和求平均的单表作方面,Presto的性能要比Impala好很多,而sql_06-sql_09一些复杂点的多个列的单表作,Impala的性能要比Presto好一些,这也反映出Presto更加适合一些简单的数据量大的聚合作,而Impala适合一些复杂的聚合作。
最后我们发现HAWQ、GreenPlum在单表聚合作方面性能不如其余四种组件,测试时间要大大超过它们,当然也不排除测试环境的影响,但是测试结果表明,HAWQ、GreenPlum不适合单表的复杂聚合作,更适合多表的聚合*作。
更多性能压测可以参考官网:http://www.clickhouse.com.cn/topic/5c453371389ad55f127768ea
10、有谁在使用ClickHouse
除了Yandex自己以外,ClickHouse还被众多商业公司或研究组织成功地运用到了它们的生产环境。欧洲核子研究中心(CERN)将它用于保存强对撞机实验后记录下的数十亿事件的测量数据,并成功将先前查找数据的时间由几个小时缩短到几秒。著名的CDN服务厂商CloudFlare将ClickHouse用于Http的流量分析。国内的今日头条、阿里、腾讯和新浪等一众互联网公司对ClickHouse也都有涉猎。