【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非常适合大宽表,也就是字段(纬度)非常多,数据量非常大的实时统计分析查询

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

相关推荐
智慧化智能化数字化方案18 分钟前
华为IPD流程管理体系L1至L5最佳实践-解读
大数据·华为
XINGTECODE43 分钟前
海盗王集成网关和商城服务端功能golang版
开发语言·后端·golang
程序猿进阶1 小时前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
FIN技术铺1 小时前
Spring Boot框架Starter组件整理
java·spring boot·后端
凡人的AI工具箱1 小时前
15分钟学 Go 第 60 天 :综合项目展示 - 构建微服务电商平台(完整示例25000字)
开发语言·后端·微服务·架构·golang
先天牛马圣体1 小时前
如何提升大型AI模型的智能水平
后端
java亮小白19971 小时前
Spring循环依赖如何解决的?
java·后端·spring
PersistJiao1 小时前
在 Spark RDD 中,sortBy 和 top 算子的各自适用场景
大数据·spark·top·sortby
2301_811274312 小时前
大数据基于Spring Boot的化妆品推荐系统的设计与实现
大数据·spring boot·后端
Yz98762 小时前
hive的存储格式
大数据·数据库·数据仓库·hive·hadoop·数据库开发