大家好,我是老兵。
数据去重
是大数据面试
当中经常会遇到的一个问题,它在面试以不同的方式提出。这里我例举几个常见问题。
-
限制内存大小要求去重
-
不同组件的去重实现
-
生产环境中实时大规模去重实践
上述的每一个问题都很好,单拎出来讲能以万字论。很多博主分享过这些内容,也不乏深度好文,有兴趣的看官可以留言找我分享文字链接,我就不班门弄斧,反复赘述了。
很多小伙伴在工作当中顾此失彼,完全忽视对sql底层
原理的分析,缺乏对底层知识的深入理解,因此很容易出现在面试时候被面试官问倒的尴尬局面。
今天我另辟蹊径,以hive引擎
为切入点,带大家探索在sql中大数据领域是如何去重的,借以引入一个新的计算引擎Clickhouse
。为什么要讲Clickhouse,读到后面相信大家会有自己的答案。
1. Hive去重
先以两个简单的sql启发我们的话题
select count(distinct id)
from order_combine;
select count(id)
from (
select id
from
order_combine
group by id
) t;
从执行日志当中我们可以看到二者的差异(只摘取关键部分)
# distinct
+ Stage-Stage-1:
Map: 396 Reduce: 1 ...
Time taken: 200.192 seconds
#group by
Stage-Stage-1: Map: 396 Reduce: 457 ...
Time taken: 87.191 seconds
二者关键的区别就在于使用distinct
会将id都shuffle到一个reducer里面,当数据量大了之后,不可避免的就会出现数据倾斜。
group by
在reducer阶段会将数据分布到多台机器上执行,在处理大数据时在执行性能上自然相比于distinct提高很多。
其实一般面试中,这种程度的回答会考量到MapReduce阶段数据的分区分组以及流向是否真正理解。
但是我们今天的主题主要是去重,写到这里就此打住很显然是不行的。
让我们换个角度思考一下
针对一个常用的order表去重就需要消耗87s
的时间,如果我们在日常工作中经常需要针对order表进行数据分析,可想而知,这样的速度是难以忍受的。
老兵也常常就遇到这样的问题,两年前公司就开始慢慢的用Spark
引擎替换Hive
,在速度上加快了很多,但是随着业务的发展,Spark
的实时查询能力还是显得有些力不从心,在去重方面的性能自然不必多说。
能不能找到一个方案让去重更快?
说到这里,ClickHouse
就呼之欲出了。接下来会详细介绍ClickHouse的主要原理以及他是如何去重的。
2. Clickhouse
ClickHouse
是 Yandex(俄罗斯最大的搜索引擎)开源的一个用于实时数据分析的基于列存储的数据库。
ClickHouse的性能超过了目前市场上可比的面向列的 DBMS,每秒钟每台服务器每秒处理数亿
至十亿
多行和数十千兆
字节的数据。
2.1 MergeTree存储结构
说得这么神乎其神,很多人可能会有疑问,ClickHouse真的有这么强大吗?
要了解Clickhouse的强大,首先要提的绝对是合并树MergeTree
引擎,因为Clickhouse的核心原理就是依赖于它,而所有的其他引擎都是基于它来实现的。
我将以MergeTree为切入点揭开ClickHouse神秘面纱。
从图中可以看出,一张数据表的完整物理结构分为3个层级,依次是数据表目录
、分区目录
及各分区下具体的数据文件
。接下来逐一介绍它们的作用。
-
partition
:分区目录,属于相同分区的数据最终会被合并到同一个分区目录,而不同分区的数据,永远不会被合并到一起。 -
checksums.txt
:校验文件,使用二进制格式存储。它保存了各类文件(primary.idx、count.txt等)的size