这是《漫谈分布式系统》系列的第 23 篇,预计会写 30 篇左右。扫描文末二维码,关注公众号,听我娓娓道来。也欢迎转发朋友圈分享给更多人。
前面几篇讲 SQL 的文章,大量提到了 Hive。作为 SQL on Hadoop 的初代领军者,Hive 大大降低了使用分布式系统处理海量数据的学习和使用成本,同时提供了一些性能优化的手段。
但这并不是 Hive 的全部,它还有一个甚至更加重要的功能和职责,也就是我们这篇要重点聊的,作为数据库,甚至是数据仓库的核心。
作为数据库自不用多说,虽然 SQL 也能用来分析自描述性的文件,但更多还是用来操作数据库。
从上面这张 Hive 的架构图也很容易看出,Hive 提供了完整的元数据存储和管理功能,使得我们可以像操作传统关系数据库那样处理数据,并且得到的是一个分布式的数据库,不用再引入各种中间件去做分库分表。
常规的 DDL、DML 操作,库、表、分区、桶等不同层次的数据规划等等,大家都非常熟悉了,这里不再赘述。
在数据量膨胀、业务复杂度升级、参与人员扩张后,单纯技术上的数据库已经不再能满足人们的需求。
大量的数据冗余和作业冗余产生,大量的业务歧义无法统一,大量的数据孤岛丛生。
数据的规范化变得迫在眉睫。过去几十年,在关系数据库领域,已经从实践中总结出了一套数据仓库的方法论,来指导企业数据的建设。
和前面文章提到的各种 Join 算法一样,在分布式的场景下,只要依葫芦画瓢,就能用来建设分布式数据仓库。
而基于 Hive 提供的分布式数据库能力去建设数据仓库,也成了大数据领域的主流。
即使是分布式数仓,在技术上也并没有体现出多少和传统数仓的区别,分布式更多体现在更底层。不过我们还是简单梳理下数仓的要点。
最经典的数据仓库模型有两种:
数仓大师 Bill Immon 提出的范式模型(Normalized Model),
数仓大师 Ralph Kimball 提出的维度模型(Dimensional Model)。
顾名思义,两种模型各有特点:
范式模型以关系为核心来建立数仓,严格遵守 ER 模型和第三范式(3NF),需要更强的整体统筹能力,是一种自上而下的方法,
而维度模型,以业务为出发点,通过各自的事实表和统一的维度表,组合起来建设数仓,是一种自下而上的方法。
这两种模型没有绝对的优劣,对不同的业务场景而言,会有不同的选择。甚至还诞生了所谓混合模型(Hybrid Model),综合了各个模型的特点。
对典型的互联网业务而言,更加追求业务上的敏捷度,以适应市场的快速变化,因此,维度模型得到了更加广泛的应用。
而根据维度组合方式的不同,维度模型又分为两种:
星型模型,所有维表都直接连接事实表,
雪花模型,有些维表通过其他维表连接事实表。
这两种方式,望文即能生义,当维度复杂、体现出层次时,可以考虑雪花模型,否则,星型模型足以。
在数仓的实践中,为了更好的整理和使用数据,又会做横向和纵向切分:
横向划域,切分的维度是业务,根据不同的业务,也可以进一步细分为主题、子主题等,
纵向分层,切分的维度是数据流向或者说聚合粒度,目的是空间换时间,固化下标准的计算结果。
横向划域的方法,没有定论,全看各家业务,复杂的多分细分,简单的就怎么简单怎么来。
纵向分层的方法,各有实践,但大体有固定套路。以数据中台的首倡阿里巴巴为例,可以看到,数据流向和聚合粒度是比较清晰的。
在数仓架构设计完后,要保证顺利落地,还需要在流程规范和配套工具有足够的限制和支持。
流程上,需要明确设计-审核-上线的阶段,尽早发现处理问题,避免污染,
规范上,需要定义清楚一些指导性的实践要求,如词根定义、主题定义、表命名规范、指标命名规范等,
配套工具方面,最好有专门的系统固化流程规范,否则很难有执行力。
按照上述的模型和规范,就能得到一个基于 Hive 的分布式数据仓库。
上面提到的数据仓库,都是所谓离线数据仓库,需要经过漫长的数据处理流程,才能拿到更新的数据。
对于一些对实时性要求比较高的场景,就显得不够用了。这个时候就需要实时/流式数仓了。
流处理是个很宽泛的话题,我们后面会专门讲。这里只简单介绍下和数仓有关的部分。
最典型的实时数仓,可以考虑依托 Kafka 这样的消息中间件 + 以 Flink 为代表的流处理引擎去做。和离线数仓的主要区别,是离线的表换成了实时的 topic,这样就能依托消息中间件的能力,提供更加及时的数据更新。
而离线数仓中的层次划分、维度定义、指标定义,以及构建和审核流程等,都可以沿用。
当然,这样带来的就是两套不同的技术架构,也就是数仓这个场景下的所谓 lambda 架构,开发和维护成本是 double 的。关于 lambda 架构,后面我们也会专门讲,先不展开。
不过这里可以提一个折中的改进思路,考虑在计算引擎和 ETL 阶段,以流式数仓为基础,在数据存储上做系统级别的批和流的双写,再结合统一的元数据,就能同时提供流和批的数仓。这块又涉及所谓「流批一体」,我们也放在后续的文章中讨论。
当然,这只是一个思路,具体做的时候仍然有许多问题要解决。
而另一方面,Kafka 虽然也可以通过设置偏移量来访问旧的历史数据,但由于设计上的取舍,其实并不擅长。
所以上面提到的 Kafka topic 替换 Hive table 来建设实时数仓的方式,更适合实时响应类的场景,比如实时 ETL、实时报表等。
而对于需要大量频繁处理历史数据的场景,比如探索类的 ad-hoc 查询,或者明细数据类的查询,就并不适合了。
对于这种场景,可以考虑把 Kafka topic 的数据实时写入到诸如 Clickhouse、Druid 这样的分布式 OLAP 数据库。
大致示意图如下:
另一个值得一提的趋势,是云原生的数据仓库逐渐流行起来。像 Snowflake 这样的公司,甚至都做到上市了,体量还不小。
不难看出,数据仓库为了更好的使用数据,在前期建设阶段会有很多规范和限制。
换句话说,是为了读友好而加重了写的负担。
这就限制了数据仓库的适用场景,比如有些探索性的业务,没法事先定义好数据模型,也不愿意早期就投入大量人力和时间成本去做规范化的数仓建设。
可谓「天下苦数仓久矣」,于是出现了数据湖的概念,也涌现了一些技术和实践。这个系列的提纲里也已经计划好了,后面会专门写一篇介绍数据湖的文章。
在这里,我们需要知道的是,数仓通过规范建设,可以很好用。但数仓也不是银弹,不要指望能解决所有问题。
这篇文章就写到这里,基于 Hive 的离线数仓,和基于 Kafka+Flink 的实时数仓,使得我们很容易就能给数仓插上分布式的翅膀,不用再为存储和计算能力操心。
原创不易
关注/分享/赞赏
给我坚持的动力