一. 关于Hadoop
1.1 入门
hadoop的组成:
广义:泛指整个hadoop生态圈.
狭义:包含三个, 1. HDFS: 分布式文件管理系统.
2. MapReduce: 分布式计算系统.
3. Yarn: 分布式资源管理系统.
1: 端口号
2.x版本: HDFS 50070 yarn 8088 历史进程 19888 hdfs 8020(默认) 9000
3.x版本: 9870 8088 19888 8020
2: 安装需要的配置文件:
2.x版本: core-site.xml hdfs-site.xml yarn-site.xml
mapred-site.xml 3个env.sh salves;
3.x版本: workers
1.2 简要描述如何安装配置apache的一个开源Hadoop,只描述即可, 无需列出具体步骤,列出具体步骤更好。
1) 准备三台客户机(配置IP,配置主机名...)
2) 安装jdk,安装hadoop
3) 配置JAVA_HOME和HADOOP_HOME
4) 使每个节点上的环境变量生效(source /etc/profile)
5) 准备分发脚本 xsync a) 在/user/atguigu/bin下创建脚本:xsync
6) 明确集群的配置
7) 修改配置文件
a) **core-site.xml
b) **hadoop-env.sh
c) **hdfs-site.xml
d) **yarn-env.sh
e) **yarn-site.xml
f) **mapred-env.sh
g) **mapred-site.xml
h) **配置slaves
8) 分发配置文件 a) **xsync /etc/hadoop
9) 删掉data和logs文件夹
10) 配置ssh(hadoop102,hadoop103)
11) 分发配置文件
12) 格式化hdfs(hdfs namenode -format)
13) 群启hdfs
总结:hadoop的安装其实就是配置文件的修改,首先要上传hadoop的安装包,解压到指定的目录,
然后开始修改配置文件(确保主机配置好了Java环境,hadoop是基于Java开发),
a) **core-site.xml
b) **hadoop-env.sh
c) **hdfs-site.xml
d) **yarn-env.sh
e) **yarn-site.xml
f) **mapred-env.sh
g) **mapred-site.xml
h) **配置slaves
修改完之后分发给其他的主机,就可以启动.
1.3 请列出正常工作的Hadoop集群中Hadoop都分别需要启动哪些进程,它们的作用分别是什么?
1)NameNode: 它是hadoop中的主服务器节点,用来存储源数据。
2)SecondaryNameNode: 辅助节点,辅助NameNode管理元数据信息,以及合并edits日志,减少NN启动时间。
3)DataNode: 从结点,它负责存储具体数据的,每个存储数据的节点运行一个datanode进程。
4)ResourceManager(JobTracker): 负责调度DataNode上的工作。每个DataNode 有一个TaskTracker,它们执行实际工作。
5)NodeManager(TaskTracker)执行任务
6)DFSZKFailoverController(ZKFC)高可用时它负责监控NN的将康状态,并及时的把状态信息写入ZK。
7)JournalNode: 高可用情况下存放namenode的edits日志文件文件。
1.4 元数据的checkpoint
每隔一段时间,会由secondary namenode将namenode上积累的所有edits和一个最新的fsimage下载到本地,并加载到内存进行merge(这个过程称为checkpoint)
二. HDFS
2.1HDFS的体系结构
整体来说他是一个主从架构,一旦主节点挂了,集群将无法工作.
其中包含4个部分:
1.Client 客户端:提供一些shell命令与NameNode进行文件的交互,以及对文件进行切割.
2.NameNode 主节点: 主要管理元数据信息,以及分配副本放在副本放在哪一个主机上.
3.SecondaryNameNode 辅助节点: 辅助NameNode管理元数据信息,以及合并edits日志.
4.DataNode 从节点: 储存具体数据的.
2.2. HDFS的读写流程(笔试题)
写流程 (单独写 hadoop fs -put)
首先客户端会像服务器发送上传请求,经过服务器的校验同意之后,客户端对文件
进行切片;服务器会选择一个合适的主机开始上传,一个Block上传完后接着上传
下一个Block,最后NaameNode更新元数据,上传成功.
细节:1.如何上传Block呢? 会把Block切分成一个更小的单元packet(64K),
与DataNode建立pipeline通信.
2.如何保证packet都能收到成功? DataNode之间ACK通信.
读流程(并发读 hadoop fs -get)
客户端首先会像服务器发起下载请求;然后服务器做一个权限的检查同时对Black
进行一个综合的排序,把Block列表发送给客户端;最后客户端与合适的主机(就近原则)建立
通信,合并Block读取成功.
2.3 小文件处理
1:HDFS不适合小文件存储,因为每个小文件都需要占用一条元数据
2:如何处理这些小文件,最理想的办法是将这些小文件进行归档
3:归档之后,我们既可以访问其中每一个小文件,又使这个归档文件只占用一条元数据
4:以后我们还可以解压归档文件
1) 危害:
是NameNode 内存不够: 128g内存: 128g*1024M*1024kb*1024byte/150字节 大约 9亿个文件
计算: 一个文件对应一个切片 ->maptask线程
2) 解决: archive归档 客户端执行命令
hadoop archive -archiveName test.har -p /config /outputdir
2.4 块大小 副本数
block块 128M 2.X默认
64M 1.X默认
32M 本地模式
256M Hive默认,大厂
3个副本(默认)
2.5 一个DataNode宕机怎么一个回复流程
一般一个集群中都有多个DataNode,它是同来储存具体数据的,一般数据都有备份
,一个挂了删除他的数据重启就ok了.
2.6 NameNode宕机怎么一个恢复流程
一般在高可用集群中,都有一个备用状态的NomeNode;一个活跃状态的NomeNode
挂了,备用的会代替它.(相当于太子继承皇位).
2.7 NameNode管理元数据(SecondaryNameNode 工作机制).
分为两个阶段(画图讲解):
1)第一阶段:namenode启动
(1)第一次启动namenode,创建fsimage和edits文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。
(2)客户端对元数据进行增删改的请求
(3)namenode记录操作日志,更新滚动日志。
(4)namenode在内存中对数据进行增删改查
2)第二阶段:Secondary NameNode工作
(1)Secondary NameNode询问namenode是否需要checkpoint。直接带回namenode是 否检查结果。
(2)Secondary NameNode请求执行checkpoint。
(3)namenode滚动正在写的edits日志
(4)将滚动前的编辑日志和镜像文件拷贝到Secondary NameNode
(5)Secondary NameNode加载编辑日志和镜像文件到内存,并合并。
(6)生成新的镜像文件fsimage.chkpoint
(7)拷贝fsimage.chkpoint到namenode
(8)namenode将fsimage.chkpoint重新命名成fsimage
2.8 NameNode与SecondaryNameNode 的区别与联系?
(1)NameNode负责管理整个文件系统的元数据,以及每一个路径(文件)所对应的数 据块信息。
(2)SecondaryNameNode主要用于定期合并磁盘镜像文件(fsimage)和edits日志文件。
(3)在主namenode发生故障时(假设没有及时备份数据),可以从SecondaryNameNode 恢复数据。
2.9 Hadoop的联邦机制
NameNode的使用资源受到物理服务器的限制,不能满足业务需求.
这个时候就需要采用多台NN组成联邦,共同管理的DN作为block的公共存储。
三. MapReduce(shuffle过程以及优化)
Map阶段shuffle(MapTask工作机制):
(1)Read阶段:Map Task通过用户编写的RecordReader,从输入InputSplit中
解析出一个个 key/value。
(2)Map阶段:该节点主要是将解析出的key/value交给用户编写map()函数处理,
并产生一 系列新的key/value。
(3)Collect收集阶段:在用户编写map()函数中,当数据处理完成后,一般会调用
OutputCollector.collect()输出结果。在该函数内部,它会将生成的
key/value分区(调用Partitioner), 并写入一个环形内存缓冲区中。
4)Spill阶段:即“溢写”,当环形缓冲区满后,MapReduce会将数据写到本地磁盘
上,生成 一个临时文件。需要注意的是,将数据写入本地磁盘之前,先要对数据进
行一次本地排序,并在必 要时对数据进行合并、压缩等操作。
溢写阶段详情:
步骤1:利用快速排序算法对缓存区内的数据进行排序,排序方
式是,先按照分区编号partition 进行排序,然后按照key进行排序。这样,
经过排序后,数据以分区为单位聚集在一起,且同一分 区内所有数据按照key有序。
步骤2:按照分区编号由小到大依次将每个分区中的数据写入任务工作目录下的临时文件 output/spillN.out(N表示当前溢写次数)中。如果用户设置了Combiner,则写入文件之前,对每 个分区中的数据进行一次聚集操作。
步骤3:将分区数据的元信息写到内存索引数据结构SpillRecord中,其中
每个分区的元信息包 括在临时文件中的偏移量、压缩前数据大小和压缩后
数据大小。如果当前内存索引大小超过1MB, 则将内存索引写到文件output/spillN.out.index中。
(5)Combine阶段:当所有数据处理完成后,MapTask对所有临时文件进行一次合并,以确 保最终只会生成一个数据文件。
当所有数据处理完后,MapTask会将所有临时文件合并成一个大文件,并保存到文件 output/file.out中,同时生成相应的索引文件output/file.out.index。
在进行文件合并过程中,MapTask以分区为单位进行合并。对于某个分区,它
将采用多轮递归 合并的方式。每轮合并io.sort.factor(默认100)个文件,并将
产生的文件重新加入待合并列表中, 对文件排序后,重复以上过程,直到最终得到
一个大文件。
让每个MapTask最终只生成一个数据文件,可避免同时打开大量文件和同时读取大量小文件产 生的随机读取带来的开销。
Reduce阶段shuffle(ReduceTask工作机制):
(1)Copy阶段:ReduceTask从各个MapTask上远程拷贝一片数据,并针对某一片
数据,如果 其大小超过一定阈值,则写到磁盘上,否则直接放到内存中。
(2)Merge阶段:在远程拷贝数据的同时,ReduceTask启动了两个后台线程对内存
和磁盘上 的文件进行合并,以防止内存使用过多或磁盘上文件过多。
(3)Sort阶段:按照MapReduce语义,用户编写reduce()函数输入数据是按key进
行聚集的一 组数据。为了将key相同的数据聚在一起,Hadoop采用了基于排序的策
略。由于各个MapTask已 经实现对自己的处理结果进行了局部排序,因此,
ReduceTask只需对所有数据进行一次归并排序 即可。
(4)Reduce阶段:reduce()函数将计算结果写到HDFS上。
3.1 hadoop中combiner和partition的作用
combiner(规约):是发生在map的最后一个阶段,父类就是Reducer,意义就是对每一个
maptask的输出进行局部汇总,挺高网络IO的香炉,进而提高reducer的执行效率。
partition(分区):主要作用将map阶段产生的所有kv对分配给不同的reducer task处
理,进而减少reduce的负载,到达提高效率的目的.
3.2 Mapreduce 的 map 数量 和 reduce 数量是由什么决定的 ,怎么配置
map数量由切片决定,理论上一个切片对应一个Block(实际多一点点),有多少切片
就有多少maptask线程,reduce数量自己配置。
3.3 Hadoop总job和Tasks之间的区别是什么?
Job是我们对一个完整的mapreduce程序的抽象封装
Task是job运行时,每一个处理阶段的具体实例,如maptask,reducetask,
maptask和reducetask都会有多个并发运行的实例.
3.4 简述hadoop实现join的几种方法及每种方法的实现。
1)reduce side join
Map端的主要工作:为来自不同表(文件)的key/value对打标签以区别不同来源
的记录。然后用连接字段作为key,其余部分和新加的标志作为value,最后进
行输出。
Reduce端的主要工作:在reduce端以连接字段作为key的分组已经完成,我们
只需要在每一个 分组当中将那些来源于不同文件的记录(在map阶段已经打标
志)分开,最后进行合并就ok了。
2)map join 在map端缓存多张表,提前处理业务逻辑,这样增加map端业务,减少
reduce端数据的压力, 尽可能的减少数据倾斜。 具体办法:采用distributedcache
(1)在mapper的setup阶段,将文件读取到缓存集合中。
(2)在驱动函数中加载缓存。
job.addCacheFile(new URI("file:/e:/mapjoincache/pd.txt"));// 缓存普通文件到task运行
3.5 请描述mapReduce中combiner的作用是什么,一般使用情 景,哪些情况不需要,及和reduce的区别?
1)Combiner的意义就是对每一个maptask的输出进行局部汇总,以减小网络传输量。
2)Combiner能够应用的前提是不能影响最终的业务逻辑,而且,Combiner的输出kv应该跟reducer 的输入kv类型要对应起来。
3)Combiner和reducer的区别在于运行的位置。
Combiner是在每一个maptask所在的节点运行;
Reducer是接收全局所有Mapper的输出结果。
3.6 请简述hadoop怎样实现二级排序。
对map端输出的key进行排序,实现的compareTo方法。 在compareTo方法中排序的条件有二 个。
四.Yarn
4.1yarn的三大调度策略
4.2 为什么会产生yarn,它解决了什么问题,有什么优势?
Yarn最主要的功能就是解决运行的用户程序与yarn框架完全解耦。
Yarn上可以运行各种类型的分布式运算程序(mapreduce只是其中的一种),比如mapreduce、 storm程序,spark程序……
五. Hadoop优化
5.1 mapreduce 跑的慢的原因?
Mapreduce 程序效率的瓶颈在于两点:
1)计算机性能 CPU、内存、磁盘健康、网络
2)I/O 操作优化
(1)数据倾斜
(2)map和reduce数设置不合理
(3)reduce等待过久
(4)小文件过多
(5)大量的不可分块的超大文件
(6)spill次数过多
(7)merge次数过多等
5.2 mapreduce 优化方法。
1)数据输入:
(1)合并小文件:在执行mr任务前将小文件进行合并,大量的小文件会产生大量的map任务,
增大map任务装载次数,而任务的装载比较耗时,从而导致 mr运行较慢。
(2)采用archive归档 一条命令
2)map阶段
(1)减少spill次数:通过调整io.sort.mb及sort.spill.percent参数值,增大触发spill的内存上限,减少spill次数,从而减少磁盘 IO。
(2)在 map 之后先进行combine处理,减少 I/O。
3)reduce阶段
(1)合理设置map和reduce数:两个都不能设置太少,也不能设置太多。太少,会导致task等待,延长处理时间;太多,会导致 map、reduce任务间竞争资源,造成处理超时等错误。
(2)设置map、reduce共存:调整slowstart.completedmaps参数,使map运行到一定程度后, reduce也开始运行,减少reduce的等待时间。
(3)规避使用reduce,因为Reduce在用于连接数据集的时候将会产生大量的网络消耗。
从而减少IO开销: mapred.job.reduce.input.buffer.percent,默认为0.0。当值大于0的时候,会保留指定比例的内存读buffer中
的数据直接拿给reduce使用。这样一来,设置buffer需要内存,读取数据需要内存, reduce计算也要内存,所以要根据作业的运行情况进行调整。
4)IO传输
(1) orc存储格式 snappy压缩方式
5)数据倾斜问题
(1)数据倾斜现象:
数据频率倾斜——某一个区域的数据量要远远大于其他区域。
数据大小倾斜——部分记录的大小远远大于平均值。
(2)减少数据倾斜的方法
方法1:抽样和范围分区
可以通过对原始数据进行抽样得到的结果集来预设分区边界值。
方法2:自定义分区
另一个抽样和范围分区的替代方案是基于输出键的背景知识进行自定义分
区。例如,如果map 输出键的单词来源于一本书。其中大部分必然是省略
词(stopword)。那么就可以将自定义分区将 这部分省略词发送给固定
的一部分reduce实例。而将其他的都发送给剩余的reduce实例。
方法3:Combiner
使用Combine可以大量地减小数据频率倾斜和数据大小倾斜。在可能的情况下,combine的目 的就是聚合并精简数据
5.3 MapReduce怎么解决数据均衡问题,如何确定分区号?
1.数据均衡问题指的就是某个节点或者某几个节点的任务运行的比较慢,拖慢了
整个Job的进度。 实际上数据均衡问题就是数据倾斜问题,解决方案同解决数
据倾斜的方案。
2.MapReduce中分区默认是按hashcode来分的,用户可以自定义分区类,需要
继承系统的Partitioner 类,重写getPartition()方法即可。
六. ZK高频面试
6.1 请简述ZooKeeper的选举机制
zookeeper默认的算法是FastLeaderElection,采用投票数大于半数则胜
出的逻辑。(过半原则)
1:第一次启动选举
核心点是判断投票数是否过半,然后比较myid的值
2:Leader宕机选举
核心点是比较谁的数据最新(Mzxid 越大月新),如果数据都是最新,
则比较myid的值.
6.2 ZooKeeper对节点的watch监听是永久的吗?为什么?
不是。
官方声明:一个Watch事件是一个一次性的触发器,当被设置了Watch的数据发生了改变的时
候,则服务器将这个改变发送给设置了Watch的客户端,以便通知它们。
为什么不是永久的,举个例子,如果服务端变动频繁,而监听的客户端很多情况下,每次变动
都要通知到所有的客户端,这太消耗性能了。
一般是客户端执行getData(“/节点A”,true),如果节点A发生了变更或删除,客户端会得到它的
watch事件,但是在之后节点A又发生了变更,而客户端又没有设置watch事件,就不再给客户端发
送。
在实际应用中,很多情况下,我们的客户端不需要知道服务端的每一次变动,我只要最新的数
据即可。
6.3 ZooKpeer的结点类型
Znode有两种:
1. 临时节点: 一旦会话结束,临时节点将被自动删除,当然可以也可以
手动删除。临时节点不允许拥有子节点。
普通临时节点;
序列化临时节点;
2. 永久节点: 该节点的生命周期不依赖于会话,并且只有在客户端显
示执行删除操作的时候,他们才能被删除。
普通永久节点;
序列化永久节点;
PERSISTENT:永久节点
EPHEMERAL:临时节点
PERSISTENT_SEQUENTIAL:永久节点、序列化
EPHEMERAL_SEQUENTIAL:临时节点、序列化
6.4 ZooKeeper的部署方式有哪几种?集群中的角色有哪些?集 群最少需要几台机器?
ZooKeeper的部署方式有单机模式和集群模式,集群中的角色有Leader和Follower,
集群最少3 (2N+1)台,根据选举算法,应保证奇数。
6.5 ZooKeeper集群如果有3台机器,挂掉一台是否还能工作?挂 掉两台呢?
对于ZooKeeper集群,过半存活即可使用。
6.6 谈谈你对ZooKeeper的理解?
1. Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题。
ZooKeeper提供的服务包括:分布式消息同步和协调机制、服务器节点动态上下线、统一配置管理、
负载均衡、集群管理等。
2. ZooKeeper提供基于类似于Linux文件系统的目录节点树方式的数据存储,即分层命名空间。
Zookeeper 并不是用来专门存储数据的,它的作用主要是用来维护和监控你存储的数据的状态变
化,通过监控这些数据状态的变化,从而可以达到基于数据的集群管理,ZooKeeper节点的数据上
限是1MB。
3. 我们可以认为Zookeeper=文件系统+通知机制,
对于ZooKeeper的数据结构,每个子目录项如 NameService 都被称作为 znode,这个 znode
是被它所在的路径唯一标识,如 Server1 这个 znode 的标识为 /NameService/Server1;
znode 可以有子节点目录,并且每个 znode 可以存储数据,注意 EPHEMERAL 类型的目录
节点不能有子节点目录(因为它是临时节点);
4. znode 可以是临时节点,一旦创建这个 znode 的客户端与服务器失去联系,这个 znode 也
将自动删除,Zookeeper 的客户端和服务器通信采用长连接方式,每个客户端和服务器通过心跳
来保持连接,这个连接状态称为 session,如果 znode 是临时节点,这个 session 失效,znode 也
就删除了;
5. znode 的目录名可以自动编号,如 App1 已经存在,再创建的话,将会自动命名为 App2;
6. znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变 化可以通知设置监控的客户端,
这个是 Zookeeper 的核心特性,Zookeeper 的很多功能都是基 于这个特性实现的,后面在典型的应用场景中会有实例介绍。
6.7 请谈谈对ZooKeeper对事务性的支持?
ZooKeeper对于事务性的支持主要依赖于四个函数,zoo_create_op_init,zoo_delete_op_init,
zoo_set_op_init以及zoo_check_op_init。每一个函数都会在客户端初始化一个operation,客户端
程序有义务保留这些operations。当准备好一个事务中的所有操作后,可以使用zoo_multi来提交所
有的操作,由zookeeper服务来保证这一系列操作的原子性。也就是说只要其中有一个操作失败了,
相当于此次提交的任何一个操作都没有对服务端的数据造成影响。Zoo_multi的返回值是第一个失
败操作的状态信号。
6.8 ZooKeeper集群中服务器之间是怎样通信的?
Leader服务器会和每一个Follower/Observer服务器都建立TCP连接,同时为每个F/O都创建一
个叫做LearnerHandler的实体。LearnerHandler主要负责Leader和F/O之间的网络通讯,包括数据
同步,请求转发和Proposal提议的投票等。Leader服务器保存了所有F/O的LearnerHandler。
6.9 ZooKeeper是否支持动态进行机器扩容?如果目前不支持,那 么要如何扩容呢?
ZooKeeper中的动态扩容其实就是水平扩容,Zookeeper对这方面的支持不太好,目前有两种
方式:
全部重启:关闭所有Zookeeper服务,修改配置之后启动,不影响之前客户端的会话。
逐个重启:这是比较常用的方式。
6.10 ZooKeeper是否会自动进行日志清理?如何进行日志清理?
zk自己不会进行日志清理,需要运维人员进行日志清理。