文章地址
https://www.dcs.bbk.ac.uk/~dell/teaching/cc/paper/dbc08/dewitt_mr_db.pdf

背景

这篇文章写于 2008年,当时 MapReduce非常火,很多研究机构、大学都在鼓吹MapReduce多么好,代表了未来的计算范式
但是 DavidJ. DeWitt 和 Michael Stonebraker 两位数据库专家不这么认为
他们列举出了MapReduce的5个问题:

  • 对于数据密集型应用来说,是一个巨大的退步
  • 不是很好的实现,没有使用索引,而是蛮力查找
  • 这种系统也不是新玩意,25年前就有了
  • 缺乏很多当前数据库的有用特性
  • 跟所有的数据库工具都不兼容

下面先谈下MapReduce是什么,然后再讨论这5个问题

MapReduce介绍

MapReduce很简单,就是两个程序,map和reduce,然后在大规模集群上运行
map从输入文件中读取一组记录,然后做一些转换操作写入到一个输出文件中
map程序通过一个split函数将数据写入到不同分区,这个函数一般就是hash函数,这就写入到 M 个不同的桶中,然后flush到磁盘,map程序结束
一般来说会有多个map程序同时运行,如果有 N 个节点参与map阶段 最终会生成 N * M 个文件

map端执行执行的是相同的hash函数,所以相同的值会被写入到同一个分区中
reduce程序会从这 M 个输入中读取文件,然后执行任意的操作
比如对数据字段执行一个函数,最终reduce的各个实例会将数据写入到一个最终文件,这就是结果

map有点像 SQL 中的 group-by,而reduce有点类似于 聚合函数

关于MapReduce的5个缺点

相比关系型数据库访问层的缺点

为什么说MapReduce是巨大的退步?
自1968年IBM IMS发布至今,已有40多年历史了,整个数据库的社区学会了三件事

  • schema 很重要
  • 将 schema 和应用程序隔离
  • 高层API很重要

关系型数据都是有 schema 的,这样在运行期间,如果输入数据中有垃圾,就会被 schema 阻挡
但是MapReduce没有 schema,这就糟糕了,因为一个错误的程序可能会写入一些垃圾数据,而且也不会产生错误或者提示,同时导致所有的读取这些数据的MapReduce都不可用

在写应用程序的时候,就需要明确程序的记录结构,像关系型数据库可以通过查询获取表的结构,如果没有这种结构,程序员就得找到源码,找到数据的结构才行,MapReduce的开发者就是这样

在70年代,DMBS社区有一场争论,参与者是 关系型数据库 vs Codasyl,他们的区别如下:

  • 关系模式,申明你想要什么,而不是实现一个算法来获得它
  • Codasyl,通过一个算法来获得它

后来的事情是 关系型数据库赢得了市场,因为 Codasyl 太难用了,相当于数据库层面的汇编语言
而MapReduce就类似于 Codasyl,必须要写一个低层次的语言来实现一个低层次的操作

利用MapReduce,从输入文件中提取一个key时,map函数至少需要一个数据字段,对于reduce程序也是一样的
BigTable、HBase也没有改善这个问题,自描述的元组格式 row key, column name, {values}
在同一个表的不同元组实际上会有不同的模式
这两个系统也没有提供逻辑的独立性,比如 view
逻辑schema更改时,view可以保持应用程序的独立性

MapReduce是一个糟糕的实现

现代的关系数据库都有 hash、B树索引这种机制,可以大幅提高检索速度
优化器可以选择使用 索引,或者使用蛮力的顺序扫描
而MapReduce只有一个选项,就是顺序扫描

MapReduce的支持者会说,它可以自动的实现大规模并行查询
这种机制80年代的关系型数据库就有了,包括

  • Gamma
  • Bubba
  • Grace
  • Teradata (商业实现)

MapReduce还有两个严重问题

  • 数据倾斜
  • map阶段的大量数据写磁盘

第一个问题在《Parallel Database System: The Future of High Performance Database Systems》里面就提到了
数据倾斜是实现可扩展查询系统的巨大障碍,而在map阶段,如果相同key的记录分布差别很大,这个差异会影响到reduce阶段
可能会导致某个reduce非常慢,从而最终拖慢了整个计算时间

对于第二个问题,map阶段是需要写文件的,假设有 N 个map每个map写入M个文件,这就有N * M 个文件,如果N 和 M 都比较大,那么一次会写入很多文件
而reduce阶段开始时,每个reduce都需要用pull的方式从节点读取数据
如果多个reduce从map节点并行的读取文件,这会导致大量的磁盘ssek,严重拖垮性能
并行数据库系统则使不使用物化而使用push(socket)的方式
但MapReduce是依靠写文件实现fault-tolerance,所以MapReduce框架要实现push模式可能不太容易

MapReduce不是新事物

MapReduce所提出的概念,20多年前就有了:

  • 将大数据集分区放入小数据集中: Application of Hash to Data Base Machine and Its Architecture
  • 在shard-nothing集群上执行并行join,它使用分区联合表、分区执行、hash拆分: Multiprocessor Hash-Based Join Algorithms
  • 在并行情况下,不用group by执行聚合
  • 并行数据库系统如何处理请求的
  • 以及更多的并行聚合策略

Teradata使用上述技术,并售卖商业的数据库超过20多年了,所以MapReduce并不是新玩意
POSTGRES 在1980年就提供了UDF和UDFA,大部分数据库都有类似的功能

MapReduce缺少的特性

下面是关系型数据库都有的,而MapReduce没有的特性:

  • bulk load:将文件中的格式转换为需要的格式,并导入数据库
  • index
  • update
  • transactions
  • integrity constraints,通过约束避免不正确的数据
  • referential integrity,同上
  • views,改变schema而无需改变程序

MapReduce和关系型数据库工具不兼容

现代关系数据库都支持下列工具

  • 报表生成,如Crystal reports
  • BI工具,如Business Objects or Cognos,可以在打数据集中执行adhoc查询
  • 数据采集工具,如Oracle Data Mining、IBM DB2 Intelligent Miner ,在大数据集中发现结构
  • 复制工具,如Golden Gate,将DB中的数据复制到另一个DB -数据库设计工具,如Embarcadero,帮助用户设计数据库

MapReduce没有这些工具,除非它能兼容SQL,或者有人写了这些工具

总结

能设计出这种可扩展的查询系统非常棒,但也不能忽视关系型数据库超过40多年的经验,如数据模型、逻辑数据物理数据分离、声明查询语言如SQL
很多计算机科学家往往只关注自己的领域,我们鼓励社会多关注数据库领域超过25年的经验
MapReduce想到达到现代数据库的要求,还需要增加很多特性和工具
关系数据库也并非完美,很多人抱怨难用,关系数据库也可以学习MapReduce中的容错机制
我们也注意到有研究人员在MapReduce之上构建可扩展的数据库系统,如Pig