Hadoop生态圈
Hadoop 都说广义上讲是Hadoop生态圈,狭义上讲就是HDFS,MapReduce和Yarn。说Hadoop起源于Nutch。根据谷歌发表的三篇论文得来 :GFS,MapReduce和Big table,分别对应的hadoop生态圈里面的hdfs,mapReduce和HBase。
HDFS:分布式文件系统
MapReduce:分布式计算系统
Yarn:分布式集群资源管理
但是准确来说,Hadoop具体是啥呢。我感觉,像Java里面的List,Set和Map统称为集合框架。就是一个圈子。所以我感觉Hadoop不能说准确的是什么东西,他更像一个圈子,只是伸展度、扩展度的问题。
HDFS:Hadoop Distributed File System --hadoop的分布式文件系统
HDFS由四部分组成:HDFS Client 、NameNode、DataNode和SecondaryNameNode
HDFS的文件写入过程
1、Client 发起请求,通过RPC(远程控制协议)建立通讯。NameNode检查文件是否存在,父目录是否存在,返回是否可以上传。
2、当临时文件达到一个block文件的大小时,Client通知用户申请写入文件;
3、NameNode在HDFS的文件系统中创建一个文件,并把该block id和要写入的DataNode的列表返回给客户端;
4、客户端收到信息后,将内容发给DataNode,第一个DataNode通过管道pipeline的方式进行复制传给第二个DataNode。NameNode会挑一个比较好的DataNode进行复制冗余
5、后面的DataNode接收完数据后,都会发送一个确认给前一个DataNode,最终第一个DataNode返回确认给客户端;
6、当客户端接收到整个block的确认后,会向NameNode发送一个最终的确认信息,每个block都会有一个校验码,并存放到独立的文件中,以便读的时候来验证其完整性,文件写完后,客户端关闭,NameNode提交文件。
HDFS的文件读取过程
- Client向NameNode发起RPC请求,来确定请求文件block所在的位置;
- NameNode会返回文件的部分或者全部block列表,对于每个block,NameNode 都会返回含有该 block 副本的 DataNode 地址; 这些返回的 DN 地址,会按照集群拓扑结构得出 DataNode 与客户端的距离,然后进行排序,排序两个规则:网络拓扑结构中距离Client 近的排靠前;心跳机制中超时汇报的 DN 状态为 STALE,这样的排靠后;
- Client 选取排序靠前的 DataNode 来读取 block,如果客户端本身就是DataNode,那么将从本地直接获取数据(短路读取特性);
- 底层上本质是建立 Socket Stream(FSDataInputStream),重复的调用父类
DataInputStream 的 read 方法,直到这个块上的数据读取完毕; - 当读完列表的 block 后,若文件读取还没有结束,客户端会继续向NameNode 获取下一批的 block 列表;
- 读取完一个 block 都会进行 checksum 验证,如果读取 DataNode 时出现错误,客户端会通知 NameNode,然后再从下一个拥有该 block 副本的DataNode 继续读。
- read 方法是并行的读取 block 信息,不是一块一块的读取;NameNode 只是返回Client请求包含块的DataNode地址,并不是返回请求块的数据;
- 最终读取来所有的 block 会合并成一个完整的最终文件。
FsImage
fsimage 内容包含了 NameNode 管理下的所有 DataNode 文件及文件 block 及 block所在的 DataNode 的元数据信息。随着 edits 内容增大, 就需要在一定时间点和 fsimage 合并。
Edits
Edits存放了客户端最近一段时间的操作日志,客户端对 HDFS 进行写文件时会首先被记录在 edits 文件中。
MapReduce
MR的思想就是“分而治之”,而且MR运行在Yarn集群中。
一个完整的mapreduce程序在分布式运行时有三类实例进程:
- MRAppMaster 负责整个程序的过程调度及状态协调
- MapTask 负责map阶段的整个数据处理流程
- ReduceTask 负责reduce阶段的整个数据处理流程
MR的阶段
1、生成Job的实例对象,设置一个输入流InputFormatClass默认是TextInputFormat。
2、Job会先经过MapTask阶段,会先进行之前设置的MapperClass类,设置k1和v1的输入类型和k2v2的输出类型。
3、经过分区,进入环形缓冲区,环形缓冲区默认大小是100M,而且默认溢出的大小是百分之80。环形缓冲区将溢出的文件切分(spill),然后经过排序,规约将很多小文件合并,生成一个临时文件。
4、经过网络的传输,传输到Reducer的Shuffle阶段,经过Reduce的缓冲区将文件分切成许多小文件,然后把小文件并成一个大文件,经过排序分组形成一个中间文件,然后经过Reducer的Task阶段生成,最终通过outputFormar类输出在hdfs上的part文件。
Yarn
yarn是资源管理系统模块,可为各类计算框架提供资源的管理和调度。
YARN总体上是Master/Slave结构 ,主要由ResourceManager、NodeManager、ApplicationMaster和Container等几个组件构成。
ResourceManager(RM)
负责处理客户端请求,对各NodeManager上的资源进行统一管理和调度。给ApplicationMaster分配空闲的Container运行并监控其运行状态。主要由两个组件构成:调度器和应用程序管理器:
- 调度器(Scheduler):将系统中的资源分配给各个正在运行的应用程序。
- 应用程序管理器(Applications Manager):应用程序管理器负责管理整个系统中所有应用程序。
NodeManager (NM)
NodeManager 是每个节点上的资源和任务管理器。它会定时地向ResourceManager汇报本节点上的资源使用情况和各个Container的运行状态;同时会接收并处理来自ApplicationMaster 的Container 启动/停止等请求。
ApplicationMaster (AM)
它负责向ResourceManager协调资源,并且与NodeManager协同工作完成Task的执行和监控。
Container
Container是Yarn中的资源抽象。
yarn的调度器
FIFO Scheduler(队列调度)
Capacity Scheduler(容量调度器,apache版本默认使用的调度器)
Fair Scheduler(公平调度器,CDH版本的hadoop默认使用的调度器)
数据仓库
数据仓库:面向分析的存储系统 。
- 数据库是面向事务的设计,数据仓库是面向主题设计的。 数据库一般存储业务数据,数据仓库存储的一般是历史数据。
- 数据库设计是尽量避免冗余,一般针对某一业务应用进行设计,符合业务应用,但是不符合分析。数据仓库在设计是有意引入冗余,依照分析需求,分析维度、分析指标进行设计。
- 数据库是为捕获数据而设计,数据仓库是为分析数据而设计。
数据仓库,是在数据库已经大量存在的情况下,为了进一步挖掘数据资源、为了决策需要而产生的,它决不是所谓的“大型数据库”。
数仓
1.4. 数仓的分层架构
按照数据流入流出的过程,数据仓库架构可分为三层——源数据、数据仓库、数据应用。
- 源数据层(ODS)
不对外开放,为临时存储层,是接口数据的临时存储区域,为后一步的数据处理做准备。 - 数据仓库层(DW)
也称为细节层,数据应该是一致的、准确的,即对源系统数据进行了清洗后的数据。 - 数据应用层(DA或APP)
前端应用直接读取的数据源;根据报表、专题分析需求而计算生成的数据。
数据仓库从各数据源获取数据及在数据仓库内的数据转换都可以认为是ETL
(抽取Extra, 转化Transfer, 装载Load)的过程,而数据仓库日常的管理和维护工作的大部分精力就是保持ETL的正常和稳定。
对数据仓库分层:用空间换时间,通过大量的预处理来提升应用系统的效率,因此数据仓库会存在大量冗余的数据;不分层的话,如果源业务系统的业务规则发生变化将会影响整个数据清洗过程,工作量巨大。
Hive
Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。
自定义函数
- UDF(User-Defined-Function)
一进一出 - UDAF(User-Defined Aggregation Function)
聚集函数,多进一出
类似于: count / max / min - UDTF(User-Defined Table-Generating Functions)
一进多出
如 lateral view explore() - 编程步骤:
- 继承org.apache.hadoop.hive.ql.UDF
- 需要实现evaluate函数;evaluate函数支持重载;
- 注意事项
- UDF必须要有返回类型,可以返回null,但是返回类型不能为void;
- UDF中常用Text/LongWritable等类型,不推荐使用java类型;
hive的数据存储格式
Hive支持的存储数的格式主要有:TEXTFILE(行式存储) 、SEQUENCEFILE(行式存储)、ORC(列式存储)、PARQUET(列式存储)。
存储文件的压缩比总结:
ORC > Parquet > textFile
存储文件的查询速度总结:
ORC > TextFile > Parquet
hive表的数据存储格式一般选择:orc或parquet。压缩方式一般选择snappy。
hive调优
1.Fetch抓取
Hive中对某些情况的查询可以不必使用MapReduce计算。
把hive.fetch.task.conversion设置成none,然后执行查询语句,都会执行mapreduce程序。
把hive.fetch.task.conversion设置成more,然后执行查询语句,都不会执行mapreduce程序。
2.本地模式
有时Hive的输入数据量是非常小的。Hive可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显被缩短。设置hive.exec.mode.local.auto的值为true。
3.Map Join
容易发生数据倾斜。可以用MapJoin把小表全部加载到内存在map端进行join,避免reducer处理。
4.Group By
默认情况下,Map阶段同一Key数据分发给一个reduce,当一个key数据过大时就倾斜了。很多聚合操作都可以先在Map端进行部分聚合。有数据倾斜的时候进行负载均衡(默认是false)
5. Count(distinct)
数据量大的情况下,由于COUNT DISTINCT操作需要用一个ReduceTask来完成,这一个Reduce需要处理的数据量太大,就会导致整个Job很难完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替换。
6.笛卡尔积
尽量避免笛卡尔积,即避免join的时候不加on条件,或者无效的on条件。
7.动态分区调整
往hive分区表中插入数据时,hive提供了一个动态分区功能,其可以基于查询参数的位置去推断分区的名称,从而建立分区。使用Hive的动态分区,需要进行相应的配置。
Hive的动态分区是以第一个表的分区规则,来对应第二个表的分区规则,将第一个表的所有分区,全部拷贝到第二个表中来,第二个表在加载数据的时候,不需要指定分区了,直接用第一个表的分区即可。
8.严格模式
Hive提供了一个严格模式,可以防止用户执行那些可能意向不好的查询。通过设置属性hive.mapred.mode值为默认是非严格模式nonstrict 。开启严格模式需要修改hive.mapred.mode值为strict,开启严格模式可以禁止3种类型的查询。
1.对于分区表,在where语句中必须含有分区字段作为过滤条件来限制范围,否则不允许执行。
2.对于使用了order by语句的查询,要求必须使用limit语句。
3.限制笛卡尔积的查询 。
9.JVM重用
JVM对Hive的性能具有非常大的影响,特别是对于很难避免小文件的场景或task特别多的场景,这类场景大多数执行时间都很短。JVM重用可以使得JVM实例在同一个job中重新使用N次。N的值可以在Hadoop的mapred-site.xml文件中进行配置。
10.推测执行
在分布式集群环境下,会出现负载不均衡或者资源分布不均等原因,会造成有些任务的运行速度可能明显慢于其他任务,则这些任务会拖慢作业的整体执行进度。为了避免这种情况发生,Hadoop采用了推测执行(Speculative Execution)机制 ,它根据一定的法则推测出“拖后腿”的任务,并为这样的任务启动一个备份任务,让该任务与原始任务同时处理同一份数据,并最终选用最先成功运行完成任务的计算结果作为最终结果。
Flume
Flume 是 Cloudera 提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的软件。
Flume 的核心是把数据从数据源(source)收集过来,再将收集到的数据送到指定的目的地(sink)。为了保证输送的过程一定成功,在送到目的地(sink)之前,会先缓存数据(channel)在整个数据的传输的过程中,在整个过程中流动的是event,event是 Flume 内部数据传输的最基本单元。
每一个 agent 相当于一个数据传递员,内部有三个组件:
Source:采集源,用于跟数据源对接,以获取数据;
Sink:下沉地,用于往下一级 agent 传递数据或者传递数据;
Channel:agent 内部的数据传输通道,用于从 source 将数据传递到 sink;
Sqoop
Sqoop 可以理解为:“SQL 到 Hadoop 和 Hadoop 到 SQL”。
Azkaban
Azkaban 是由 linkedin(领英)公司推出的一个批量工作流任务调度器,用于在一个工作流内以一个特定的顺序运行一组工作和流程。
Oozie
Oozie 是一个用来管理 Hadoop 生态圈 job 的工作流调度系统。Oozie 的目的是按照 DAG(有向无环图)调度一系列的 Map/Reduce 或者 Hive等任务。
HUE
HUE=Hadoop User Experience,它是基于Python Web框架Django实现的。界面很友好。