【ClickHouse】初识

本文为稀土掘金技术社区首发签约文章,30天内禁止转载,30天后未获授权禁止转载,侵权必究!

在存储数据超过20万亿 行的情况下,ClickHouse做到了90 %的查询都能够在1秒内返回的惊人之举 ------《ClickHouse原理解析与应用实践》

怎么个事儿

不知道大家有没有听过ClickHouse,反正我在第一次听到ClickHouse之前都是没有听过ClickHouse

因为我现在的公司有用ClickHouse来实现一些业务场景,但我却没听说过,所以特地问了几个前同事看看他们是不是对ClickHouse有所了解

同事A:那是个啥?

同事B:刷到过,但是没用过。

同事C:你要请我吃饭?

他们纷纷表示没有听过或者听过但不熟或者。。。要请我吃饭

很好,ClickHouse你已经成功的引起了我的注意,毕竟有人说要请我吃饭(dog

定位

ClickHouse是一款OLAP数据库

什么是OLAP?

On-Line Analysis Processing,联机分析处理,比如Hive

与之对应还有一种OLTP

On-Line Transaction Processing,联机事务处理,比如MySQL

简而言之,ClickHouse就是一款大数据分析数据库

适用的场景

ClickHouse非常适合大宽表,就是字段较多的表

不同纬度的数据存储在一张表中更方便做纬度分析

分析(营销)

借助用户的行为画像,对用户进行精准的内容投放

假设我们开了一家淘宝店铺,最近这段时间我们的产品A会进行打折促销

同时我们可以认为之前复购过产品A的顾客有很大的可能会再次回购

所以我们可以圈定产品A购买次数 > 1的顾客

给他们发送短信或推送消息,告诉他们之前购买过的产品A最近有活动

当然实际的行为分析字段非常多而且营销条件也会更复杂

为什么

所以为什么ClickHouse适合这种分析场景呢

当然是因为快啊!

假设我们有1亿个客户,有100个可以用于用户行为筛选的字段

你:MySQL大哥,能不能。。。

MySQL:滚!

列式存储

和我们熟悉的按行存储的MySQL不同,ClickHouse是按列存储的

所以ClickHouse可以按需读取数据

我们继续来开淘宝店

我们的客户行为表有非常多的字段,比如下表(非真实字段):

客户号 新客户 店铺点击次数 总花费金额 产品A购买次数 点击产品A详情页面次数 ...共100个字段
1 123 1378.24 3 27 ...
2 56 2567.98 5 5 ...
... ... ... ... ... ... ...
100000 3 0.00 0 1 ...

现在我们要开始营销了

sql 复制代码
select 客户号 from 客户行为表 where 产品A购买次数 > 1

如果用MySQL,因为是按行存储,所以每一行的所有数据都要读取出来作判断

也就是10w行 * 100个字段

如果用ClickHouse,因为是按列存储,而我们的SQL中只需要用到两列,所以只需要读取两列即可

也就是10w行 * 2个字段

大量无用数据的磁盘IO被优化掉了,毕竟磁盘IO的效率真的非常低

数据压缩

除了优化无用数据的磁盘IO,ClickHouse还使用了数据压缩来优化有用数据的磁盘IO

由于同一列数据的数据类型一致,所以数据更容易压缩,压缩效率也更高

一般会以8192 行数据作为一(最小处理单元)进行压缩和解压

一条一条数据压缩解压性能很低,毕竟压缩和解压也需要时间,频繁的压缩解压反而不如不压缩

从书中了解到,ClickHouse一般能达到6-8:1的压缩比,也就是6G-8G的数据压缩之后就变成了1G

让我们浅浅估算一下我们的营销SQL

假设MySQLClickHouse都要扫描10w行数据,每列数据的数据量一样,压缩率也一样

光是磁盘IO的效率就能至少提升100列/2列 * 6/1(压缩)= 300

向量计算

你以为到这儿就结束了?

还有一项降维打击的优化策略,那就是向量计算

向量计算 需要借助CPUSIMD技术

Single Instruction Multiple Data,单指令多数据流

使用单条指令对多个数据进行并行操作

一般情况下,我们通过循环来处理多条数据(假设有4条数据)

js 复制代码
for (int i = 0;i < 4; i++) {
    c[i] = cmd(a[i], b[i]);
}

这段代码最终执行的时候就会变成下面这样,实际上会执行4次

js 复制代码
c[0] = cmd(a[0], b[0]);
c[1] = cmd(a[1], b[1]);
c[2] = cmd(a[2], b[2]);
c[3] = cmd(a[3], b[3]);

向量计算则是这样的

js 复制代码
c[] = cmd(a[], b[]);

举一个更具体的例子就是(以两数相加为例)

js 复制代码
[3, 5, 7, 9] = [1, 2, 3, 4] + [2, 3, 4, 5]

四条数据只需要执行一次相加指令

对于不同的数据类型(8位,16位,32位,64位),SIMD可以同时处理2-16个数据

所以对于列式存储的ClickHouse来说,可以非常方便的使用向量计算 提升2-16倍(粗略计算)的计算效率

位图计算

顺带提一句,ClickHouse是支持位图存储和计算的

所以在部分场景的性能非常高,比如一些需要用到IN的场景

IN一百万的过滤和用位图判断是否存在,这两者的性能差距还是很大的

位图相关的内容会在后续的文章中做单独的说明

不适用的场景

单条数据

因为列式存储 而且每次处理8192行数据

为了一条数据读取8192条数据怎么想都不划算吧

而且查询的列越多越不划算,列式存储反而变成了弊端

不如换成行式存储的数据库

不支持事务

这个应该也好理解

如果要支持一条数据的事务能力,就需要读取每一列的数据,相比单条数据更是雪上加霜

再加上需要考虑并发竞争,性能必定直线下降

所以需要事务的场景还是交给OLTP数据库吧

兼容标准SQL

ClickHouse的语法和我们常用的SQL基本没有太大的差别

如果熟悉MySQL的话,完全不会有任何问题(当然还是有一些细小的差别)

并不会像ES那样有自己的一套DSL需要单独学习

所以把一些大表迁移到ClickHouse之后查询SQL也是基本兼容的,迁移后重新开发的成本也不高

小结

ClickHouse非常适合大宽表,也就是字段(纬度)非常多,数据量非常大的实时统计分析查询

但是不适合事务场景以及单条(精准)查询

相关推荐
攸攸太上14 分钟前
Spring Gateway学习
java·后端·学习·spring·微服务·gateway
2301_7869643619 分钟前
3、练习常用的HBase Shell命令+HBase 常用的Java API 及应用实例
java·大数据·数据库·分布式·hbase
罗曼蒂克在消亡30 分钟前
graphql--快速了解graphql特点
后端·graphql
潘多编程33 分钟前
Spring Boot与GraphQL:现代化API设计
spring boot·后端·graphql
matlabgoodboy38 分钟前
“图像识别技术:重塑生活与工作的未来”
大数据·人工智能·生活
大神薯条老师1 小时前
Python从入门到高手4.3节-掌握跳转控制语句
后端·爬虫·python·深度学习·机器学习·数据分析
happycao1232 小时前
Flink 03 | 数据流基本操作
大数据·flink
2401_857622662 小时前
Spring Boot新闻推荐系统:性能优化策略
java·spring boot·后端
Neituijunsir2 小时前
2024.09.22 校招 实习 内推 面经
大数据·人工智能·算法·面试·自动驾驶·汽车·求职招聘
AskHarries2 小时前
如何优雅的处理NPE问题?
java·spring boot·后端