1,. Hadoop常用端口号
作用 | hadoop2.x | Hadoop3.x |
---|---|---|
访问HDFS端口 | 50070 | 9870 |
访问MR执行情况端口 | 8088 | 8088 |
历史服务器 | 19888 | 19888 |
客户端访问集群端口 | 9000 | 8020 |
2. HDFS读流程和写流程
-
读流程
-
Client 向 NameNode 发起 RPC 请求,来确定请求文件 block 所在的位置;
-
NameNode 会视情况返回文件的部分或者全部 block 列表,对于每个 block,NameNode 都会返回含有该 block 副本的 DataNode 地址;
-
这些返回的 DataNode 地址,会按照集群拓扑结构得出 DataNode 与客户端的距离,然后进行排序,排序两个规则:网络拓扑结构中距离Client近的排靠前;心跳机制中超时汇报的 DataNode 状态为 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 会合并成一个完整的最终文件。
-
写流程
-
client 发起文件上传请求,通过 RPC 与 NameNode 建立通讯,NameNode 检查目标文件是否已存在,父目录是否存在,返回是否可以上传;
-
client 请求第一个 block 该传输到哪些 DataNode 服务器上;
-
NameNode 根据配置文件中指定的备份数量及副本放置策略进行文件分配,返回可用的 DataNode 的地址,如:A,B,C;
-
client 请求3台 DataNode 中的一台A上传数据(本质上是一个 RPC 调用,建立 pipeline),A收到请求会继续调用B,然后B调用C,将整个 pipeline 建立完成,后逐级返回 client;
-
client 开始往A上传第一个 block(先从磁盘读取数据放到一个本地内存缓存),以 packet 为单位(默认64K),A收到一个 packet 就会传给B,B传给C;A每传一个 packet 会放入一个应答队列等待应答。
-
数据被分割成一个个 packet 数据包在 pipeline 上依次传输,在 pipeline 反方向上,逐个发送 ack(ack 应答机制),最终由pipeline中第一个 DataNode 节点A将 pipeline ack 发送给client;
-
当一个 block 传输完成之后,client 再次请求 NameNode 上传第二个 block 到服务器。
3. MapReduce流程
计算流程是: map阶段 ---> shuffle阶段 ---> reduce阶段
-
map阶段:在进行map计算之前,mapreduce会根据输入文件计算输入分片(input split),每个输入分片(input split)针对一个map任务,默认一个block对应一个切片。一个切片对应一个MapTask, 切片完成后开始执行自定义map代码逻辑
-
shuffle阶段:
-
Mapper任务结束后产生<K2,V2>的输出,这些输出先存放在缓存中,每个map有一个环形内存缓冲区,用于存储任务的输出。默认大小100MB(io.sort.mb属性),一旦达到阀值0.8(io.sort.spil l.percent),一个后台线程就把内容写到(spill)Linux本地磁盘中的指定目录(mapred.local.dir)下的新建的一个溢出写文件。
-
写磁盘前,要进行partition、sort和combine等操作。通过分区,将不同类型的数据分开处理,之后对不同分区的数据进行排序,如果有Combiner,还要对排序后的数据进行combine。等最后记录写完,将全部溢出文件合并为一个分区且排序的文件。
-
Reduce阶段:当MapTask执行完成之后开始执行ReduceTask
-
执行ReduceTask之前会先从Map端拉取
-
从map端复制来的数据首先写到reduce端的缓存中,同样缓存占用到达一定阈值后会将数据写到磁盘中,同样会进行partition、combine、排序等过程。如果形成了多个磁盘文件还会进行合并,最后一次合并的结果作为reduce的输入而不是写入到磁盘中。
-
最后将合并后的结果作为输入传入Reduce任务中。
-
最后就是Reduce过程了,在这个过程中产生了最终的输出结果,并将其写到HDFS上。
-
3. Shuffle优化
-
配置方面:
-
增大map阶段的缓冲区大小。
-
map阶段输出结果使压缩;压缩算法使用lzo。
-
增加reduce阶段copy数据线程数。
-
增加副本数,从而提高计算时的数据本地化。
-
-
程序方面:
-
在不影响计算结果的情况下建议使用combiner。
-
输出结果的序列化类型尽量选择占用字节少的类型。
-
-
架构方面:
-
将http改为udp,因为http还要进行3次握手操作。
-
4. Yarn工作机制
-
Yarnrunner向Resourcemanager申请一个Application。
-
rm将该应用程序的资源路径返回给yarnrunner。
-
该程序将运行所需资源提交到HDFS上。
-
程序资源提交完毕后,申请运行mrAppMaster。
-
RM将用户的请求初始化成一个task。
-
其中一个NodeManager领取到task任务。
-
该NodeManager创建容器Container,并产生MRAppmaster。
-
Container从HDFS上拷贝资源到本地。
-
MRAppmaster向RM 申请运行maptask资源。
-
RM将运行maptask任务分配给另外两个NodeManager,另两个NodeManager分别领取任务并创建container。
-
MR向两个接收到任务的NodeManager发送程序启动脚本,这两个NodeManager分别启动maptask,maptask对数据分区排序。
-
MrAppMaster等待所有maptask运行完毕后,向RM申请container,运行reduce task。
-
reduce task向maptask获取相应分区的数据。
-
程序运行完毕后,MR会向RM申请注销自己。
5. Yarn调度器
1)Hadoop调度器重要分为三类:
-
FIFO 、Capacity Scheduler(容量调度器)和Fair Sceduler(公平调度器)。
-
Apache默认的资源调度器是容量调度器;
-
CDH默认的资源调度器是公平调度器。
2)区别:
-
FIFO调度器:支持单队列 、先进先出 生产环境不会用。
-
容量调度器:支持多队列,保证先进入的任务优先执行。
-
公平调度器:支持多队列,保证每个任务公平享有队列资源。
3)在生产环境下怎么选择?
-
大厂:如果对并发度要求比较高,选择公平,要求服务器性能必须OK;
-
中小公司,集群服务器资源不太充裕选择容量。
4)在生产环境怎么创建队列?
-
调度器默认就1个default队列,不能满足生产要求。
-
按照框架:hive /spark/ flink 每个框架的任务放入指定的队列(企业用的不是特别多)
-
按照业务模块:登录注册、购物车、下单、业务部门1、业务部门2
5)创建多队列的好处?
-
因为担心自己或者员工不小心,写递归死循环代码,把所有资源全部耗尽。
-
实现任务的降级使用,特殊时期保证重要的任务队列资源充足。
5. Hadoop宕机
-
如果MR造成系统宕机。此时要控制Yarn同时运行的任务数,和每个任务申请的最大内存。调整参数:yarn.scheduler.maximum-allocation-mb(单个任务可申请的最多物理内存量,默认是8192MB)
-
如果写入文件过快造成NameNode宕机。那么调高Kafka的存储大小,控制从Kafka到HDFS的写入速度。例如,可以调整Flume每批次拉取数据量的大小参数batchsize
6. Hadoop解决数据倾斜方法
1)提前在map进行combine,减少传输的数据量
-
在Mapper加上combiner相当于提前进行reduce,即把一个Mapper中的相同key进行了聚合,减少shuffle过程中传输的数据量,以及Reducer端的计算量。
-
如果导致数据倾斜的key大量分布在不同的mapper的时候,这种方法就不是很有效了。
2)导致数据倾斜的key 大量分布在不同的mapper
(1)局部聚合加全局聚合。
-
第一次在map阶段对那些导致了数据倾斜的key 加上1到n的随机前缀,这样本来相同的key 也会被分到多个Reducer中进行局部聚合,数量就会大大降低。
-
第二次mapreduce,去掉key的随机前缀,进行全局聚合。
-
思想:二次mr,第一次将key随机散列到不同reducer进行处理达到负载均衡目的。第二次再根据去掉key的随机前缀,按原key进行reduce处理。
-
这个方法进行两次mapreduce,性能稍差。
(2)增加Reducer,提升并行度
-
JobConf.setNumReduceTasks(int)
(3)实现自定义分区
-
根据数据分布情况,自定义散列函数,将key均匀分配到不同Reducer
7. 集群资源分配参数(项目中遇到的问题)
-
集群有50台机器,跑mr任务的时候发现5个map任务全都分配到了同一台机器上,这个可能是由于什么原因导致的吗?
-
解决方案:yarn.scheduler.fair.assignmultiple 这个参数 默认是开的,需要关掉