跑在文件系统上的数据仓库

封闭的传统数据仓库

我们知道数据仓库是晚于数据库出现的,当 TP 数据库无法满足日益增长的数据分析需要时,人们便通过架设单独的数据库把 AP 业务独立出来就形成了数据仓库(逻辑概念)。后续出现了专门的数据仓库产品为 AP 业务服务,由于数据仓库在技术上本身也是个数据库,因此继承了数据库的诸多特性,比如元数据和数据约束,这使得从 TP 数据库过渡到 AP 数据仓库较为平滑。

但是,TP 和 AP 的目标并不一致,有些 TP 业务中有意义的特性在 AP 业务中并无好处,甚至还有很多坏处,比如封闭性。

所谓封闭性,是指要被数据库计算和处理的数据,必须事先装入数据库之内,由数据库统一管理,数据在数据库内部还是外部是很明确的。

那么封闭性会带来什么问题呢?

一个典型的现象就是 ETL 经常被做成 ELT 甚至 LET。ETL 中的 E 和 T 这两步事实上也是某种计算,如果计算能力被封闭到数据库之内的话,我们就只能先把数据装入库中才能计算了,因为无法计算库外的数据。然而 ETL 过程中的原始数据常常并不在库内,或者至少不在数据仓库中,也可能存在于多个数据库。总之,都需要先做个同库动作之后才能再计算,费时费力。

当代应用中多样性的数据源越来越普遍,经常有来自外部服务的数据。如果为了计算这些数据而先把它们转入数据库中,也是非常累赘的。临时转入的效率很低(因为数据库的 IO 成本高),很可能跟不上访问需求,而定时批量转入又很难获得最新的数据,同样影响计算结果的实时性。

封闭性的坏处还不止于此。

封闭性还会导致实时数据使用困难。当代应用的数据源种类很多,每种数据源都在特定场景下单独发挥作用,但对于 OLAP 业务经常要统计全局数据,这就涉及跨多数据源计算。如果每次都要先把其他数据源数据导入再使用很低效,还会导致无法使用实时数据,因为这要求能够跨数据源进行实时计算,但当前数据仓库却没有这个能力。

封闭性还有一个表现是对数据有约束,数据符合要求才能进来,这在一定程度能保证数据质量,但从另一面也导致有些不太合规的数据很难进来参与计算,这对于分析某些原始数据并无好处,不利于数据湖的建设。

相关的另一个特征是整体性,库内的数据库逻辑上是的整体,不可拆分。如果数据种类(数据表)太多时,又会造成元数据信息臃肿、运维管理困难和耦合性高等问题。实际业务中的数据仓库中表数量通常也真地都很多,有的会高达几万张表。为什么会出现这种情况?

这些表大部分是为了查询效率采用空间换时间的办法后事先加工出来的中间表。这种表一旦产生就很难删除(表被共用,删除会影响其他部分),最后越积越多达到成千上万。

中间表要消耗数据库计算资源定时更新数据,中间表越来越多,资源消耗就越来越大,其中很多表不用还删不掉白白浪费资源。存储和计算压力会让数据仓库面临扩容压力,导致成本升高。

表被多个应用共用就会造成应用间的紧耦合问题,这与中间表越来越多互为因果。耦合性太高会导致应用扩展困难,运维也十分不便。

分库分表也是数据量较大的数据仓库中十分常见的手段,大量的分表会进一步增加表的数量,分库则面临跨库计算的问题。

我们知道数据库的结构是线性的,表的数量太多就会导致难以管理,运维复杂。虽然数据库有模式的辅助,但最多也只能分成两层,与很多树状结构(如文件系统)的方便程度不可同日而语。

单就“数据仓库”的名字来看,给人的感觉作用主要是存储,但其实数据仓库主要的任务是计算,数据光存起来并没有意义,只有使用才能发挥价值。数据库的封闭性,相当于城市有个城墙,数据要进出也必须通过数据库的城门,过程中还要进行一些检查。对于 OLTP 业务,为了保证一致性,这些检查是有必要的,但也会损失数据库的 IO 效率,而这对于 OLAP 这类以计算为主的业务几乎没有意义,只是浪费时间浪费资源而已。现代城市(数据仓库)并不需要城墙。

在文件系统上构建数据仓库

如果我们采用开放的存储体系来构建数据仓库,比如直接采用文件来存储,上述很多问题都能有效地解决。

文件使用没有任何约束,没有了“城墙”的限制,什么样数据都能进来(甚至就没有“进来”这样概念),这样更能保持“原汁原味”也更符合数据湖的初衷。文件的使用更加灵活高效,采用树状目录的结构可以分类管理数据表(文件),这样既不会造成应用间的耦合性问题,管理和使用也很方便,表数量再多也不怕。

同时,文件存储的成本也很低廉,低成本是大数据建设不可忽略的关键因素。

当然,文件相对数据库来说改写能力较弱,但数据仓库中历史数据通常不再改变,牺牲代价较小的数据更新(更新意味着重写)能力可以换来更高的计算效率(采用压缩编码、列存)通常是值得的,基于文件的计算性能会更高,而且文件系统相对数据库也具备更高的 IO 性能。

使用文件的另外一个好处是容易实现存算分离。原来数据库经常是打穿文件系统直接访问硬盘的,要改造成存算分离的机制,使用网络文件系统以及云上的对象存储时,就要从底层重构,这是个复杂的任务,也就会带来不少实施风险。使用文件做存储天然支持存算分离(专业存储保证数据安全性,专业计算引擎保证性能),上云也更容易。

文件存储的确好处多多,但却缺失一个关键能力:计算。如前所述,数据存起来是要使用的,文件存储什么都好,但如果没有计算能力,那对于数据仓库的目标来讲就还是个零。

文件型数据仓库 esProc SPL

在 esProc SPL 协助下,可以让文件拥有计算能力,从而实现开放灵活高效的文件型数据仓库

esProc 是专门面向结构化数据的计算引擎,与数据库一样具备完备的计算能力。与数据库不同的是,esProc 直接基于文件计算,支持 CSV、Excel、JSON 等文件格式,同时还提供了自有的高性能文件格式。esProc 具备良好的开放性,数据源种类不仅局限于文件,还支持多种数据源类型(RDB/NoSQL/RESTful)的同时进行跨数据源混合计算。

文件计算

将数据存储在文件中可以获得更低廉的成本、灵活的使用和方便的管理,这些前面我们已经说过。而且直接使用文件(系统)还可以获得更高的效率,不管是写入还是读取都要远高于数据库。esProc 直接基于文件计算就能实现完整的数据仓库功能(存储 + 计算)。

不过,直接使用如文本这类开放文件格式效率仍然不高。esProc 为此设计了专有的二进制文件格式,提供了压缩、列存、有序、并行分段等机制来充分保证计算性能。

在高性能文件存储的基础上,esProc 还设计了诸多高性能算法(要知道有些算法需要存储的配合才能应用),其中有序游标、遍历复用、外键指针、单边分堆、倍增分段并行等都是 esProc 的独创发明。

esProc 提供的部分高性能算法

有了高性能文件存储和算法的保证,esProc 在实际应用中相对传统数据仓库经常获得数量级的性能提升。比如在计算用户流失率的电商漏斗分析场景中,用户使用 Snowflake 的 Medium 服务器(相当于 4*8=32 核)3 分钟没有跑出来;而 esProc 在一个 12 核 1.7G 的低端服务器上仅用不到10 秒就跑出来了。还有国家天文台的天体聚类任务中 esProc 的性能相较其他实现(某分布式数据库)快了2000 倍

跨源计算

esProc 还具备良好的开放性,天然支持跨源计算

esProc 作为开放计算引擎支持几十种数据源,不同数据源只要 esProc 能访问到都能参与运算,无非只是访问性能上的差异(使用 esProc 提供的二进制文件格式效率最高)。这些数据源不仅能单独访问,还可以进行混合计算,即跨源计算。原来数据库实施跨源计算需要先 ETL 带来的诸多问题使用 esProc 都可以完全解决,不仅具备更强的数据实时数据,还可以充分保留各类数据源自身的优势。

有了文件存储、高性能和跨源计算的保证以后,esProc 还很容易实现 HTAP。HTAP 需求本质上是由于数据量大分库后无法进行 T+0 查询产生的。esProc 支持多样性数据源混合计算,天然可以进行 T+0 分析。更多内容: HTAP 数据库搞不定 HTAP 需求

这种机制下还易于实现真正的湖仓一体。湖仓一体要求能存能算,既能充分保留原始数据又具备强计算能力可以充分发挥数据价值。但使用数据库实现湖仓一体会面临只能算不能存(只能 House 不能 Lake)的处境,这是由其封闭性、强约束导致的。文件存储天然是湖,不合规不符合约束的数据存储在湖内,再在上面增加 esProc 提供强计算能力,无论什么样的数据都能计算,需要高性能再进行整理,这自然实现了可逐步完善的湖仓一体。更多内容: 现在的湖仓一体像是个伪命题

总结

数据仓库与数据库的应用目标大不相同,再使用数据库建设数据仓库势必会造成很多不适,像本文提到的封闭性有如一道城墙横亘在计算体系内外,不仅浪费时间空间,一些新时代的应用需求(如数据实时性、存算分离等)也很难满足。而基于文件的数据仓库具备更强的开放性,没有了“城墙”的限制使用上更加灵活、高效,同时基于 esProc 的强计算能力,在使用方便的同时还能提供更高效的计算效率,这才是现代数据仓库该有的样子。