DDIA:批处理和 MPP 数据库千丝万缕( 三 )

  • 逻辑布线分离 。和 Unix 工具一样,MapReduce 也将逻辑和接线分离(通过配置输入、输出文件夹),从而分拆复杂度并且提高代码复用度:一些团队可以专注于实现干好单件事的任务开发;另一些团队可以决定在哪里、在何时来组合跑这些代码 。
  • 在上述方面,Unix 中用的很好地一些设计原则也适用 Hadoop——但 Unix 工具和 Hadoop 也有一些不同的地方 。比如,大部分 Unix 工具假设输入输出是无类型的文本 , 因此不得不花一些时间进行输入解析(比如之前的例子中 , 需要按空格分割,然后取第 7 个字段,以提取 URL) 。在 Hadoop 中,通过使用更结构化的数据格式,消除了底层的一些低价值的语法解析和转换:Avro (参见Avro)和 Parquet 是较常使用的两种编码方式 , 他们提供基于模式的高效编码方式,并且支持模式版本的演进 。
    对比 Hadoop 和分布式数据库从之前讨论我们可以感觉到,Hadoop 很像一个分布式形态的 Unix 。其中,HDFS 对标 Unix 中的文件系统,MapReduce 类似于 Unix 进程的一个奇怪实现(在 map 阶段和 reduce 阶段间必须要进行排序) 。在这些源语之上,我们可以实现各种 join 和 group 语义 。
    MapReduce 被提出时,并非是一种全新的思想 。在其十多年前,所有前述小节我们提到的一些并行 join 算法都已经被 MPP (massive parallel processing)数据库所实现了 。如 , Gamma data base machine、Teradata 和 Tandem NonStop SQL 都是这个领域的先驱 。
    当然,如果硬要区分的话:
    1. MPP 数据库是在一组机器上分布式地、并行执行分析型的 SQL
    2. MapReduce 和分布式文件系统提供了一种类似于操作系统的、更为通用的计算方式
    存储类型更为多样数据库要求用户遵循特定的模式(schema,数据模型,如关系型或者文档型)组织数据,但分布式系统中的文件是面向字节序列(byte arrary , 即内容对于系统是黑盒),用户可以使用任何必要的方式进行建模和编码 。因此 , 这些文件既可以是数据库记录的集合,也可以是文本、图像、视频、传感器数值、稀疏矩阵、特征向量、基因序列,或者其他任意类型的数据 。
    换句话说 , Hadoop 允许你以任意格式的数据灌入 HDFS,将如何处理的灵活性推到之后(对应之前讨论过的 schema-less,或者 schema-on-read ) 。与之相反,MPP 数据库通常要求用户在数据导入之前,就要针对数据类型和常用查询模式,进行小心的建模(对应 schema-on-write) 。
    从完美主义者的角度来说,事先对业务场景进行仔细地建模再导入数据才是正道 。只有这样,数据库用户才能够得到更高质量的数据 。然而在实践中,即便不管模式快速导入数据,可能会让数据处于奇怪、难用、原始的格式,反而会比事先规划、考究建模后将限制死格式更为有价值 。
    这种思想和数据库仓库很像:在大型组织中 , 将从不同部门来的数据快速聚集到一块非常重要 , 因为这提供了将原先分离的数据进行联结(join)的各种可能性 。MPP 数据库所要求的小心精确地建模 , 会严重拖慢中心化数据的速度 。以原始格式将数据聚集到一块,之后再去考虑如何进行建模,可以大大加速数据收集速度(这个概念有时也被称为数据湖,data lake,或者企业数据中心 , enterprise data hub) 。
    无脑数据导入其实是将数据理解的复杂度进行了转移:数据生产者无需关心数据会被如何使用,这是数据消费者的问题(类似读时模式,参见文档模型中 Schema 的灵活性) 。在数据生产者和消费者处于不同团队、具有不同优先级时,这种方式的优势非常明显 。因为可能没有一种通用的理想模型 , 出于不同目的,会有不同的看待数据方式 。将数据以原始方式导入,允许之后不同消费者进行不同的数据变换 。这种方式被总结为 sushi 原则:数据越原始越好 。
    因此 Hadoop 经常用于 ETL 处理:将数据以某种原始的格式从事务型的处理系统中引入到分布式文件系统中,然后编写 MapReduce 任务以处理这些数据,将其转换回关系形式,进而导入到 MPP 数据仓库汇总以备进一步分析之用 。数据建模依然存在,但是拆解到了其他的步骤,从而与数据收集解耦了开来 。由于分布式文件系统不关心应用方以何种方式对数据进行编码,仅面向字节数组存储 , 让这种解耦成为了可能 。


    推荐阅读