目录:
前言:
这是为一次数据团队内部分享准备的内容,希望通过这次分享能让大家对大数据领域的技术生态有一个全面且较宏观的认知,了解大数据领域常用的开源技术及各自的特性。
一、大数据技术生态图
-
Ambari:可以安装、部署及管理hadoop、hive、hbase、zk等集群。
-
HDFS:Hadoop中的分布式文件存储系统。
-
Yarn:Hadoop中的集群资源管理和调度系统。
-
MapReduce:Hadoop中的分布式离线计算框架。
-
Spark:分布式内存计算框架。包括spark core、spark streaming、spark mllib等组件。
-
Tez:对MapReduce任务进行优化,加快执行速度。
-
Hive:数据仓库工具。
-
Pig:通过内置pig Latin高级语言,简化MapReduce任务的开发。
-
Impala:交互式实时查询系统,查询速度较快。与presto类似。
-
Shark:即spark sql,通过sql方式实现spark任务查询计算。
-
HBase:分布式列式存储数据库。
-
Spark MLlib:spark机器学习算法库。
-
Mahout:Hadoop机器学习算法库。
-
Hue:图形化数据查询(连接Hive、spark、pig等集群查询能力),可管理hadoop等集群。
-
Nutch:基于hadoop的数据搜索引擎。
-
spark Graphx:spark图计算框架。
-
RHadoop:可使用R语言进行MapReduce程序开发。
-
Hadoop Streaming:可支持多种语言进行mr任务开发,且简化mr任务开发流程。
-
Oozie:作业调度系统,可处理任务间血缘依赖、按顺序执行等。
-
Zookeeper:分布式协调服务系统,hadoop、Hbase等均依赖zk服务完成选举、监控等。
-
Flume:分布式日志采集工具,支持丰富的上游数据来源类型和下游数据输出渠道。
-
Kafka:分布式发布订阅消息系统,吞吐量较大,大数据系统常用。
-
Sqoop:数据库间同步工具,类似dataX。
-
Storm:流式实时计算框架,毫秒级延迟。
-
Spark Streaming:实时计算框架,秒级延迟。
二、Hadoop
1、HDFS
分布式文件系统(HDFS)是指被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统(Distributed File System)。HDFS是一个高度容错性的系统,适合部署在廉价的机器上。HDFS能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。
采用了主从(Master/Slave)结构模型,一个HDFS集群是由一个NameNode和若干个DataNode组成的。其中NameNode作为主服务器,管理文件系统的命名空间和客户端对文件的访问操作;集群中的DataNode管理存储的数据。
名称结点(NameNode)
名称节点(nameNode)负责管理分布式文件系统的命名空间(NameSpace),NameSpace中保存了两个核心的数据结构,即FsImage和EditLog。
-
FsImage:用于维护文件系统树以及文件树中所有的文件和文件夹的元数据。
-
EditLog:操作日志文件,它记录了所有针对文件的创建、删除、重命名等操作。
数据节点(DataNode):
• 数据节点是分布式文件系统HDFS的工作节点,负责数据的存储和读取,会根据客户端或者是名称节点的调度来进行数据的存储和检索,并且向名称节点定期发送自己所存储的块的列表
当一个数据节点加入HDFS集群时,会把自己包含的数据块列表报告给名称节点,此后会通过“心跳”的方式定期执行这种告知操作,以确保名称节点的块映射是最新的。
容灾:
NameNode故障
SecondaryNameNode:镜像备份、日志与镜像的定期合并。
Hadoop HA: active NameNode, standby NameNode
Hadoop HA 架构图:
DataNode故障
-
10分钟没有心跳上报才会被集群认为节点dead,该节点上存储的block被标记为Missing状态。
-
集群容错机制开始生效,将mission状态block在其他节点上复制。
Block问题
-
datanode默认每隔6小时会向namenode汇报一次节点block信息。
-
NameNode节点根据节点上报的blcok信息,与自身存储block信息比对NameNode发现异常后,会对datanode节点发布新建/删除block的指令。
-
DataNode执行NameNode指令。
2、MapReduce
-
Map
首先会对输入文件做预处理,将文件切分成分片,并把数据转化成key-value的键值对集合。
map任务首先会被分配一个缓存,默认100M,达到0.8时启动溢写到磁盘。
溢写前要进行哈希分区,然后写进分区,对于分区内的键值对默认会进行排序操作,然后是一个可选的合并操作combine,对分区内部的键值对根据key值进行合并(需要事先定义,如求和、最大值等可以使用)。
对多个溢写分区进行归并(Merge),将若干个相同key的键值对归并成新的键值对。
-
Reduce
Reduce任务首先会把map端领回的数据存放在reduce机器的缓存中,如果缓存被占满,就会像map端一样溢写到磁盘中。
溢写操作前首先会进行归并操作,如果定义了combiner,归并后的数据还会进行合并操作,减少写入磁盘数据量。
当map端数据都被领回时,多个溢写文件会被归并同时还会对键值对进行排序最终生成一个有序的大文件。
3、Yarn
MapReduce1.0的资源调度管理采用的是JobTracker和TaskTreacker机制。在MapReduce2.0中已经被取消,由yarn来接管资源调度管理(ResourceManager、ApplicationMaster和NodeManager。)
1.ResourceManager
概述:RM是一个集群资源管理器,负责整个系统的资源管理和分配。它主要由两个组件构成:调度器(Scheduler)和应用程序管理器(Application Manager)。
(1)调度器(Scheduler) 调度器根据容量、队列等限制条件(如每个队列分配一定的资源,最多执行一定数量的作业等),将系统中的资源分配给各个正在运行的应用程序。
(2) 应用程序管理器 应用程序管理器负责管理整个系统中所有应用程序,包括应用程序提交、与调度器协商资源以启动ApplicationMaster、监控ApplicationMaster运行状态并在失败时重新启动它等。
2.NodeManager
NM是每个节点上的资源和任务管理器,一方面,它会定时地向RM汇报本节点上的资源使用情况和各个Container的运行状态;另一方面,它接收并处理来自AM的Container启动/停止等各种请求。
3.Application Master
用户提交的每个应用程序均包含一个AM,主要功能是与RM调度器协商获取资源,将得到的任务进一步分配给内部任务;与NM通信以启动/停止任务;监控所有任务运行状态,并在任务运行失败时重新为任务申请资源以重启任务。
applicationMaster是应用程序提交时才会启动的进程。RM和NM是Yarn的常驻进程,由配置文件指定机器。
YARN工作流程
当用户向YARN中提交一个应用程序后,YARN将分两个阶段运行该应用程序:
第一个阶段是启动ApplicationMaster;
第二个阶段是由ApplicationMaster创建应用程序,为它申请资源,并监控它的整个运行过程,直到运行完成。
具体步骤
-
步骤1(任务提交):用户向YARN中提交应用程序,其中包括ApplicationMaster程序、启动ApplicationMaster的命令、用户程序等。
-
步骤2(启动AM):ResourceManager负责接收和处理客户端请求。为该应用程序分配第一个Container,并与对应的NodeManager通信,要求它在这个Container中启动应用程序的ApplicationMaster。
-
步骤3(向RM注册):ApplicationMaster首先向ResourceManager注册,这样用户可以直接通过ResourceManager查看应用程序的运行状态,然后它将为各个任务申请资源,并监控它的运行状态。
接下来步骤4-步骤7是应用程序执行步骤。
-
步骤4 ApplicationMaster采用轮询的方式通过RPC协议向ResourceManager申请资源。(向RM申请资源)
-
步骤5 一旦ApplicationMaster申请到资源后,便与对应的NodeManager通信,要求它启动任务。(启动任务1)
-
步骤6 NodeManager为任务设置好运行环境(包括环境变量、JAR包、二进制程序等)后,将任务启动命令写到一个脚本中,并通过运行该脚本启动任务。(启动任务2)
-
步骤7 各个任务通过某个RPC协议向ApplicationMaster汇报自己的状态和进度,以让ApplicationMaster随时掌握各个任务的运行状态,从而可以在任务失败时重新启动任务。在应用程序运行过程中,用户可随时通过RPC向ApplicationMaster查询应用程序的当前运行状态。(任务执行和汇报)
-
步骤8 应用程序运行完成后,ApplicationMaster向ResourceManager注销并关闭自己。(AM关闭)
三、Hive
1、背景
Hive起源于Facebook,Facebook每天产生PB级的数据。
解决数据存储的方案是Hadoop:
特点:
-
拥有较好的可用性和扩展性;
-
多台机器时效率可以提升;
-
ACID没有可用性和扩展性重要。
依然面临的问题:
1、专业人才短缺(MapReduce):编写MapReduce程序学习成本高,大多员工比较熟悉sql语言;
2、统一数据管理需求。需要一个元数据管理模块来管理数据。
Hive设计的初衷:
-
对于大量的数据,使得数据汇总,查询和分析更加简单。
-
它提供了SQL,允许用户更加简单地进行查询,汇总和数据分析,即SQL on Hadoop 。
-
Hive不是为在线事务处理而设计,它适合于传统的数据仓库任务。
2、Hive框架
比较官方的介绍:
Hive是基于Hadoop的一个数据仓库工具,用来进行数据提取、转化、加载,这是一种可以存储、查询和分析存储在Hadoop中的大规模数据的机制。
Hive数据仓库工具能将结构化的数据文件映射为一张数据库表,并提供SQL查询功能,能将SQL语句转变成MapReduce任务来执行。
Hive的优点是学习成本低,可以通过类似SQL语句实现快速MapReduce统计,使MapReduce变得更加简单,而不必开发专门的MapReduce应用程序。
Hive框架:
-
Hive计算基于MapReduce
-
Hive存储基于hdfs
Hive可以认为是MapReduce的一个封装、包装。Hive的意义就是在业务分析中将用户容易编写、会写的Sql语言转换为复杂难写的MapReduce程序,从而大大降低了Hadoop学习的门槛,让更多的用户可以利用Hadoop进行数据挖掘分析。
为了让大家容易理解Hive的实质——-“Hive就是一个SQL解析引擎,将SQL语句转化为相应的MapReduce程序”。下面用一个图例来演示:
Hive跟ODPS表操作很相似:
表管理、sql语法、任务调优、内表/外表 、分区、动态插入、多种数据存储格式
四、Spark
在核心框架 Spark 的基础上,主要提供四个范畴的计算框架:
- Spark SQL: 提供了类 SQL 的查询,返回 Spark-DataFrame 的数据结构(类似 Hive)
- Spark Streaming: 流式计算,主要用于处理线上实时时序数据(类似 storm)
- MLlib: 提供机器学习的各种模型和调优
- GraphX: 提供基于图的算法,如 PageRank
RDD 初识
RDD(Resilent Distributed Datasets)俗称弹性分布式数据集,是 Spark 底层的分布式存储的数据结构,可以说是 Spark 的核心, Spark API 的所有操作都是基于 RDD 的。
RDD数据不只存储在一台机器上,而是分布在多台机器上,实现数据计算的并行化.弹性表明数据丢失时,可以进行重建。
RDD算子举例:map,countByKey,foreach,reduce,aggregate,foreachPartition……
var mapresult = data.map(line => line.split("\\s+"));
Partition
spark中的partion是弹性分布式数据集RDD的最小单元,RDD是由分布在各个节点上的partion组成的。
Spark宽窄依赖
-
窄依赖表现为一个父RDD的分区对应于一个子RDD的分区或多个父RDD的分区对应于一个子RDD的分区。
-
宽依赖则表现为存在一个父RDD的一个分区对应一个子RDD的多个分区。
DAG划分
Spark Streamming介绍
基本概念:
批处理窗口大小通常在0.5~2s之间。
重要参数:
1.批处理时间间隔。将该时间间隔内采集到的数据统一处理。即spark多久对数据流切分一次,每切分一次生成一个RDD。
2.窗口时间间隔。对一定时间范围内的数据进行统计和分析。它必须是批处理时间的整数倍,且比批处理时间间隔大。
3.滑动时间间隔。对数据进行统计和分析的频率,即多久滑动一下窗口。也必须是批处理时间的整数倍,即触发计算的间隔时间。
比如三个参数分别为(1,3,2)。含义则是每隔2s对过去3秒内的3个RDD进行统计分析。
scala> import org.apache.spark.streaming._
scala> val ssc = new StreamingContext(sc, Seconds(2)) //2秒的批处理时间间隔
scala> val lines = ssc.textFileStream("file:///usr/local/spark/mycode/streaming/logfile")
lines: org.apache.spark.streaming.dstream.DStream[String] = org.apache.spark.streaming.dstream.MappedDStream@62e0fe3
scala> val words = lines.flatMap(_.split(" "))
words: org.apache.spark.streaming.dstream.DStream[String] = org.apache.spark.streaming.dstream.FlatMappedDStream@86cdf99
scala> val wordCounts = words.map(x => (x, 1)).reduceByKey(_ + _)
scala> wordCounts.print()
scala> ssc.start()
scala> ssc.awaitTermination()
五、Flume
1、Flume基础概念
Flume 是一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统, Flume支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力。(Flume使用java编写,支持Java1.6及以上。)
Flume主要有以下几个核心概念:
Event:flume最基本的数据单元,带有一个可选的消息头(headers) 。如果是文本,event通常是一行记录,event也是事务的基本单位。
Flow:Event从源点到达目的点的迁移的抽象。
Client:操作位于源点处的Event,将其发送到Flume Agent。
Agent:一个独立的Flume进程,包含组件Source、Channel、Sink 。
Source:用来消费传递到该组件的Event,完成对数据的收集,分成transtion和event打入到channel之中。不同的 source,可以接受不同的数据格式。
Channel: 主要提供一个队列的功能,对source提供中的数据进行简单缓存,作用是保证source到sink的数据传输过程一定能成功。
Sink:取出Channel中的数据,进行相应的存储文件系统、数据库等。
2、核心组件配置介绍
Flume官方文档链接: Flume官方文档
source
client端操作消费数据的来源,支持的类型有exec、Avro、log4j、syslog、http post、Thrift、JMS、Spooling Directory等类型。
对于直接读取文件 Source,有两种方式:
-
ExecSource: 以运行 Linux 命令的方式,持续的输出最新的数据,如 tail -F 文件名 指令,在这种方式下,取的文件名必须是指定的。
-
SpoolSource: 监测配置的目录下新增的文件,并将文件中的数据读取出来。
channel
有Memory Channel, JDBC Channel, File Channel, Kafka Channel、Psuedo Transaction Channel. 比较常用的是前三种。
-
MemoryChannel 可以实现高速的吞吐,但是无法保证数据的完整性。
-
FileChannel保证数据的完整性与一致性、但吞吐量下降。
Sink
支持的数据类型:HDFS Sink, Logger Sink, Avro Sink, Thrift, IPC, File Roll ,Kafka Sink等等。
一个基本的配置文件示例:
(监测一个文件内日志数据变化,并输出到日志)
a1.sources = r1
a1.sinks = k1
a1.channels = c1
#describe/configure the source
a1.sources.r1.type=exec
a1.sources.r1.command=tail -F /home/hadoop/abc.log
a1.sources.r1.channels = c1
# Use a channel which buffers events in memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
# Describe the sink
a1.sinks.k1.type = logger
# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
3、Kafka、Flume对比
都可以实现数据传输,但侧重点不同。
Kafka追求的是高吞吐量、高负载、提供push和pull、自带存储。
Flume追求的是数据的多样性:数据来源的多样性、数据流向的多样性。
如果数据来源很单一、想要高吞吐的话可以使用Kafka;但需要自己实现source和sink进程。
如果数据来源很多、数据流向很多的话可以使用Flume,很适合做日志采集;
另外有些场景,可以将Kafka和Flume结合起来使用。
六、大数据架构图示例
1、基于开源Hadoop生态技术的大数据架构图:
2、Hadoop大数据生态图: