《从0开始学大数据》笔记

大数据

Posted by Jesse on June 12, 2023

极客时间 《从0开始学大数据》

大数据前生今世

今天我们常说的大数据技术,其实起源于Google在2004年前后发表的三篇论文,也就是我们经常听到的“三驾马车”,分别是分布式文件系统GFS、大数据分布式计算框架MapReduce和NoSQL数据库系统BigTable。

Hadoop,主要包括Hadoop分布式文件系统HDFS和大数据计算引擎MapReduce

MapReduce进行大数据编程太麻烦了,Facebook又发布了Hive。Hive支持使用SQL语法来进行大数据计算,比如说你可以写个Select语句进行数据查询,然后Hive会把SQL语句转化成MapReduce的计算程序。

在Hadoop早期,MapReduce既是一个执行引擎,又是一个资源调度框架,服务器集群的资源调度管理由MapReduce自己完成。但是这样不利于资源复用,也使得MapReduce非常臃肿。于是一个新项目启动了,将MapReduce执行引擎和资源调度分离开来,这就是Yarn。2012年,Yarn成为一个独立的项目开始运营,随后被各类大数据产品支持,成为大数据平台上最主流的资源调度系统

2012年,UC伯克利AMP实验室(Algorithms、Machine和People的缩写)开发的Spark开始崭露头角,Spark一经推出,立即受到业界的追捧,并逐步替代MapReduce在企业应用中的地位。

而在大数据领域,还有另外一类应用场景,它们需要对实时产生的大量数据进行即时计算,比如对于遍布城市的监控摄像头进行人脸识别和嫌犯追踪。这类计算称为大数据流计算,相应地,有Storm、Flink、Spark Streaming等流计算框架来满足此类大数据应用的场景。 流式计算要处理的数据是实时在线产生的数据,所以这类计算也被称为大数据实时计算

除了大数据批处理和流处理,NoSQL系统处理的主要也是大规模海量数据的存储与访问,所以也被归为大数据技术。涌现出HBase、Cassandra等许多优秀的产品,其中HBase是从Hadoop中分离出来的、基于HDFS的NoSQL系统。

大数据处理的主要应用场景包括数据分析、数据挖掘与机器学习。数据分析主要使用Hive、Spark SQL等SQL引擎完成;数据挖掘与机器学习则有专门的机器学习框架TensorFlow、Mahout以及MLlib等,内置了主要的机器学习和数据挖掘算法。

大数据应用发展史:从搜索引擎到人工智能

大数据应用的搜索引擎时代

Google开发了GFS(Google文件系统),将数千台服务器上的数万块磁盘统一管理起来,然后当作一个文件系统,统一存储所有这些网页文件

大数据应用的数据仓库时代

Hive可以在Hadoop上进行SQL操作,实现数据统计与分析。也就是说,我们可以用更低廉的价格获得比以往多得多的数据存储与计算能力。我们可以把运行日志、应用采集数据、数据库数据放到一起进行计算分析,获得以前无法得到的数据结果,企业的数据仓库也随之呈指数级膨胀。

大数据应用的数据挖掘时代

在商业环境中,如何解读这种关系并不重要,重要的是它们之间只要存在关联,就可以进行关联分析,最终目的是让用户尽可能看到想购买的商品。

大数据应用的机器学习时代

而现在有了大数据,可以把全部的历史数据都收集起来,统计其规律,进而预测正在发生的事情

这就是机器学习。

大数据从搜索引擎到机器学习,发展思路其实是一脉相承的,就是想发现数据中的规律并为我们所用

大数据应用领域:数据驱动一切

04讲移动计算比移动数据更划算

既然数据是庞大的,而程序要比数据小得多,将数据输入给程序是不划算的,那么就反其道而行之,将程序分发到数据所在的地方进行计算,也就是所谓的移动计算比移动数据更划算

现在我们来看,移动计算程序到数据所在位置进行计算是如何实现的呢?

1.将待处理的大规模数据存储在服务器集群的所有服务器上,主要使用HDFS分布式文件存储系统,将文件分成很多块(Block),以块为单位存储在集群的服务器上

2.大数据引擎根据集群里不同服务器的计算能力,在每台服务器上启动若干分布式任务执行进程,这些进程会等待给它们分配执行任务。

3.使用大数据计算框架支持的编程模型进行编程,比如Hadoop的MapReduce编程模型,或者Spark的RDD编程模型。应用程序编写好以后,将其打包,MapReduce和Spark都是在JVM环境中运行,所以打包出来的是一个Java的JAR包。

4.用Hadoop或者Spark的启动命令执行这个应用程序的JAR包,首先执行引擎会解析程序要处理的数据输入路径,根据输入数据量的大小,将数据分成若干片(Split),每一个数据片都分配给一个任务执行进程去处理。

5.任务执行进程收到分配的任务后,检查自己是否有任务对应的程序包,如果没有就去下载程序包,下载以后通过反射的方式加载程序。走到这里,最重要的一步,也就是移动计算就完成了。

6.加载程序后,任务执行进程根据分配的数据片的文件地址和数据在文件内的偏移量读取数据,并把数据输入给应用程序相应的方法去执行,从而实现在分布式服务器集群中移动计算程序,对大规模数据进行并行处理的计算目标。

05讲从RAID看垂直伸缩到水平伸缩的演化

06讲新技术层出不穷,HDFS依然是存储的王者

关键组件有两个,一个是DataNode,一个是NameNode

DataNode负责文件数据的存储和读写操作,HDFS将文件数据分割成若干数据块(Block),每个DataNode存储一部分数据块,这样文件就分布存储在整个HDFS服务器集群中。应用程序客户端(Client)可以并行对这些数据块进行访问,从而使得HDFS可以在服务器集群规模上实现数据并行访问,极大地提高了访问速度。

NameNode负责整个分布式文件系统的元数据(MetaData)管理,也就是文件路径名、数据块的ID以及存储位置等信息,相当于操作系统中文件分配表(FAT)的角色

HDFS的高可用设计

1.数据存储故障容错

计算并存储校验和(CheckSum)。在读取数据的时候,重新计算读取出来的数据的校验和,如果校验不正确就抛出异常

2.磁盘故障容错

如果DataNode监测到本机的某块磁盘损坏,就将该块磁盘上存储的所有BlockID报告给NameNode,NameNode检查这些数据块还在哪些DataNode上有备份,通知相应的DataNode服务器将对应的数据块复制到其他服务器上,以保证数据块的备份数满足要求。

3.DataNode故障容错

DataNode会通过心跳和NameNode保持通信

4.NameNode故障容错

冗余备份

失效转移

降级限流

07讲为什么说MapReduce既是编程模型又是计算框架

WordCount主要解决的是文本处理中词频统计的问题,就是统计文本中每一个单词出现的次数。如果只是统计一篇文章的词频,几十KB到几MB的数据,只需要写一个程序,将数据读入内存,建一个Hash表记录每个词出现的次数就可以了。这个统计过程你可以看下面这张图。

map函数的计算过程是,将这行文本中的单词提取出来,针对每个单词输出一个<word, 1>这样的<Key, Value>对。

MapReduce计算框架会将这些<word , 1>收集起来,将相同的word放在一起,形成<word , <1,1,1,1,1,1,1…»这样的<Key, Value集合>数据,然后将其输入给reduce函数。

这里reduce的输入参数Values就是由很多个1组成的集合,而Key就是具体的单词word。

reduce函数的计算过程是,将这个集合里的1求和,再将单词(word)和这个和(sum)组成一个<Key, Value>,也就是<word, sum>输出。每一个输出就是一个单词和它的词频统计总和。

一个map函数可以针对一部分数据进行运算,这样就可以将一个大数据切分成很多块(这也正是HDFS所做的),MapReduce计算框架为每个数据块分配一个map函数去计算,从而实现大数据的分布式计算。

假设有两个数据块的文本数据需要进行词频统计,MapReduce计算过程如下图所示。

08讲MapReduce如何让数据完成一次旅行

在实践中,这个过程有两个关键问题需要处理。

  • 如何为每个数据块分配一个Map计算任务,也就是代码是如何发送到数据块所在服务器的,发送后是如何启动的,启动以后如何知道自己需要计算的数据在文件什么位置(BlockID是什么)。

  • 处于不同服务器的map输出的<Key, Value> ,如何把相同的Key聚合在一起发送给Reduce任务进行处理。

1.应用进程JobClient将用户作业JAR包存储在HDFS中,将来这些JAR包会分发给Hadoop集群中的服务器执行MapReduce计算。

2.应用程序提交job作业给JobTracker。

3.JobTracker根据作业调度策略创建JobInProcess树,每个作业都会有一个自己的JobInProcess树。

4.JobInProcess根据输入数据分片数目(通常情况就是数据块的数目)和设置的Reduce数目创建相应数量的TaskInProcess。

5.TaskTracker进程和JobTracker进程进行定时通信。

6.如果TaskTracker有空闲的计算资源(有空闲CPU核心),JobTracker就会给它分配任务。分配任务的时候会根据TaskTracker的服务器名字匹配在同一台机器上的数据块计算任务给它,使启动的计算任务正好处理本机上的数据,以实现我们一开始就提到的“移动计算比移动数据更划算”。

7.TaskTracker收到任务后根据任务类型(是Map还是Reduce)和任务参数(作业JAR包路径、输入数据文件路径、要处理的数据在文件中的起始位置和偏移量、数据块多个备份的DataNode主机名等),启动相应的Map或者Reduce进程。

8.Map或者Reduce进程启动后,检查本地是否有要执行任务的JAR包文件,如果没有,就去HDFS上下载,然后加载Map或者Reduce代码开始执行。

9.如果是Map进程,从HDFS读取数据(通常要读取的数据块正好存储在本机);如果是Reduce进程,将结果数据写出到HDFS。

MapReduce数据合并与连接机制

MapReduce计算真正产生奇迹的地方是数据的合并与连接

每个Map任务的计算结果都会写入到本地文件系统,等Map任务快要计算完成的时候,MapReduce计算框架会启动shuffle过程,在Map任务进程调用一个Partitioner接口,对Map产生的每个<Key, Value>进行Reduce分区选择,然后通过HTTP通信发送给对应的Reduce进程。这样不管Map位于哪个服务器节点,相同的Key一定会被发送给相同的Reduce进程。Reduce任务进程对收到的<Key, Value>进行排序和合并,相同的Key放在一起,组成一个<Key, Value集合>传递给Reduce执行。

map输出的<Key, Value>shuffle到哪个Reduce进程是这里的关键,它是由Partitioner来实现,MapReduce框架默认的Partitioner用Key的哈希值对Reduce任务数量取模,相同的Key一定会落在相同的Reduce任务ID上。从实现上来看的话,这样的Partitioner代码只需要一行。

1
2
3
4
 /** Use {@link Object#hashCode()} to partition. */ 
public int getPartition(K2 key, V2 value, int numReduceTasks) { 
    return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks; 
 }

分布式计算需要将不同服务器上的相关数据合并到一起进行下一步计算,这就是shuffle

09讲为什么我们管Yarn叫作资源调度框架

分布式文件系统HDFS、分布式计算框架MapReduce,还有一个是分布式集群资源调度框架Yarn

Yarn是“Yet Another Resource Negotiator”的缩写

Yarn包括两个部分:一个是资源管理器(Resource Manager),一个是节点管理器(Node Manager)

具体说来,资源管理器又包括两个主要组件:调度器和应用程序管理器

调度器其实就是一个资源分配算法,根据应用程序(Client)提交的资源申请和当前服务器集群的资源状况进行资源分配。Yarn内置了几种资源调度算法,包括Fair Scheduler、Capacity Scheduler等,你也可以开发自己的资源调度算法供Yarn调用。

Yarn进行资源分配的单位是容器(Container),每个容器包含了一定量的内存、CPU等计算资源,默认配置下,每个容器包含一个CPU核心。容器由NodeManager进程启动和管理,NodeManger进程会监控本节点上容器的运行状况并向ResourceManger进程汇报。

应用程序管理器负责应用程序的提交、监控应用程序运行状态等。应用程序启动后需要在集群中运行一个ApplicationMaster,ApplicationMaster也需要运行在容器里面。每个应用程序启动后都会先启动自己的ApplicationMaster,由ApplicationMaster根据应用程序的资源需求进一步向ResourceManager进程申请容器资源,得到容器以后就会分发自己的应用程序代码到容器上启动,进而开始分布式计算。

我们以一个MapReduce程序为例,来看一下Yarn的整个工作流程。

1.我们向Yarn提交应用程序,包括MapReduce ApplicationMaster、我们的MapReduce程序,以及MapReduce Application启动命令。

2.ResourceManager进程和NodeManager进程通信,根据集群资源,为用户程序分配第一个容器,并将MapReduce ApplicationMaster分发到这个容器上面,并在容器里面启动MapReduce ApplicationMaster。

3.MapReduce ApplicationMaster启动后立即向ResourceManager进程注册,并为自己的应用程序申请容器资源。

4.MapReduce ApplicationMaster申请到需要的容器后,立即和相应的NodeManager进程通信,将用户MapReduce程序分发到NodeManager进程所在服务器,并在容器中运行,运行的就是Map或者Reduce任务。

5.Map或者Reduce任务在运行期和MapReduce ApplicationMaster通信,汇报自己的运行状态,如果运行结束,MapReduce ApplicationMaster向ResourceManager进程注销并释放所有的容器资源。

MapReduce如果想在Yarn上运行,就需要开发遵循Yarn规范的MapReduce ApplicationMaster,相应地,其他大数据计算框架也可以开发遵循Yarn规范的ApplicationMaster,这样在一个Yarn集群中就可以同时并发执行各种不同的大数据计算框架,实现资源的统一调度管理。