3.2 大数据处理技术
1993—2013:大数据处理技术发展的风雨二十年
在新型大数据处理技术与平台出现之前,人们处理大规模数据或计算密集型科学计算任务的方式通常是借助MPI(Message Passing Interface)编程模型和方法。在大数据处理技术与平台出现之前,业界也使用MPI进行大数据的并行化编程与计算。MPI起源于1993年,由来自大学、美国国家实验室、高性能计算厂商共同发起组织与研究。MPI由于能够充分利用并行计算系统的硬件资源,发挥其计算性能,从而被广泛应用于高性能科学计算的多个领域。然而,MPI缺少统一的计算框架支持,缺少良好的架构支撑,程序员需要考虑包括数据存储、划分、容错处理等诸多细节,因此其并行化编程计算的自动化程度较低、程序设计较为复杂、程序员负担较重。
随着Web2.0时代的发展,互联网上的数据量呈现爆炸式增长,为了满足信息搜索的需要,人们对大规模数据的存储提出了非常强劲的需要。基于成本的考虑,通过提升硬件来解决大批量数据的搜索越来越不切实际,于是谷歌提出了一种基于软件的可靠文件存储体系“谷歌文件系统”(GFS),使用普通的电脑来并行支撑大规模数据的存储。
存进去的数据是低价值的,只有对数据进行加工才能满足实际的应用需要,于是谷歌又创造了MapReduce这一计算模型,该模型能够利用集群的力量将复杂的运算拆分到多个普通电脑上进行计算,计算完成后通过汇总得到最终的计算结果。
有了GFS和MapReduce之后,文件的存储和运算得到了解决,这时候又出现了新的问题。GFS的随机读写能力很差,同时谷歌又需要一种存放格式化数据的数据库,原本通过单机的数据库就能解决的问题,在新的架构下又“悲剧”了。于是谷歌开发了一套列式数据库系统——BigTable。
谷歌完成了上述系统后,就把其中的思想作为论文发布出来了,美国科学家Doug Cutting 参考了Google这3项技术的原理之后,开始利用Java程序语言开发自家的DFS文件系统和MapReduce程序。Doug Cutting在2006年1月成立了独立的开源项目,并且以儿子的玩具大象名字将之命名为Hadoop。
后来,Yahoo看到了Hadoop可以运用于大量数据运算的价值,便开始支持Hadoop项目,并投入不少人力和财力参与其开发工作,并开始在内部运用Hadoop。Yahoo甚至在2008年建置了一个当时全球最大规模的Hadoop体系,利用4千多台服务器,使用超过3万个处理器核心来索引超过16 PB的网页数据。一段时间后,Google公司也参与了Hadoop项目的开发,并利用此项目作为教材,在世界各地培训云端运算的开发人才,Hadoop逐渐被视为云端运算的关键技术。因为重要性日增,Hadoop也在2008年成为Apache的顶级项目。
伴随数据时代的发展,新兴社交网站如脸书(Facebook)、推特(Twitter)等发展起来,由于用户数据量剧增且数据类型大多为非结构化数据,诸如图片、网络视频、网站或聊天记录等,于是也开始采用Hadoop来处理数据。例如Facebook就利用Hadoop打造了一个数据仓储平台来整理和缩减庞大的用户数据,数据量减少后再放入原有数据库中进行处理分析。
由于众多行业对大规模数据处理的热切需求,开源的Hadoop在推出之后很快得到了全球学术界和工业界的普遍关注和使用。在此过程中,大家还想要各种各样的特性,Hadoop也得到了不断的完善和发展。和谷歌类似,Hadoop除了最核心的存储层HDFS(Hadoop分布式文件存储系统)以及开源版本的MapReduce,类似的参照BigTable就有了Hbase。Facebook的工程师觉得MapReduce程序太难写,于是就开发了Hive。Hive是一套能把SQL语句转成MapReduce的工具,有了这套工具,只要你会SQL就可以来Hadoop上写MapReduce程序分析数据了。对了,参考chubby,后面又有了开源的ZooKeeper来作为分布式锁服务的提供者。
Hadoop从2006年项目成立开始,已经风风雨雨走过了12年,从最开始的HDFS和MapReduce两个组件开始,到现在已经形成了一个完整的框架(图3-2)。
图3-2 Hadoop框架
最新发布的Hadoop3.0框架,除了其最核心的存储层HDFS (分布式文件系统)和计算模型MapReduce(分布式计算),它还包括了HBase(列式数据库)、Hive(数据仓库)、Sqoop(ETL工具)、Flume(日志收集)、Impala、Zookeeper(协作)、Mahout (数据挖掘)、Pig(数据流)以及Ambari(安装、部署、配置、管理)等。
由于Hadoop最开始是用来跑文件的,对于数据的批处理来说没什么问题,但是,如果有一天突然大家想要一个实时的查询服务,数据这么大,要满足实时查询首先要抛开的是Mapreduce,因为它速度很慢。为此,学术界和业界又在不断的研究中推出了多种大数据计算模式。2008年,一家叫Cloudera的公司出现了,其目标是要做Hadoop界的redhat,把各种外围系统打包进去组成一个完整的生态系统,后来它开发了impala。impala的速度与MapReduce相比,实时分析的效率有了几十倍的提升,后来Hadoop的创始人Doug Cutting也加入了Cloudera。这时候学院派也开始发力了,加州大学伯克利分校于2013年开发了Spark。Spark是支撑常见的大数据处理计算模式的集大成者。Spark提出了一种高效的、基于分布式内存的抽象数据对象:弹性分布式数据集RDD。Spark在全面兼容Hadoop HDFS分布式存储访问接口的基础上,通过更多的利用内存处理大幅提高了并行化计算系统的性能。刚开始,Spark的语法比较难掌握,后来慢慢出现了Shark项目,渐渐使Spark向SQL语法靠近。
在一套完整的大数据处理流程中,用户往往需要综合多种计算模式。在支持多计算模式的大数据处理系统中,除了Apache Spark,还出现了起源于欧洲的大数据内存计算框Apache Flink。Flink的核心是一个流式数据流引擎,它为数据的分布式计算提供了数据分布、通信、容错等功能,同时支持流式(Streaming)计算和批处理(Batch)计算(批处理计算当作流式计算的一种特殊情况),并为这两种类型的计算提供了相应的分布式数据计算模型DataStream和Dataset及丰富的数据转换接口。
大数据时代的计算模型:MapReduce
MapReduce是用于大数据并行计算的核心算法模型,其实,在生活中也不缺乏类似的模型。举个简单的例子,比如我们要统计一个档案馆里到底保存了多少份档案。一种方法是,找一个数数很厉害又能够长时间工作的人,由他一个人来完成这个任务。第二种方法是,找一大批数数资质不那么好的人和一个负责分配任务的人,由分配任务的人负责划分区域,确保每个人都分到一部分要统计的区域,不重复也不疏漏。随后对所有人下发统计的指令,统计档案的人将自己负责的区域统计完成后记录下来,所有参与统计的人上交统计结果以后,负责分配任务的人将所有的统计结果相加,得到最后的结果。如果中途有人因为一些意外导致技术终止,那么就再派一个人去重新完成。在数据量很大的时候,第二种方案的优越性就显示出来了,因为数数资质不好的人总是容易找到的,而且个体成本较低,只要调度和统计的方法没问题,第二种方案能够确保更加快速地完成我们的任务,甚至可以通过增加数数的人来提升速度。MapReduce就是这样一种计算模型。
大数据时代的存储系统:HDFS
过春节的时候,家家户户都免不了吃一顿团年饭。李明家亲戚比较多,来了30多个人,一桌坐不下,就分为8人一桌,坐了4桌。这好比我们有一块500 GB的硬盘,但有1000 GB的内容需要存储,一台电脑放不下,我们可以考虑多增加几台,这多台电脑形成了一个系统,这就是我们今天所说的分布式文件系统。随之而来的问题是,假如增加的电脑每一台都只有500 GB的存储容量,如何存储1000GB的内容呢? 事实上,如图3-3所示,在分布式文件系统中,一个大的文件被切成了小块,分别存储到不同机器上。
图3-3 文件分布式存储
聪明的你也许会问,大文件被切割后,如果要查找一个文件,如何快速地知道这个文件在哪个机器上呢?我们当然可以从头到尾地搜索,找到需要的文件,但这样效率太低。想想吃饭的场景,如图3-4所示,李明为了照顾不同亲戚的口味,为每桌都点了一些不同的菜品,服务员上菜时,李明会告诉他们菜上到哪桌。
图3-4 吃饭场景架构图
我们再来看看分布式文件系统的架构,如图3-5所示,在分布式文件系统的架构中,DataNode是真正存储数据的地方,类似于上面场景的饭桌;每道菜就是一个文件切块,NameNode的作用类似于李明,是一个管理者(Master),它知道每一个DataNode的存储情况;客户端(client)是统一的操作接口,类似于上面的服务员,发出查询指令。在这样一个体系架构中,client要查询或者写入文件时,会先去询问NameNode,看看自己应该选择在哪个DateNode中读或者写,这样就避免了全局搜索,大大提高了文件操作的效率。
图3-5 HDFS架构图
在分布式文件系统中,大文件被分别存储在不同机器(DataNode)上,如果某个DataNode坏掉,那这个文件是否就不能访问了呢?假如由成千上万的机器组成的分布式系统用于存储PB或者EB级别的数据,即便是每台机器出现故障的概率在0.01%,汇总在一起也成了大概率事件,不满足可靠性的要求。想想吃饭的场景,如果某一桌的汤飞进了苍蝇,所幸其他桌还有同样的汤,可以从其他桌分过来喝。这种思想在分布式文件系统中就是将数据进行复制并保存多份,在写入一个数据文件时,不会仅仅写入一个DataNode,而会写入多个DataNode(图3-6)。这样,如果其中一个DataNode坏了,还可以从其余的DataNode中拿到数据,虽然耗费的存储空间大一些,但保证了数据的可靠性,相对于数据的价值来说,硬盘要便宜得多。
图3-6 数据写入
NameNode对于分布式文件系统是非常重要的,在Hadoop2.x之前,整个系统只有一个NameNode,如果这个丢失了,那整个系统也就丢失了。因此,在Hadoop2.x之后,可以在系统中配置多个NameNode,但这又增加了系统的复杂程度,需要考虑的问题变得更多。
总的来说,分布式文件系统可以存储海量数据,并且保证了数据的可靠性,不会造成数据的丢失。但缺点也同样明显,比如不适合存储大批量的小文件,文件写入后无法随机修改,只能追加,不支持并发写入,查询效率不高。因此,分布式文件系统设计的初衷在于做离线计算,在整个大数据的体系架构中,分布式文件系统作为核心的数据存储层位于最底层,在其上层还有接下来将介绍的分布式数据库Hbase。
大数据时代的分布式数据库:Hbase
Hbase是一个构建在分布式文件系统(HDFS)上的分布式数据库,支持百万级的高并发写入和实时查询。Hbase有着和传统数据库mysql完全不一样的存储方式,mysql是行式存储,而Hbase是列式存储。在大数据领域,Hbase相对于传统数据库有着巨大的数据读写优势。那什么是行式存储,什么又是列式存储呢?假如我们有以下的数据表(图3-7):
图3-7 原始数据表
行式存储就是建立一个二维的数据表(图3-8),存储在传统的数据库如mysql中:
图3-8 行式存储
行式存储中,如果有较多的空数据,就会造成存储空间的浪费,因此,人们设计了列式存储来解决稀疏数据的问题。同样的数据,在Hbase中的存储结构是这样的,也就是所谓的列式存储。相当于把每一行的每一列拆开,通过rowkey关联起来,rowkey相同的数据其实就是原来的一行(图3-9)。这样既可以避免空数据的存储,也使得在存储量上可以达到上百万列。此外,由于Hbase是基于HDFS来存储的,因此Hbase可以存储上亿行,是一个真正的海量数据库。当Hbase中的表达到数十亿行时,每个表的大小可能达到TB级别,有时甚至PB级,这些表就会切分成小一点的数据单位,然后分配到多台服务器上。这些小一点的数据单位叫region,管理region的服务器叫region server。一张表由多个region组成(图3-10)。
图3-9 列式存储
图 3-10 全表拆分为region