MapRedue是一个巨大的退步
文章地址
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