ClickHouse 基础介绍


什么是ClickHouse?

ClickHouse 是面向 OLAP 的分布式列式 DBMS.

在“正常”的面向行的DBMS中,数据按顺序进行存储:

5123456789123456789    1      Eurobasket - Greece - Bosnia and Herzegovina - example.com      1      2011-09-01 01:03:02    6274717  1294101174      11409  612345678912345678      0      33      6      http://www.example.com/basketball/team/123/match/456789.html http://www.example.com/basketball/team/123/match/987654.html      0      1366    768    32      10      3183      0      0      13      0\0    1      1      0      0                      2011142 -1      0              0      01321    613    660    2011-09-01 08:01:17    0      0      0      0      utf-8  1466    0      0      0      5678901234567890123              277789954      0      0      0      0      0

5234985259563631958    0      Consulting, Tax assessment, Accounting, Law      1      2011-09-01 01:03:02    6320881  2111222333      213    6458937489576391093    0      3      2      http://www.example.ru/        0      800    600      16      10      2      153.1  0      0      10      63      1      1      0      0                      2111678 000      0      588    368    240    2011-09-01 01:03:17    4      0      60310  0      windows-1251    1466    0      000              778899001      0      0      0      0      0

...

换句话说,与一行相关的所有值都被存储在一起。面向行的DBMS主要有MySQL,Postgres,MS SQL Server等等。

在面向列的DBMS中,数据存储如下:

WatchID:5385521489354350662    5385521490329509958    5385521489953706054    5385521490476781638    5385521490583269446    5385521490218868806    5385521491437850694  5385521491090174022      5385521490792669254    5385521490420695110    5385521491532181574    5385521491559694406    5385521491459625030    5385521492275175494  5385521492781318214      5385521492710027334    5385521492955615302    5385521493708759110    5385521494506434630    5385521493104611398

JavaEnable:1      0      1      0      0      0      1      0      1      1      1      1      1      1      0      1      0      0      1      1

Title:Yandex  Announcements - Investor Relations - Yandex    Yandex — Contact us — Moscow    Yandex — Mission        Ru      Yandex — History — History of Yandex    Yandex Financial Releases - Investor Relations - Yandex Yandex — Locations      Yandex Board of Directors - Corporate Governance - Yandex      Yandex — Technologies

GoodEvent:1      1      1      1      1      1      1      1      1      1      1      1      1      1      1      1      1      1      1      1

EventTime:2016-05-18 05:19:20    2016-05-18 08:10:20    2016-05-18 07:38:00    2016-05-18 01:13:08    2016-05-18 00:04:06    2016-05-18 04:21:30    2016-05-18 00:34:16    2016-05-18 07:35:49    2016-05-18 11:41:59    2016-05-18 01:13:32...

这些示例仅显示数据排列的顺序。不同列的值分开存储,同一列的数据一起存储。例如,面向列的DBMS:Vertica,Paraccel(Actian Matrix)(Amazon Redshift),Sybase IQ,Exasol,Infobright,InfiniDB,MonetDB(VectorWise)(Actian Vector),LucidDB,SAP HANA,Google Dremel,Google PowerDrill,Druid ,kdb +等。

存储数据的不同存储顺序更适合于不同的应用场景。数据访问场景指的是执行什么查询,多长时间查询,每种类型的查询读取多少数据 - 行,列和字节;写取和更新数据之间的关系;数据的大小以及它在本地的使用情况;是否使用交易处理,以及它们是如何隔离的;数据同步和逻辑完整性的要求;每类查询的延迟和吞吐量要求等等。

系统上的负载越高,场景化的系统定制就越重要,定制化就越具体。没有一个系统能够适用于截然不同的应用场景。如果一个系统可以适应多种场景,那么在高负载情况下,系统处理所有场景表现都会很差,或者仅其中一种场景表现良好。

对于OLAP(联机分析处理)方案,将会有如下几种应用场景:

- 绝大多数请求是以读为主。

- 数据以相当大的批次(> 1000行)进行更新,而不是单行更新;或者根本不更新。

- 数据被添加到数据库,基本不怎么修改。

- 对于读取,大量的数据从数据库中抽取出来,但只有列的一个子集。

- 表是“宽的”,这意味着它们包含大量的列。

- 查询相对较少(通常每台服务器数百个查询或更少)。

- 对于简单的查询,允许大约50 ms的延迟。

- 列值相当小 - 数字和短字符串(例如,每个URL 60个字节)。

- 处理单个查询时需要高吞吐量(每台服务器每秒高达数十亿行)。

- 无事务处理。

- 数据一致性要求低- 每个查询有一个大表,其他所有的表都是小表。

- 查询结果显著小于源数据。也就是说,数据被过滤或聚合。结果可以放在单个服务器的内存中。

很容易看出,OLAP方案与其他常见方案(如OLTP或Key-Value访问)有很大不同。所以,如果你想获得不错的表现,尝试使用OLTP或Key-Value DB来处理分析查询是没有意义的。例如,如果您尝试使用MongoDB或Elliptics进行分析,与OLAP数据库相比,您的性能会很差。

面向列的数据库更适合于OLAP方案(对于大多数查询,处理速度至少提高了100倍),原因如下:

1.对于I/O

1.1 对于分析查询,只需要读取少量的列。在面向列的数据库中,您只能读取所需的数据。例如,如果您需要100列中的5列,则I/O可能会减少20倍。

1.2 由于数据是以数据包的形式读取的,因此压缩比较容易。列中的数据也更容易压缩。这进一步减少了I/O量。

1.3 由于减少的I/O,更多的数据适合在系统缓存中。

例如,查询“统计每个广告平台的记录数量”需要读取一个“广告平台ID”列,其占用1个未压缩字节。如果大多数流量不是来自广告平台,那么您可以期望至少有10倍的压缩比。当使用快速压缩算法时,数据解压缩速度可以达到每秒至少几千兆字节的未压缩数据。换句话说,这个查询可以在一台服务器上以每秒大约几十亿行的速度处理。这个速度实际上是在实践中是容易实现的。

milovidov@████████.yandex.ru:~$ clickhouse-client

ClickHouse client version 0.0.52053.

Connecting to localhost:9000.

Connected to ClickHouse server version 0.0.52053.

:) SELECT CounterID, count() FROM hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20

SELECT

CounterID,

count()

FROM hits

GROUP BY CounterID

ORDER BY count() DESC

LIMIT 20

┌─CounterID─┬──count()─┐

│    114208 │ 56057344 │

│    115080 │ 51619590 │

│      3228 │ 44658301 │

│    38230 │ 42045932 │

│    145263 │ 42042158 │

│    91244 │ 38297270 │

│    154139 │ 26647572 │

│    150748 │ 24112755 │

│    242232 │ 21302571 │

│    338158 │ 13507087 │

│    62180 │ 12229491 │

│    82264 │ 12187441 │

│    232261 │ 12148031 │

│    146272 │ 11438516 │

│    168777 │ 11403636 │

│  4120072 │ 11227824 │

│  10938808 │ 10519739 │

│    74088 │  9047015 │

│    115079 │  8837972 │

│    337234 │  8205961 │

└───────────┴──────────┘

20 rows in set. Elapsed: 0.153 sec. Processed 1.00 billion rows, 4.00 GB (6.53 billion rows/s., 26.10 GB/s.)

:)

2.对于CPU

由于执行查询需要处理大量的行,因此它有助于为整个向量而不是单独的行指派所有操作,或者实现查询引擎,以便没有指派成本。如果你不这样做,任何半象限的磁盘子系统,查询解释器不可避免地中断CPU。将数据存储在列中并在可能的情况下按列处理是有意义的。

有两种方法可以做到这一点:

1.向量引擎。所有的操作都是为向量而写的,而不是单独的值。这意味着您不需要经常调用操作,调度成本可以忽略不计。操作代码包含一个优化的内部循环。

2.代码生成。为查询生成的代码具有所有的间接调用。

这不是在“普通”数据库中完成的,因为运行简单查询时没有意义。但是,也有例外。例如,MemSQL在处理SQL查询时使用代码生成来减少延迟。(为了比较,分析DBMS需要优化吞吐量,而不是延迟。)

请注意,为了提高CPU效率,查询语言必须是声明式的(SQL或MDX),或者至少是一个向量(J,K)。查询应该只包含隐式循环,以便优化。

ClickHouse的显著特性

1.真正的面向列的DBMS

2.数据高效压缩

3.磁盘存储的数据

4.多核并行处理

5.在多个服务器上分布式处理

6. SQL语法支持

7.向量化引擎

8.实时数据更新

9.索引

10.适合在线查询

11.支持近似预估计算

12.支持嵌套的数据结构

支持数组作为数据类型

13.支持限制查询复杂性以及配额

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

我们来看看其中的一些功能:

1.真正的面向列的DBMS

在一个真正的面向列的DBMS中,没有任何“垃圾”存储在值中。例如,必须支持定长数值,以避免在数值旁边存储长度“数字”。例如,十亿个UInt8类型的值实际上应该消耗大约1 GB的未压缩磁盘空间,否则这将强烈影响CPU的使用。由于解压缩的速度(CPU使用率)主要取决于未压缩的数据量,所以即使在未压缩的情况下,紧凑地存储数据(没有任何“垃圾”)也是非常重要的。

因为有些系统可以单独存储单独列的值,但由于其他场景的优化,无法有效处理分析查询。例如HBase,BigTable,Cassandra和HyperTable。在这些系统中,每秒钟可以获得大约十万行的吞吐量,但是每秒不会达到数亿行。

另外,ClickHouse是一个DBMS,而不是一个单一的数据库。ClickHouse允许在运行时创建表和数据库,加载数据和运行查询,而无需重新配置和重新启动服务器。

2.数据压缩

一些面向列的DBMS(InfiniDB CE和MonetDB)不使用数据压缩。但是,数据压缩确实提高了性能。

3.磁盘存储的数据

许多面向列的DBMS(SAP HANA和Google PowerDrill)只能在内存中工作。但即使在数千台服务器上,内存也太小,无法在Yandex.Metrica中存储所有浏览量和会话。

4.多核并行处理

多核多节点并行化大型查询。

5.在多个服务器上分布式处理

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

6. SQL支持

如果你熟悉标准的SQL,我们不能真正谈论SQL的支持。

NULL不支持。

所有的函数都有不同的名字。

JOIN支持。

子查询在FROM,IN,JOIN子句中被支持;

标量子查询支持。

关联子查询不支持。

7.向量化引擎

数据不仅按列存储,而且由矢量 - 列的部分进行处理。这使我们能够实现高CPU性能。

8.实时数据更新

ClickHouse支持主键表。为了快速执行对主键范围的查询,数据使用合并树(MergeTree)进行递增排序。由于这个原因,数据可以不断地添加到表中。添加数据时无锁处理。

9.索引

例如,带有主键可以在特定的时间范围内为特定客户端(Metrica计数器)抽取数据,并且延迟时间小于几十毫秒。

10.支持在线查询

这让我们使用该系统作为Web界面的后端。低延迟意味着可以无延迟实时地处理查询,而Yandex.Metrica界面页面正在加载(在线模式)。

11.支持近似计算

1.系统包含用于近似计算各种值,中位数和分位数的集合函数。

2.支持基于部分(样本)数据运行查询并获得近似结果。在这种情况下,从磁盘检索比例较少的数据。

3.支持为有限数量的随机密钥(而不是所有密钥)运行聚合。在数据中密钥分发的特定条件下,这提供了相对准确的结果,同时使用较少的资源。

12.数据复制和对数据完整性的支持。

使用异步多主复制。写入任何可用的副本后,数据将分发到所有剩余的副本。系统在不同的副本上保持相同的数据。数据在失败后自动恢复,或对复杂情况使用“按钮”。有关更多信息,请参阅“数据复制”一节。

ClickHouse目前未实现功能

1.无事务处理。

2.对于聚合,查询结果必须适合单个服务器上的内存。但是,查询的源数据量可能无限大。

3.缺乏全面的UPDATE / DELETE实现

Yandex.Metrica任务

我们需要根据点击和会话获取自定义报告,并使用用户设置的自定义。报告数据实时更新。查询必须立即运行(在线模式)。我们必须能够在任何时间段建立报告。必须计算复杂的汇总,例如唯一访客的数量。目前(2014年4月),Yandex.Metrica每天接收约120亿次事件(浏览量和鼠标点击)。所有这些事件都必须存储以建立自定义报告。单个查询可能需要几秒钟扫描数亿行,或者数百万行不超过几百毫秒。

汇总和非汇总数据

有一种流行的观点认为,为了有效地计算统计数据,您必须汇总数据,因为这会减少数据量。

但是数据聚合是一个非常有限的解决方案,原因如下:

- 您必须具有用户需要的预定义报告列表。用户不能进行自定义报告。

- 聚合大量密钥时,数据量不会减少,聚合无用。

- 对于大量的报告,聚合变化太多(组合爆炸)。

- 聚合高基数密钥(如URL)时,数据量不会减少太多(小于两倍)。出于这个原因,聚合的数据量可能会增长,而不是缩小。

- 用户不会查看我们为他们计算的所有报告。大部分的计算是无用的。

- 各种聚合可能违反数据的逻辑完整性。

如果我们不汇总任何内容并使用非汇总的数据,这实际上可能会减少计算量。

但是,通过汇总,相当一部分工作脱离了线索,相对冷静地完成了工作。相反,在线计算需要尽可能快地计算,因为用户正在等待结果。

Yandex.Metrica有一个专门的系统来汇总称为Metrage的数据,这个数据用于大多数报告。从2009年开始,Yandex.Metrica还使用专门的OLAP数据库来处理非聚合数据,称为OLAPServer,以前用于报告生成器。OLAPServer对非汇总数据运行良好,但是它有许多限制,不能根据需要用于所有报告。这些包括缺乏对数据类型(仅数字)的支持,以及无法实时增量更新数据(只能通过每天重写数据来完成)。OLAPServer不是一个DBMS,而是一个专门的DB。

为了消除OLAPServer的限制,并解决所有报告使用非汇总数据的问题,我们开发了ClickHouse DBMS。

用于Yandex.Metrica和其他Yandex服务

ClickHouse在Yandex.Metrica中用于多种用途。其主要任务是使用非聚合数据以在线模式构建报告。它使用374个服务器的集群,在数据库中存储超过8万亿行(超过四十亿个值)。压缩数据量不计复制和复制,大约是800TB。未压缩的数据量(以TSV格式)将大约为7PB。

ClickHouse还用于:

- 存储WebVisor数据。

- 处理中间数据。

- 使用Google Analytics构建全球报告。

- 运行查询以调试Metrica引擎。

- 分析来自API和用户界面的日志。

ClickHouse在其他Yandex服务中至少安装了十几个安装:搜索行业,市场,Direct,业务分析,移动开发,AdFox,个人服务等。

类似开源系统

有没有类似的ClickHouse可用。目前(2016年5月),没有任何可用的开源和免费系统具有上面列出的所有功能。但是,这些功能对于Yandex.Metrica是绝对必要的。

可能愚蠢的问题

1.为什么不使用map-reduce等系统?

像map-reduce这样的系统是分布式计算系统,其中使用分布式排序来执行缩减阶段。回顾这个方面,map-reduce与YAMR,HadoopYT等其他系统类似。

这些系统由于延迟而不适合在线查询,所以不能用于后台级别的网页界面。这样的系统也不适合实时更新。分布式排序并不是减少操作的最佳解决方案,如果操作的结果和所有中间结果都存在,就像通常在联机分析查询的情况下发生的那样,它们适合单个服务器的运行内存。在这种情况下,执行reduce操作的最佳方法是使用散列表。map-reduce任务的常用优化方法是在内存中使用散列表的组合操作(partial reduce)。这个优化是由用户手动完成的。分布式排序是简单的map-reduce作业长时间延迟的主要原因。

与map-reduce类似的系统可以在集群上运行任何代码。但是,对于OLAP,使用情况下的执行查询语言更为合适,因为经过调研它们可以更快地运行。例如,Hadoop有HivePig。还有其他:Cloudera Impala,Shark (depricated)andSpark SQLforSpark,Presto,Apache Drill.。然而,与专门系统的性能相比,这些任务的性能是非常不理想的,相对较高的延迟不允许将这些系统用作网络接口的后端。YT允许您存储单独的一组列。但YT不是一个真正的列式存储系统,因为系统没有固定长度的数据类型(所以你可以有效地存储一个数字而不是“垃圾”),而且没有向量化引擎。YT中的任务由流模式下的任意代码执行,因此不能被充分优化(每台服务器每秒高达数亿行)。在2014-2016年,YT将开发使用合并树,强类型值和类SQL语言支持的“动态表格排序”功能。动态排序的表不适用于OLAP任务,因为数据存储在行中。YT中的查询语言开发仍处于孵化阶段,不能专注于这个功能。YT开发人员正在考虑在OLTP和Key-Value方案中使用动态排序的表。

性能

根据内部测试结果,ClickHouse在可用于测试的同类系统中显示出最佳性能。这包括长查询的最高吞吐量和短查询的最低延迟。测试结果显示在此页面上

吞吐量为单个大型查询

吞吐量可以以每秒行数或兆字节每秒来衡量。如果数据放置在页面缓存中,则在现代硬件上处理不太复杂的查询,在单个服务器上以大约2-10 GB / s的未压缩数据的速度进行处理(对于最简单的情况,速度可能会达到30 GB / s)。如果数据不在页面缓存中,则速度取决于磁盘子系统和数据压缩率。例如,如果磁盘子系统允许以400 MB / s读取数据,并且数据压缩率为3,则速度将在1.2 GB / s左右。要获得每秒行数的速度,请将查询中使用的列的总大小除以每秒字节数。例如,如果提取10个字节的列,速度将在每秒大约1到2亿行。

处理速度对于分布式处理几乎线性地增加,但是只有在聚合或排序产生的行数不太大的情况下。

处理短的查询时延迟

如果一个查询使用一个主键,并且没有选择太多的行来处理(成千上万),并且不使用太多的列,我们可以预计到不到50毫秒的延迟(最好的情况下,单位为毫秒)if数据被放置在页面缓存中。否则,延迟是根据搜索的数量来计算的。如果使用旋转驱动器,对于没有过载的系统,延迟时间通过以下公式计算:查找时间(10 ms)*查询的列数*数据部分的数量。

处理大量的短查询时的吞吐量

在相同的条件下,ClickHouse可以在单个服务器上每秒处理几百个查询(在最好的情况下可以达到几千个)。由于这种情况对分析型DBMS并不常见,因此我们建议每秒最多可以查询100个查询。

数据插入性能

我们建议将数据插入至少1000行的数据包中,或者每秒不超过一个请求。从制表符分隔转储插入到MergeTree表时,插入速度将从50到200 MB / s。如果插入的行大小约为1Kb,速度将从每秒50,000到200,000行。如果行很小,则每秒的行数会更高(Yandex Banner System数据 - > 500,000行/秒,Graphite数据 - > 1,000,000行/秒)。为了提高性能,可以并行执行多个INSERT查询,并且性能会线性增加。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容