学好hadoop不是一朝一夕的事情此文档简略仅适用于初入门做了解使用,若想深入学习请使用《hadoop权威指南》
hadoop模块:
Hadoop Common:支持其他Hadoop模块的常用实用程序。
Hadoop分布式文件系统(HDFS™):一种分布式文件系统,可提供对应用程序数据的高吞吐量访问。
Hadoop YARN:作业调度和集群资源管理的框架。
Hadoop MapReduce:基于YARN的系统,用于并行处理大型数据集。(一种计算框架)
Hadoop Ozone: Hadoop的对象存储。(后来新增)
三种运行模式:
本地(独立)模式:
Hadoop配置为以非分布式模式运行,作为单个Java进程。这对调试很有用
伪分布式模式:
Hadoop还可以在伪分布式模式下在单节点上运行,其中每个Hadoop守护程序在单独的Java进程中运行
在一台机器上运行hdfs文件系统,运行mr程序,从hdfs上获取数据,结果存放到hdfs上
完全分布式模式:
运行在多台机器上,同时只有一个hdfs系统
10.12
hdfs体系结构(主、/从结构)
图参照官方文档
namenode:维护命名空间、保存元数据和用户对hdfs的操作、副本数等
管理文件系统命名空间的主服务器,和管理客户端对文件的访问组成,块到DataNode的映射
datanode: 存放实际数据(块)
连接到它们运行的节点的存储
提供来自文件系统客户端的读写请求
执行块的创建,删除
secondarynamenode:辅助namenode进行工作(检查点保存)
hdfs的设计理念
硬件故障是常态而非例外。HDFS实例可能包含数百或数千台服务器计算机,每台计算机都存储文件系统数据的一部分。事实上,存在大量组件并且每个组件具有非平凡的故障概率意味着HDFS的某些组件始终不起作用。
因此,检测故障并从中快速自动恢复是HDFS的核心架构目标。
在HDFS上运行的应用程序需要对其数据集进行流式访问。
它们不是通常在通用文件系统上运行的通用应用程序。HDFS设计用于批处理而不是用户的交互式使用。
重点是数据访问的高吞吐量而不是数据访问的低延迟。
POSIX强加了许多针对HDFS的应用程序不需要的硬性要求。
交易几个关键领域的POSIX语义以提高数据吞吐率。
在HDFS上运行的应用程序具有大型数据集。HDFS中的典型文件大小为千兆字节到太字节。
因此,HDFS被调整为支持大文件。它应该提供高聚合数据带宽并扩展到单个集群中的数百个节点。
它应该在单个实例中支持数千万个文件。
HDFS应用程序需要一个一次写入多次读取的文件访问模型。
除了追加和截断之外,无需更改创建,写入和关闭的文件。支持将内容附加到文件末尾,但无法在任意点更新。该假设简化了数据一致性问题并实现了高吞吐量数据访问。
MapReduce应用程序或Web爬虫应用程序完全适合此模型。
应用程序请求的计算如果在其操作的数据附近执行则更有效。
当数据集的大小很大时尤其如此。这可以最大限度地减少网络拥塞并提高系统的整体吞吐量。
假设通常更好的是将计算迁移到更靠近数据所在的位置,而不是将数据移动到运行应用程序的位置。
HDFS为应用程序提供了接口,使其自身更靠近数据所在的位置。
数据块
存储在hdfs中的最小单位
默认大小128M
这么大的原因:
为了最小化寻址开销,一般寻址时间为10ms,传输速率为100MB/s
为了寻址时间占传输时间的1%,所以。。。。
10.13
元数据:
查看fsimage
整个文件系统命名空间(包括块到文件和文件系统属性的映射)
hdfs oiv -i 要查看的文件名 -o输出的文件名 -p XML
查看edites
文件系统元数据发生的每个更改
hdfs oev -i 要查看的文件名 -o输出的文件名
namenode启动过程
加载fsimage
加载edites
进行检查点保存
等待datanode汇报块信息
datanode启动后
扫描本地块的信息
汇报给namenode
心跳机制
datanode每隔三秒汇报给namenode
检查点(运行时主要由secondarynamenode完成)
它从磁盘读取FsImage和EditLog,将EditLog中的所有事务应用到FsImage的内存中表示,并将此新版本刷新为磁盘上的新FsImage。然后它可以截断旧的EditLog,因为它的事务已应用于持久性FsImage
10.15
机架感知:
检查两台机器是否在同一机架上
NameNode通过Hadoop Rack Awareness中概述的过程确定每个DataNode所属的机架ID 。
一个简单但非最优的策略是将复制品放在独特的机架上。这可以防止在整个机架发生故障时丢失数据,并允许在读取数据时使用来自多个机架的带宽。此策略在群集中均匀分布副本,这样可以轻松平衡组件故障的负载。但是,此策略会增加写入成本,因为写入需要将块传输到多个机架。
副本存放策略:
基于机架感知
当复制因子为3时,HDFS的放置策略是在编写器位于datanode上时将一个副本放在本地计算机上,否则放在随机datanode上,另一个副本放在另一个(远程)机架上的节点上,
最后一个在同一个远程机架的不同节点上。此策略可以减少机架间写入流量,从而提高写入性能。
机架故障的可能性远小于节点故障的可能性; 此策略不会影响数据可靠性和可用性保证。
但是,它确实减少了读取数据时使用的聚合网络带宽,因为块只放在两个唯一的机架而不是三个。
使用此策略时,文件的副本不会均匀分布在机架上。三分之一的副本位于一个节点上,
三分之一的副本位于一个机架上的其他节点,另外三分之一均匀分布在剩余的机架上。此策略可提高写入性能,而不会影响数据可靠性或读取性能。
网络带宽 22
大型HDFS实例在通常分布在许多机架上的计算机群集上运行。不同机架中两个节点之间的通信必须通过交换机。
在大多数情况下,同一机架中的计算机之间的网络带宽大于不同机架中的计算机之间的网络带宽。
数据磁盘故障:
心跳和重新复制
每个DataNode定期向NameNode发送Heartbeat消息。网络分区可能导致DataNode的子集失去与NameNode的连接。
NameNode通过缺少Heartbeat消息来检测此情况。NameNode将DataNodes标记为没有最近的Heartbeats,并且不会将任何新的IO请求转发给它们。注册到死DataNode的任何数据都不再可用于HDFS。
DataNode死亡可能导致某些块的复制因子低于其指定值。NameNode不断跟踪需要复制的块,并在必要时启动复制。由于许多原因可能会出现重新复制的必要性:DataNode可能变得不可用,副本可能会损坏,DataNode上的硬盘可能会失败,标记DataNodes死机的超时是保守的长(默认情况下超过10分钟),以避免由DataNode状态抖动引起的复制风暴。
均衡器
使忙碌的datanode上的块复制到相对空闲的datanode上,确保每个datanode使用率接近集群的使用率
start-balancer.sh
数据的完整性
从DataNode获取的数据块可能已损坏。由于存储设备中的故障,网络故障或有缺陷的软件,可能会发生此损坏。HDFS客户端软件对HDFS文件的内容进行校验和检查。当客户端创建HDFS文件时,它会计算文件每个块的校验和,并将这些校验和存储在同一HDFS命名空间中的单独隐藏文件中。
当客户端检索文件内容时,它会验证从每个DataNode接收的数据是否与存储在关联校验和文件中的校验和相匹配。
如果不是,则客户端可以选择从具有该块的副本的另一个DataNode中检索该块。
文件删除和取消删除:
如果启用了垃圾箱配置,则FS Shell删除的文件不会立即从HDFS中删除。
相反,HDFS将其移动到垃圾目录(每个用户在/user/
只要文件保留在垃圾箱中,文件就可以快速恢复。
最近删除的文件被移动到当前的垃圾箱目录(/user/
对于当前垃圾目录中的文件,并在过期时删除旧检查点。有关垃圾箱的检查点,
请参阅FS shell的expunge命令。
它的生命周期在垃圾箱中到期后,NameNode将从HDFS命名空间中删除该文件。
删除文件会导致释放与文件关联的块。
请注意,在用户删除文件的时间与HDFS中相应增加的可用空间之间可能存在明显的时间延迟。
减少复制因子
在副本数大于设定的副本数时进行
当文件的复制因子减少时,NameNode选择可以删除的多余副本。下一个Heartbeat将此信息传输到DataNode。
然后,DataNode删除相应的块,并在群集中显示相应的可用空间。
再一次,setReplication API调用完成与集群中可用空间的出现之间可能存在时间延迟。
块缓存:
预先读取文件的块到内存,用来提升常用文件的读取效率
10.22
写流程:
1.加载配置文件(参照上节课)
2.获取文件系统(参照上节课)
3.创建写入路径(Path)
4.创建输出流
10.23
mapreduce:填空式编程
MapReduce是一个分布式计算框架
分而治之-数据在哪计算在哪
两个阶段
map(映射)阶段
reduce(规约或合并)阶段
MapReduce作业的输入和输出类型:
(输入)
输入和输出的KV对必须由框架序列化
将结构化对象转换为字节流-----方便在网络传输和写入磁盘
10.25
Mapper
将输入键/值对映射到一组中间键/值对。
将 K1和V1 映射到 K2和V2
映射是将输入记录转换为中间记录的单个任务。
转换后的中间记录不需要与输入记录具有相同的类型。
给定的输入对可能映射到零或多个输出对。
执行一次map只对一行记录进行处理,K1V1和K2V2不需要具有相同类型
Hadoop map - reduce框架为作业的InputFormat生成的每个InputSplit生成一个map任务。
Mapper实现可以通过JobContext.getConfiguration()访问作业的配置。
InputFormat对文件进行切分,一般情况文件有几个块就会被切分成几个InputSplit,每一个InputSplit产生一个map任务, 文件130M ,2个块 128M 2M 1.1 InputSplit数是1
InputSplit是逻辑切分
Block是物理的
mapper框架的调用顺序
框架首先调用
setup(org.apache.hadoop.mapreduce.Mapper.Context),
然后为InputSplit中的每个键/值对调用
map(Object, Object, org.apache. mapreduce. mapper . context)。
最后调用
cleanup(org.apache.hadoop.mapreduce.Mapper.Context)。
与给定输出键关联的所有中间值随后由框架分组,并传递给一个Reducer,以确定最终的输出。
用户可以通过指定两个关键的RawComparator类来控制排序和分组。
map输出按每个reduce进行分区
用户可以通过实现自定义分区器来控制哪个键(以及相应的记录)到哪个Reducer。
用户可以选择通过Job.setCombinerClass(Class)指定一个组合器来执行中间输出的本地聚合,这有助于减少从映射器到还原器的数据传输量。
如果reduce数为零,那么mapper的输出将直接写入OutputFormat,而无需按键排序。
Mapper的组成
setup(Context context)
在任务一开始的时候调用一次
map(KEYIN key, VALUEIN value, Context context)
对于inputslipt中的每个键/值对调用一次。大多数应用程序应该重写它,但是默认的是identity函数。
cleanup(Context context )
在任务结束的时候调用一次
run(Context context)
专家用户专用,以获取完成的控制权
reducer
减少一组中间值,这些中间值与一组较小的值共享一个键。
多个Mapper产生K2V2合并到一起具有相同的K2
reducer主要有三个阶段
1.Shuffle(一部分):
Reducer通过网络使用HTTP从每个mapper复制排序的输出(K2V2)。
2.Sort:
框架合并按键对reducer输入进行排序(因为不同的mapper可能输出相同的键)。
shuffle和sort阶段是同时发生的,也就是说,在提取输出时,它们是合并的。
SecondarySort :
要对值迭代器返回的值进行二级排序,应用程序应该使用二级键扩展键并定义一个分组比较器。
键将使用整个键进行排序,但将使用分组比较器进行分组,以决定在同一个调用中发送哪些键和值以进行缩减。
分组比较器是通过Job.setGroupingComparatorClass(Class)指定的。
排序顺序由Job.setSortComparatorClass(Class)控制。
例如,假设您希望找到重复的web页面,并将它们都标记为“最知名”示例的url。你会这样做:
地图输入键:url
地图输入值:文档
地图输出键:文档校验和,url pagerank
地图输出值:url
瓜分者:通过校验和
OutputKeyComparator:通过校验和然后减少pagerank
OutputValueGroupingComparator:通过校验和
3、Reduce
在这个阶段中,对于排序输入中的每个
调用reduce(对象、Iterable、org.apache.hadoop.mapreduce. reduce. context)方法。
reduce任务的输出通常通过上下文写入记录写入器。写(对象,对象)。
总结:
reducer个数由job.setNumReduceTasks(tasks)控制。
程序有多少个输出结果reducer个数,如果没有reducer那么由mapper个数
mapper个数由inputsplit控制,inputsplit数由块数控制
注意: 如果一个文件大小 小于块大小*1.1 大于块大小 有2个块 有1个inputsplit
10.26
InputFormat:
InputFormat描述了Map-Reduce作业的输入规范。
Map-Reduce框架依赖于作业的InputFormat:
1.验证job的输入规范。
2.将输入文件分解为逻辑inputsplit,每个inputsplit都被分配给一个单独的mapper。
3.提供RecordReader实现,用于从逻辑InputSplit中收集输入记录,以便mapper进行处理。
基于文件的inputformat(通常是FileInputFormat的子类)的默认行为是根据输入文件的总大小(以字节为单位)
将输入拆分为逻辑inputsplit。但是,输入文件的文件系统块大小被视为输入分割的上限。
可以通过mapreduce.input.fileinputformat.split.minsize设置分割大小的下界。
FileInputFormat:
isSplitable(FileSystem fs, Path filename)
是否切分
getSplits(JobConf job, int numSplits)
获取逻辑切分
TextInputFormat:
FileInputFormat默认使用这个
isSplitable是否可切分
判断是否压缩,如果没有压缩返回true
判断是否属于可以切分的压缩模式,若属于返回true
压缩
文件压缩的两大好处:减少存储文件所需要的磁盘空间,并加速数据网络和磁盘上的传输
详见权威指南99页
压缩格式对于Hadoop平台和MR计算时是透明的,Hadoop能够自动将压缩文件进行解压,不需要我们关心。Hadoop会根据文件扩展名自动选择解码器进行解压,也可以人为的指定输入格式。
压缩算法比较:
压缩格式 |
split |
native |
压缩率 |
速度 |
是否hadoop自带 |
linux命令 |
换成压缩格式后,原来的应用程序是否要修改 |
gzip |
否 |
是 |
很高 |
比较快 |
是,直接使用 |
有 |
和文本处理一样,不需要修改 |
lzo |
是 |
是 |
比较高 |
很快 |
否,需要安装 |
有 |
需要建索引,还需要指定输入格式 |
snappy |
否 |
是 |
比较高 |
很快 |
否,需要安装 |
没有 |
和文本处理一样,不需要修改 |
bzip2 |
是 |
否 |
最高 |
慢 |
是,直接使用 |
有 |
和文本处理一样,不需要修改 |
压缩格式 |
codec类 |
算法 |
扩展名 |
多文件 |
splitable |
native |
工具 |
hadoop自带 |
gzip |
GzipCodec |
deflate |
.gz |
否 |
否 |
是 |
gzip |
是 |
bzip2 |
Bzip2Codec |
bzip2 |
.bz2 |
是 |
是 |
否 |
bzip2 |
是 |
lzo |
LzopCodec |
lzo |
.lzo |
否 |
是 |
是 |
lzop |
否 |
snappy |
SnappyCodec |
snappy |
.snappy |
否 |
否 |
是 |
无 |
否 |
LZ4 |
|
LZ4 |
.lz4 |
否 |
|
|
无 |
|
性能对比
压缩格式 |
压缩比 |
压缩速率 |
解压速率 |
gzip |
13.4% |
21 MB/s |
118 MB/s |
lzo |
20.5% |
135 MB/s |
410 MB/s |
snappy |
22.2% |
172 MB/s |
409 MB/s |
bzip2 |
13.2% |
2.4MB/s |
9.5MB/s |
LineRecordReader:
将键视为文件中的偏移量,将值视为行。
next()
给下一个KV赋值
对aa.txt文件可能被分成两个块进行分析分别求奇数偶数行和
如何判断奇偶行???
重写TextInputFormat
isSplitable
getRecordReader
重写LineRecordReader
构造方法
next
编写mapper
编写reducer
编写驱动
注意版本选择老版本的
10.29
RecordReader:
记录阅读器将数据分解为键/值对,以供映射器输入。
Partitioner:
分区键空间。
Partitioner
控制中间映射输出键的分区。键(或键的子集)用于派生
分区,通常通过哈希函数。分区的总数与任务的reduce任务的总数相同。因此,控制
哪个m
reduce任务的中间键(因此记录)被发送到reduce任务。
getPartition获取分区的数量一定要小于等于reduce任务数
shuffle:
将map输出作为输入传递给reduce的过程:详情见权威指南7.3-------》详详情见源码
将map方法的结果写入到缓冲区
进行分区排序溢写到磁盘
合并到磁盘
reduce端请求数据(分区好的数据)
reduce端进行合并
传递给reduce方法
10.30
combiner:
称为map端reduce
减少磁盘IO和网络带宽的使用
如果实现combiner,继承reducer类,一般情况下和自定义的reducer为同一个类
10.31
WritableComparable:
writablecom可以相互比较,任何类型想要被当成hadoop
map-reduce框架的key需要实现此接口
11.01
yarn:
是hadoop的集群资源管理系统,hadoop2之后引进,入了支持mapreduce还支持其他的计算框架
运行机制:
参照权威指南79
与jobtracker和tasktracker相比
可扩展性:
mapreduce 1节点数4000,任务数4000达到瓶颈,yarn节点数10000,任务数100000
可用性:
守护进程失败,可以快速恢复工作
利用率:
mapreduce 1里面是固定分配资源的,yarn动态分配资源
三种调度策略(调度器)
FIFO:先进先出排队执行
容器调度器:
公平调度器:
mapreduce作业运行机制:权威指南185
运行job
向资源管理器请求一个新的应用id
将作业所需的资源上传到共享文件系统
提交作业
调度器分配一个容器,资源管理器在节点管理器帮助下启动一个app master
初始化作业
在共享文件系统获取输入分片
请求资源管理器分配资源
启动其他节点的容器为了map任务和reduce任务
获取共享文件系统里面的资源(作业的配置、jar文件等)
执行map任务和reduce任务
11.02
hadoop HA(高可用)
Quorum Journal Manager:
以共享活动和备用NameNode之间的编辑日志
影响了HDFS集群(导致namenode发生故障)
对于计划外事件(例如计算机崩溃),在操作员重新启动NameNode之前,群集将不可用。
计划维护事件(如NameNode计算机上的软件或硬件升级)将导致群集停机时间窗口。
注意:必须至少有3个JournalNode守护进程,因为编辑日志修改必须写入大多数JN。
这将允许系统容忍单个机器的故障。您也可以运行3个以上的JournalNodes,但为了实际增加系统可以容忍的失败次数,您应该运行奇数个JN(即3,5,7等)。
请注意,当使用N个JournalNodes运行时,系统最多可以容忍(N-1)/ 2个故障并继续正常运行。
ZooKeeper
致力于开发和维护开源服务器,实现高度可靠的分布式协调
故障检测
活跃的NameNode选举
ZKFailoverController (ZKFC)是一个新的组件,它是一个动物管理员客户端,还监控和管理NameNode的状态。
每个运行NameNode的机器也运行ZKFC, ZKFC负责:
Health monitoring
zookeeper会话管理
ZooKeeper-based选举
11.05
zookeeper:
是hadoop的分布式协调服务
特点:
是简单的 核心是精简的文件系统
富有表现力的 用于实现多种协调数据结构协议,包括:分布式队列、分布式锁、一组 节点的领导者选举
高可用性
松耦合交互方式
资源库
高性能
zookeeper服务有两种不同运行模式:
一种是独立模式即只有一个zookeeper服务器。比较适合测试环境,但是不能保证高可用性和可恢复性。
一种是在生产环境中的zookeeper通常以复制模式运行在一个计算机集群上,这个计算机集群通常被称为集合体。通常使用复制来实现高可用性,只要集合体重半数以上的机器处于可用状态,就能提供服务。
在zookeeper设计中,以下几点考虑保证了数据一致性: