写点什么

架构师训练营 1 期 -- 第十二周总结

用户头像
曾彪彪
关注
发布于: 2020 年 12 月 09 日

大数据的技术背景

狭义的大数据是指Hadoop家族的相关技术,广义的大数据指任何的数据处理,数据挖掘,人工智能等。

大数据的三架马车分别是GFS,MapReduce和BigTable。

早期的大数据,主要是基于HDFS进行数据存储,基于MapReduce进行计算。因为MapReduce这种方式进行数据处理比较麻烦,后来人们开发出了Pig,使用一些脚本来自动生成MapReduce程序。

但是使用Pig的成本还是比较高,因为需要学习一门新的脚本语言,后来Facebook又发布了Hive,基于SQL来生成MapReduce程序。这极大的降低了使用Hadoop的使用门槛。

早期的MapReduce既是执行引擎,又是资源调度引擎。这样不利于资源复用,也使MapReduce显得十分臃肿。所以后来Yarn被开发出来,专门用于分布式系统的资源管理和调度。

MapReduce存在一个问题,对于有些计算(比如迭代次数比较多),它的性能比较差。于是后来出现了Spark,用来替代MapReduce。到目前位置,Spark是比较重要的执行引擎。

对于MapReduce和Spark,他们都是批处理作业,运算时间比较长,统计的是历史数据。对于实时的计算,也成为流式计算,需要使用其它的一些框架,如Storm,Flink,Spark Streaming等。

关于大数据,可以参考以下架构图:



大数据的应用场景又很多,比如医学影响识别,病例管理,无人驾驶,无人商店,金融大数据风控等等。



HDFS

从上面的图中,可以看出HDFS是大数据中最基础的模块,负责数据的存储。

HDFS的设计目标是以流式数据访问模式存储超大文件,它适合超大型的数据存储,适合一次写入多次读取的场景,可以运行在商业硬件上。HDFS不适合低延迟的数据访问场景,小文件也不适合存储在HDFS中,另外需要随机读取的数据也不适合放在HDFS中。

HSFS中,有三个角色,分别是NameNode,DataNodes以及Client。NameNode负责存储文件元数据信息,这些元数据信息包括文件的名称,位置,备份数目等。DataNodes负责具体的数据存储。Client是要读取或写入文件的应用程序。





HDFS写入数据的架构图如下:

客户端先和NameNode通信,获取可以写入的DataNode的URL,然后Client开始向DataNode进行数据写入,DataNode写入完成后,通过Pipeline的方式对写入的数据块进行复制。复制结束后,通知Client写入完成,此时Client告诉NameNode数据写入完成。

HDFS读取数据的原理差不多,和写入操作相比更简单,Client和NameNode通信,获取可用的DataNode的URL,然后进行数据读取即可。

在HDFS中,认为节点失效是常态,这里有很多场景以及解决方案。

  • 如果磁盘挂了,DataNode会通知NameNode,对损坏磁盘中的数据做备份。

  • 如果DataNode挂了,DataNode每3s会发心跳到NameNode,如果DataNode超过10min没发心跳到NameNode,那么NameNode认为这台DataNode已经dawn,会复制这台DataNode上的数据。

  • 如果NameNode宕机,NameNode会记录操作日志,可以根据日志进行数据恢复,但是从日志恢复的时间比较长,所以NameNode会定期备份数据文件。恢复可以从数据文件开始,在备份时间之后的数据可以根据日志进行恢复。现在的NameNode都借助于Zookeeper,实现主主复制。

  • Client宕机,Client文件写一半宕机。HDFS的解决方案是,当前正在写入的文件,其它reader是不可见的,只有写完一个块,其它reader才能读取到。文件写完后,调用sync()使整个文件可见。



另外HDFS可以跨机架进行数据备份,提高数据可用性。



MapReduce

MapReduce的精髓是移动计算比移动数据更划算,另外就是分而治之的思想。

MapReduce中,其实包含了Map和Reduce两个函数,Map函数的输入和输出都是一个key/value,而reduce函数的输入是key/values,输出是value。Map函数的输出结果,相同的key会统计起来,作为reduce函数的输入。

MapReduce的数据处理如下图:

MapReduce框架从HDFS中读取数据,将数据交给不同服务器上的Map进行处理,Map经过计算,将处理结果Reduce处理。相同key的结果会发送给同一个Reduce处理。数据达到Reduce后,会先对输入数据进行排序,相同key的结果会整理成List,传给Reduce进行计算。

更详细的处理流程如下图:



一个Map函数执行结果是放在内存中缓存区的,缓存区满后,这些结果就会被存储到硬盘上,存储结果是进行分区的,每个reduce都会对应一块分区的存储。在Reduce中,不同的分区copy过来的数据会进行合并,生成key/values。

在MapReduce中,Shuffle是很重要的概念,相关的Map结果会被shuffle到相同的Reduce中,所以Map中,Key的设计是很重要的。



MapReduce的整体架构如下:



应用程序通常会将包含MapReduce程序的jar包存储在HDFS中,然后提交作业到JobTracker服务器。JobTracker服务器中有一个JobScheduler,当接到MapReduce作业后,创建JobInProcess。这是一颗任务树,根节点是JobInProcess,子节点是TaskInProcess。子节点的个数是Map任务和Reduce任务之和。TaskInProcess也包含子节点TaskAttemp,通常情况下一个TaskInProcess只有一个TaskAttempt。

一个DataNode节点通常也是一个TaskTracker节点,它会定时向JobTracker节点发送心跳,告知当前服务器的资源使用状况。JobTracker收到心跳信息后,会将Task分派给JobTracker节点。通常,它会将Task中需要读取的数据块分配给存储该数据块的TaskTracker节点,这样可以避免数据copy。

最后,任务在TaskTracker节点上执行,它从HDFS中加载jar包,然后读取本地数据,将执行结果copy给Reduce。



InputFormat接口提供了读取文件分片信息以及生成key/value的方法,Map函数正式通过FileFormat来读取输入数据的。在MapReduce中,默认实现是FileInputFormat,通常,如果设置mapred.min.split.size=mapred.max.split.size=blockSize,可是实现任务和数据在同一个节点上。

Partitioner实现了对Map计算的结果进行分区,默认是根据hash值进行分区。

MapReduce包含的调度算法有单队列调度和容量调度。但是在生产环境中,可能需要更加灵活的调度算法。

JobTracker是整个MapReduce的调度管理器,它负责创建任务,并分配给指定的TaskTracker。

JobTracker会创建一个JobInProcess,一个JobInProcess是一棵任务树,包含TaskInProcess,而TaskInProcess会包含一个或多个TaskAttempt。当一个TaskAttemp执行失败或者长时间未执行完成,会启动另一个TaskAttemp。这意味着同一个数据块会有多个Map函数在执行,先执行完的结果会copy给Reduce,后执行完的结果会被丢弃。

当TaskAttemp成功是,TaskInProcess执行成功,所有TaskInProcess执行成功是,JonInProcess执行成功。

在整个MapReduce中,只有一个JobTracker节点,当节点宕机后,任务可能没执行完成,可以通过日志来继续执行,但是更简单的方法是将原先的Job再执行一遍。

TaskTracker是用来执行任务的节点,如果TaskTracker 10min未上报心跳,则将其从MapReduce移除,如果此节点上有位完成的TaskAttemp,则在其它节点上重新执行TaskAttemp。如果TaskTracker性能太差,可以将其从集群中剔除。

对于Task,是由TaskInProcess来管理的,可以设置允许其失败测次数,如果超过阈值,则任务不再执行。有些Task是允许失败的,比如求top的计算,可以设置失败百分比。

对于Record,有可能某一行数据非常大,可以设置读取的最大长度限制。



YARN

在MapReduce 1中,由于MapReduce承担了态度的角色,既要负责资源调度,又要负责计算,另外如果其它框架想要使用MapReduce的资源又很不方便,所以在MapReduce 2中,一个专门用于资源调度的框架YARN被开发出来了。



在YARN中,两个重要的角色分别是资源管理器和节点管理器。

资源管理器负责管理和调度集群中所有的资源。

节点管理器,负责管理节点服务器的资源,将节点服务器的资源向资源管理器汇报,资源管理器知晓哪些资源是可用的。

以MapReduce为例,一个任务的调度过程如下:

  • 应用程序向资源管理器请求执行任务。

  • 资源管理器分配一个容器给应用程序。

  • 然后应用程序在容器节点上启动一个ApplicationManager。

  • ApplicationManager负责创建所需的资源请求,并向资源服务器申请资源。

  • 资源服务器分配容器资源给Application Manager,Application Manager负责创建启动这些容器。实际上,这些任务容器需要加载两部分程序,一部分是负责与Application Manager通信的程序,另一部分是MapReduce程序。

  • 在整个过程中,ApplicationManager承担了JobTracker角色,容器承担了TaskTracker的角色。整个资源调度由YARN完成。YARN可以用于各种大数据框架的资源调度,极大的提高了HDFS与其它大数据框架整合的能力。



Hive

MapReduce使用比较复杂,尽管使用Pig可以简化MapReduce的编程,但仍然具有学习成本。实际上,人们在使用MapReduce的时候,大多是是用它来做数据分析,于是,Hive出现了,它能够将SQL语句转换成MapReduce函数执行。

Hive的架构图如下:

客户程序通过Driver提交SQL,Driver将SQL交给Compiler进行处理,Compiler对SQL进行分析,并生成MapReduce执行计划。这期间要用到Metastore中的数据,Metastore存储了表的结构信息。最后Driver将执行计划交给Hadoop进行处理。

Compiler主要的职责是:

  • 把SQL转换为抽象语法树

  • 把抽象语法书转换为查询块

  • 把查询块转换为逻辑执行计划。

  • 重写执行计划,并进行优化

  • 将逻辑执行计划转化为物理执行计划。

  • 适应性Join策略调整



对于Metastore,它是存储Hive表的元数据信息的,默认存储在Debian中,也可以存储在Mysql中。



用户头像

曾彪彪

关注

还未添加个人签名 2019.03.23 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营 1 期 -- 第十二周总结