大数据开发八股文总结——Hadoop_大数据八股文

显示文件内容 hadoop fs -cat 文件名字
修改文件属性 -chmod -chown
创建路径 -mkdir
从HDFS的一个路径拷贝到另一个路径 -cp
在HDFS中移动文件 -mv
设置文件的副本数量 -setrep




---


### 7.HDFS的写数据流程


![在这里插入图片描述](https://img-blog.csdnimg.cn/0d091ee83cb74c409ead1699d12aa60d.png)  
 1)客户端通过分布式文件系统模块(Distributed FileSystem)向NameNode请求上传文件,NameNode检查目标文件是否存在,父目录是否存在;


2)NameNode返回是否可以上传文件;


3)客户端请求第一个Block上传到哪几个DataNode服务器上;


4)NameNode返回3个DataNode节点,分别为dn1,dn2,dn3;


5)客户端通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,dn2调用dn3,将这个通信管道建立完;


6)dn1,dn2,dn3逐级应答客户端;


7)客户端开始往dn1上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,dn1收到一个Packet传给dn2,dn2传给dn3,dn1每传一个packet会放入一个应答队列等待应答;


8)当一个Block传输完成后,客户端再次请求NameNode上传第二个Block的服务器(重复执行3-7步)。




---


### 8.HDFS的读数据流程


![在这里插入图片描述](https://img-blog.csdnimg.cn/fde45577543c4022bf9a151b1cfae361.png)


1)客户端通过分布式系统模块(Distributed FileSystem)向NameNode请求下载文件,NameNode通过查询元数据,找到文件所在的DataNode地址。


2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。


3)DataNode开始传输数据给客户端(从磁盘里面读取数据流,以Packet为单位做校验)


4)客户端以Packet为单位接收,现在本地缓存,然后写入目标文件。




---


### 9.NN 和 2NN 工作机制


**1)Fsimage文件:** NameNode 内存中元数据序列化后形成的文件,用于在磁盘中备份元数据。


**2)Edits文件:** 每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits文件中;记录客户端更新元数据信息的每一步操作(可通过 Edits 运算出元数据)。


**一旦NameNode断电,就会合并Fsimage文件和Edits文件,合成元数据。引入的Secondary NameNode 专门用于合并两个文件。**




---


![在这里插入图片描述](https://img-blog.csdnimg.cn/afee85c766b541d2aeec5b8e71a4e5f2.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/e8855c2dc6264723b5729394221ad203.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/9d00d477264f4aa087e9b059e500ce2e.png)  
 **第一阶段:NameNode 启动**  
 (1)第一次启动 NameNode 格式化后,创建 Fsimage 和 Edits 文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。


(2)客户端对元数据进行增删改的请求。


(3)NameNode 记录操作日志,更新滚动日志。


(4)NameNode 在内存中对数据进行增删改。


**第二阶段: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。




---


### 扩展问题:为什么HDFS不适合批量存储小文件?


**小文件的定义:**  
 文件大小小于或者等于30M的文件


**HDFS小文件带来危害:**  
 **(1)小文件数量过多(例如图片)会占用批量占用Namenode的内存**,因为每个存储在HDFS中的文件的**元数据**(包括目录树,位置信息,命名空间镜像fsimage,文件编辑信息edits)都会在Namenode中占用**150B**的内存,如果Namenode存储空间满了,就不能继续存储新文件了。  
 **(2)如果有多小文件,会造成寻道时间>=读取文件时间(传输文件时间 = 寻道时间+读取文件时间)**,这与HDFS的原理相违背,HDFS的设计是为了**减小寻道时间,使其远小于读取文件的时间**。Hive或者Spark计算的时候会影响他们的速度,因为Spark计算时会将数据从硬盘读到内存,零碎的文件将产生较多的寻道过程。  
 (3)流式读取的方式,不适合多用户写入,以及任意位置写入。如果访问小文件,则必须从一个Datanode跳转到另外一个Datanode,这样大大降低了读取性能。


![在这里插入图片描述](https://img-blog.csdnimg.cn/88b482dfafb0465687db4b776eec258c.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/7dd22e233d924532b40b15df40f6c4f3.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/41fe5f4bdcec4bc6a11096d9f575f8fd.png)




---


### 扩展问题:数据在DataNode中如何存储?


HDFS默认的数据存储块是64MB,现在新版本的hadoop环境(2.7.3版本后),默认的数据存储块是128MB。


一个文件如果小于128MB,则按照真实的文件大小独占一个数据存储块,存放到DataNode节点中。**同时 DataNode一般默认存三份副本,以保障数据安全。** 同时该文件所存放的位置也写入到NameNode的内存中,如果有Secondary NameNode高可用节点,也可同时复制一份过去。NameNode的内存数据将会存放到硬盘中,如果HDFS发生重启,将产生较长时间的元数据从硬盘读到内存的过程。


如果一个文件大于128MB,则HDFS自动将其拆分为128MB大小,存放到HDFS中,并在NameNode内存中留下其数据存放的路径。不同的数据块将存放到可能不同的DataNode中。




---


### 扩展问题:HDFS的文件存储格式有哪些?


[Hadoop文件格式学习]( )  
 [HDFS的文件存储格式以及HDFS异构存储和存储策略]( )


**大数据存储数据,99%以上的场景都是使用的是列式存储。**




---


## MapReduce


### 1.什么是MapReduce?


MapReduce是一个**分布式运算程序的编程框架**,它的核心功能是将用户编写的业务逻辑代码和自带默认组件代码整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上。


**扩展理解:**  
 MapReduce是一种分布式计算模型,它主要用于大规模数据的处理和分析。在MapReduce模型中, **Map函数**和**Reduce函数**都是非常重要的组成部分,它们分别在**数据预处理**和**结果合并**阶段发挥重要作用。


**Map函数**一般用来对数据进行预处理。当MapReduce模型读取数据时, Map函数会对每个数据块进行处理。Map函数的输入是键-值对输出也是键-值对。Map函数可以将输入的键-值对映射为任意数量的键-值对输出。例如,一个典型的Map函数可以将一个文档分解为单词,并将每个单词映射为一个键-值对。在这个例子中,键是单词,值是1或者是出现次数。Map函数的处理结果会被传递给Reduce函数进行处理。


**Reduce函数**则用来合并Map函数输出的结果。当MapReduce模型读取完所有数据后,Reduce 函数会对合并后的数据进行处理。Reduce函数的输入是一个键和一个值构成的集合, 输出也是一个键和一个值构成的集合。Reduce 函数会对所有输入的键-值对进行分组,并对每个键的一组值进行处理。Reduce 函数的处理结果会成为MapReduce模型的输出。例如,一个典型的Reduce函数可以将相同单词的计数值相加。在这个例子中,Reduce函数的输出是一个单词及其在文档中出现的总次数。




---


### 2.MapReduce的优缺点


![在这里插入图片描述](https://img-blog.csdnimg.cn/5e8f4f3e1e984476990ee5ea8de7c941.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/9811f580a0714345888c3a6b923fb35e.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/a5d3accdf1dd4bc5b91dbfc67ccbc62c.png)




---


### 3.MapReduce的核心编程思想


![在这里插入图片描述](https://img-blog.csdnimg.cn/0ad70b4bb216440b963880430b7a4592.png)


1)MapReduce运算程序一般分成两个阶段,Map阶段和Reduce阶段。


2)Map阶段的Map Task并发实例,完全并发运行,互不相干。


3)Reduce阶段的Reduce Task并发实例互不相干,但是他们的数据依赖于上一个阶段的所有Map Task并发实例的输出。


4)MapReduce编程模型只能包含一个Map阶段和一个Reduce阶段,如果用户的业务逻辑非常复杂,那就只能多个MapReduce程序,串行运行。


### 4.MapReduce进程


**一个完整的MapReduce程序在分布式运行时有三类实例进程:**


**1) MrAppMaster:** 负责整个程序的过程调度及状态协调。


**2) MapTask:** 负责Map阶段的整个数据处理流程。


**3) ReduceTask:** 负责Reduce阶段的整个数据处理流程。




---


### 5.Hadoop序列化


**1)序列化:** 序列化就是把内存中的对象,转换成字节序列以便于存储到磁盘(持久化)和网络传输。


**2)反序列化:** 将收到字节序列或者是磁盘的持久化数据,转换成内存中的对象。


**3)为什么要序列化:**


“活的”对象只生存在内存里,关机断电就没有了,而且“活的”的对象只能在本地的进程中使用,不能被发送到网络上的另一台计算机。然而序列化可以存储“活的”对象,可以将活的对象发送到远程计算机中。


**4)为什么不用Java的序列化:**


Java的序列化是一个重量级序列化框架,一个对象被序列化后,会附带很多额外的信息,不便于在网络中高效传输,所以,Hadoop自己开发了一套序列化机制。


**5)Hadoop序列化的特点:**


**紧凑:** 高效使用存储空间


**快速:** 读写数据的额外开销小


**互操作:** 支持多语言的交互


**6)自定义bean对象实现序列化接口步骤:**


1.必须实现Writable接口;


2.反序列化时,需要反射调用空参构造函数,所以必须有空参构造;


3.重写序列化方法;


4.重写反序列化方法;


5.注意:反序列化和序列化的顺序完全一致。


6.要想把结果显示文件中,需要重写toString方法,可用”\t”分开,方便后续用


7.如果需要将自定义的bean放在key中传输,则还需要实现Comparable接口,因为MapReduce框中的Shuffle过程要求对key必须能排序。




---


### 6.MapReduce框架原理


#### 6.1 InputFormat


**1)MapTask并行度决定机制**


**数据块:** Block是HDFS物理上把数据分成一块一块,数据块是HDFS的数据存储单位。


**数据切片:** 数据切片是MapReduce程序计算输入数据的单位,一个切片会对应启动一个MapTask。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/5c0cda1089e94d9a9bcde199dadd71e1.png)  
 **2)FileInputFormat切片源码解析**


![在这里插入图片描述](https://img-blog.csdnimg.cn/734f3abf3da243559d1eaa43621ae348.png)


**3)切片大小的参数配置:**


计算切片大小的公式:`Math.max(minSize,Math.min(maxSize,blockSize))`


切片大小的设置:


maxSize(切片最大值):参数如果调得比blockSize小,则会让切片变小,而且就等于配置的这个参数的值。


minSize(切片最小值):参数调得比blockSize大,则会让切片变得比blockSize大。


#### 6.2 判定一个job的Map和Reduce数量


1)**map数量**由处理的数据分成的**block数量**决定,  
 `default_num = total_size / split_size`。


2)**reduce数量**由`job.setNumReduceTasks(x)`决定。




---


### 7.MapReduce工作机制


#### 7.1 MapTask工作机制


![在这里插入图片描述](https://img-blog.csdnimg.cn/08d447734aff46158f290d0589442ec3.png)  
 **1)Read阶段:** MapTask通过用户编写的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(默认 10)个文件,并将产生的文件重新加入待合并列表中,对文件排序后,重复以上过程,直到最终得到一个大文件。


让每个 MapTask 最终只生成一个数据文件,可避免同时打开大量文件和同时读取大量  
 小文件产生的随机读取带来的开销。


#### 7.2 ReduceTask 工作机制


![在这里插入图片描述](https://img-blog.csdnimg.cn/2e19e19e67784133973dae620129dd6f.png)  
 **1)Copy阶段:** ReduceTask 从各个 MapTask 上远程拷贝一片数据,并针对某一片数据,如果其大小超过一定阈值,则写到磁盘上,否则直接放到内存中。


**2)Merge阶段:** 在远程拷贝数据的同时,ReduceTask 启动了两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或磁盘上文件过多。


**3)Sort阶段:** 按照 MapReduce 语义,用户编写 reduce()函数**输入数据是按 key 进行聚集的一组数据**。为了将 key 相同的数据聚在一起,Hadoop 采用了基于排序的策略。**由于各个 MapTask 已经实现对自己的处理结果进行了局部排序,因此,ReduceTask 只需对所有数据进行一次归并排序即可。**


**4)Reduce阶段:** reduce()函数将计算结果写到 HDFS 上。


#### 7.3 设置 ReduceTask 并行度(个数)


ReduceTask 的并行度同样影响整个 Job 的执行并发度和执行效率,但与 MapTask 的并  
 发数由切片数决定不同,**ReduceTask 数量的决定是可以直接手动设置:**



// 默认值是 1,手动设置为 4
job.setNumReduceTasks(4);


![在这里插入图片描述](https://img-blog.csdnimg.cn/8ab0dff6a0fb48fbb2990f5092b23821.png)




---


### 8.MapReduce中的Shuffle机制


Map方法之后,Reduce方法之前的数据处理过程称之为Shuffle。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/b4b01965cbfa4b4d929a2fc8b7ea1ff3.png)  
 分区、排序、溢写、然后拷贝到对应Reduce机器上,可以选择增加Combiner,压缩溢写的文件。


**combiner的作用:**


combiner对每一个MapTask的输出进行局部汇总,以减小网络传输量。


combiner在每一个MapTask所在的节点运行;


reduce是接收全局所有map的输出结果。




---


### 9.Partition分区


1)将统计结果按照条件输出到不同分区中。


2)在没有自定义分区的情况下,数据被送到reduce端前如何分区?


根据默认的`HashPartitioner`,逻辑是根据`key`的**哈希值**和`numReduces`来**返回一个分区号**,`key.hashCode()`&`Integer.MAXVALUE % numReduces`


3)自定义Partition分区步骤:


步骤1:自定义类继承Partitioner,重写getPartition()方法。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/e94e068aae9f4f1d84891c335ad8464c.png)


步骤2:在Job驱动中,设置自定义Partitioner。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/316167e98c1747838fc6c2423a4f7cb4.png)


步骤3:自定义Partitioner后,要根据自定义Partitioner的逻辑设置相应数量的ReduceTask。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/41e15e024b7d4f5e8d3c29e57e9c9cb3.png)


![在这里插入图片描述](https://img-blog.csdnimg.cn/409b74a41d8e437293e15cf6265b1836.png)




---


### 10.Join多种应用


#### 10.1 Reduce Join


![在这里插入图片描述](https://img-blog.csdnimg.cn/1a0527a20b8949f3b709134e567677db.png)


#### 10.2 Reduce Join 案例实操


![在这里插入图片描述](https://img-blog.csdnimg.cn/f19ea5703f604edd82bdcb1152937125.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/81d45b1b791d4a0bac2e0ba6ed3ba56e.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/cb6f86d11aaf40ada0fa79e0595a4fe7.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/94637970c47e4543afb49209d9addd32.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/f7e7dad7d4e245889282fff003f74e26.png)


#### 10.3 Reduce Join缺点及解决方案


![在这里插入图片描述](https://img-blog.csdnimg.cn/8df484910aa344a4819b0a5408dc7dc5.png)


#### 10.4 Map Join


**1.使用场景**  
 Map Join 适用于一张表十分小、一张表很大的场景。


**2.优点**


**思考:在 Reduce 端处理过多的表,非常容易产生数据倾斜。怎么办?**


在 Map 端缓存多张表,提前处理业务逻辑,这样增加 Map 端业务,减少 Reduce 端数据的压力,尽可能的减少数据倾斜


**3.具体办法:采用 DistributedCache**


(1)在 Mapper 的 setup 阶段,将文件读取到缓存集合中。


(2)在驱动函数中加载缓存。



// 缓存普通文件到 Task 运行节点。
job.addCacheFile(new URI(“file://e:/cache/pd.txt”));


#### 10.5 Map Join 案例实操


![在这里插入图片描述](https://img-blog.csdnimg.cn/f8613990e066465fa160c341fca5752b.png)


![在这里插入图片描述](https://img-blog.csdnimg.cn/3b3a0348fcbe474e80a3cfa26c8ca12b.png)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/382125980953427086f7c8c257583fec.png)




---


### 11.计数器应用


![在这里插入图片描述](https://img-blog.csdnimg.cn/b2306a9a5a2a4881888ef59b1f5f0894.png)




---


### 12.数据清洗(ETL)


在运行核心业务 MapReduce 程序之前,往往要先对数据进行清洗,清理掉不符合用户  
 要求的数据。清理的过程往往只需要运行 Mapper 程序,不需要运行 Reduce 程序。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/2de2f9cde0f54aee9e19058f55de441f.png)




---


## Hadoop数据压缩


### 压缩的优缺点


**优点:**


减少磁盘I/O,减少磁盘存储空间


**缺点:**


增加CPU开销




---


### 压缩方式选择


压缩选择时应考虑:压缩/解压速度,压缩率,压缩后是否支持切片。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/2e9ce8c8c2494f379362c9b116474451.png)  
 Gzip:压缩率高,不支持切片,压缩/解压速度一般。


Bzip2:压缩率高,支持切片,压缩/解压速度较慢。


Lzo:压缩/解压速度快,支持切片,压缩率一般。


Snappy:压缩和解压速度快,不支持切片,压缩速度一般。




---


## Hadoop企业优化


### 1.MapReduce跑的慢的原因


**MapReduce程序效率的瓶颈在于两点:**


**1 计算机性能**  
 CPU、内存、磁盘健康、网络


**2 I/O 操作优化**  
 (1) 数据倾斜  
 (2) Map和Reduce数设置不合理  
 (3) Map运行时间太长,导致Reduce等待过久  
 (4) 小文件过多  
 (5) 大量的不可分块的超大文件  
 (6) Spill次数过多  
 (7) Merge次数过多等。




---


### 2.MapReduce 优化方法


MapReduce 优化方法主要从六个方面考虑:数据输入、Map 阶段、Reduce 阶段、IO 传  
 输、数据倾斜问题和常用的调优参数。


#### 2.1 数据输入


**(1)合并小文件:** 在执行MR任务前将小文件进行合并,大量的小文件会产生大量的Map任务,增大Map任务装载次数,而任务的装载比较耗时,从而导致MR运行较慢。  
 **(2)采用Combine TextInputFormat来作为输入**,解决输入端大量小文件场景。


#### 2.2 Map阶段


**(1)减少溢写(Spill) 次数:** 通过调整`io.sort.mb`及`sort.spill.percent`参数值,**增大触发Spill的内存上限,减少Spill次数,从而减少磁盘IO**。


**(2)减少合并(Merge) 次数:** 通过调整`io.sort.factor`参数, **增大Merge的文件数目,减少Merge的次数,从而缩短MR处理时间**。


(3)在Map之后,不影响业务逻辑前提下,**先进行Combine处理,减少I/O**。


#### 2.3 Reduce阶段


**(1)合理设置Map和Reduce数:** 两个都不能设置太少,也不能设置太多。太少,会导致Task等待,延长处理时间;太多,会导致Map、Reduce任务间竞争资源,造成处理超时等错误。


**(2)设置Map、Reduce共存:** 调整slowstart.completedmaps参数,使Map运行到一定程度后,Reduce也开始运行,减少Reduce的等待时间。


**(3)规避使用Reduce:** 因为Reduce在用于连接数据集的时候将会产生大量的网络消耗。


**(4)合理设置Reduce端的Buffer:** 默认情况下,数据达到一个阈值的时候,Buffer中的数据就会写入磁盘,然后Reduce会从磁盘中获得所有的数据。也就是说,Buffer和Reduce是没有直接关联的,中间多次写磁盘->读磁盘的过程,既然有这个弊端,那么就可以通过参数来配置,使得Buffer中的一部分数据可以直接输送到Reduce,从而减少IO开销:  
 **`mapreduce. reduce.input. buffer.percent`,默认为0.0。当值大于0的时候,会保留指定比例的内存读Buffer中的数据直接拿给Reduce使用。这样一来, 设置Buffer需要内存,读取数据需要内存,Reduce计算也要内存,所以要根据作业的运行情况进行调整。**


#### 2.4 IO传输


(1)**采用数据压缩的方式**,减少网络IO的的时间。安装Snappy和LZO压缩编码器。  
 (2)**使用SequenceFile二进制文件**。


#### 2.5 数据倾斜问题


##### 2.5.1 数据倾斜的概念


数据倾斜这四个字经常会在学习MapReduce中遇到。所谓数据分区,就是数据分区分布因为数据本身或者分区方法的原因变得极为不一致,**大量的数据被划分到了同一个区**。**由于Reducer Task每次处理一个区的数据,这导致Reducer Task处理有着大量数据的分区时任务繁重,而其他区分到的任务过于轻松,从而导致整体的任务效率大幅降低。  
 “一个人累死,其他人闲死”**。


##### 2.5.2 数据倾斜现象


**(1)数据频率倾斜**——某一个区域的数据量要远远大于其他区域。


比如:数据的key非常少,极少数的key中记录了非常多的记录值。**这属于相同key分到同一个分区导致分区数据过多。**


**(2)数据大小倾斜**——部分记录的大小远远大于平均值。


比如:数据的key比较多,但有某些key的记录值远远多于其他key,在分区的时候将有着大量记录值的key分到了同一个区。**这属于不同key因为分区方法分到同一个区导致分区数据过多。**


##### 2.5.3 数据倾斜导致的结果


**(1)大部分的Task运行速度很快,但是小部分Task运行速度很慢;**


**(2)原本能正常执行的Spark作业,某天突然爆出OOM(内存溢出)异常。** 观察异常栈,是我们写的业务代码造成的。


##### 2.5.4 减少数据倾斜的方法


**方法1: 抽样和范围分区**  
 可以通过对原始数据进行抽样得到的结果集来预设分区边界值。


**方法2: 自定义分区**  
 **基于输出键的背景知识**进行**自定义分区**。**例如,如果Map输出键的单词来源于一本书。且其中某几个专业词汇较多。那么就可以自定义分区将这些专业词汇发送给固定的一部分Reduce实例。 而将其他的都发送给剩余的Reduce实例。**


**方法3: Combine**  
 使用Combine可以大量地减小数据倾斜。**在可能的情况下,Combine的目的就是聚合并精简数据。** Map阶段会将环形缓冲区的数据排序并溢写,在溢写之前,使用combiner将相同key数据进行合并(如累加)。这减轻了数据倾斜的现象,减轻了map端向reduce端发送的数据量(减轻了网络带宽),也减轻了map端和reduce端中间的shuffle阶段的数据拉取数量(本地化磁盘IO速率),**推荐使用这种方法**。


**方法4: 采用Map Join,尽量避免Reduce Join**  
 比如当一个大表Join小表的时候,可以将小表直接读到内存中,进行Map Join,省去了Shuffle阶段。


**方法5: 通过加随机前缀重新设计key**  
 **聚合类型出现数据倾斜主要是使用group by、distinct造成的。**  
 针对聚合类的数据倾斜,可以通过加随机前缀重新设计key。比如,我们可以在map阶段随机加上一个固定长度的随机数,使得分区的时候不会像之前那样分到同一个节点,完成一次局部聚合。在这之后将前缀去除,重新进行一次全局聚合即可。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/d56140c4d7f7496e9c2e6984d03ea871.png)



–水果字段名为category
select count (substr(x.category,1,2))
from
(select concat(category,‘_’,cast(round(10*rand())+1 as string))
from table1
group by concat(category,‘_’,cast(round(10*rand())+1 as string))
) x --1阶段聚合
group by substr(x.category,1,2); --2阶段聚合




---


### 3.HDFS 小文件优化方法


#### 3.1 HDFS 小文件弊端


HDFS 上每个文件都要在 NameNode 上建立一个索引,这个索引的大小约为 150byte,  
 这样当小文件比较多的时候,就会产生很多的索引文件,一方面会大量占用 NameNode 的内存空间,另一方面就是索引文件过大使得索引速度变慢。


#### 3.2 HDFS 小文件解决方案


小文件的优化无非以下几种方式:


(1)在数据采集的时候,就将小文件或小批数据合成大文件再上传 HDFS。


(2)在业务处理之前,在 HDFS 上使用 MapReduce 程序对小文件进行合并。


(3)在 MapReduce 处理时,可采用 CombineTextInputFormat 提高效率。


![在这里插入图片描述](https://img-blog.csdnimg.cn/a2751ccfdf9a442dbc5f920d82121453.png)  
 (4)开启JVM重用  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/f166c612a8994136ab9977e0df67a127.png)




---


## Yarn


### 1.什么是Yarn?


Yarn是一个资源调度平台,负责为运算程序提供服务器运算资源,相当于一个分布式的操作系统平台。




---


### 2.Yarn基本架构


YARN 主要由 ResourceManager、NodeManager、ApplicationMaster 和 Container 等组件构成,如下图:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/4a1517ffdd204685b15bcbdefb810fff.png)  
 **1)ResourceManager:**


处理客户请求;




**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数大数据工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/3ba235bdb18e0a9358d872ef92c6505b.png)
![img](https://img-blog.csdnimg.cn/img_convert/6d21e554d9be5b0abaf9143d58f1d882.png)
![img](https://img-blog.csdnimg.cn/img_convert/d3a97158f5ae6e53d2524838b8c6a060.png)
![img](https://img-blog.csdnimg.cn/img_convert/9c90251ab2bdf5f04323b112bce03bd2.png)
![img](https://img-blog.csdnimg.cn/img_convert/2c2fe1e9729c78bb5d400033fdc005ce.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上大数据开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注大数据获取)**
![img](https://img-blog.csdnimg.cn/img_convert/2ed565491bf3a881db9ba3d4ec5c432e.png)


YARN 主要由 ResourceManager、NodeManager、ApplicationMaster 和 Container 等组件构成,如下图:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/4a1517ffdd204685b15bcbdefb810fff.png)  
 **1)ResourceManager:**


处理客户请求;




**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数大数据工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**
[外链图片转存中...(img-gcVdk6aU-1712890239891)]
[外链图片转存中...(img-wUrvRR4F-1712890239891)]
[外链图片转存中...(img-nqEqhX3Y-1712890239892)]
[外链图片转存中...(img-tEXuZNQ2-1712890239893)]
[外链图片转存中...(img-IF3GVJRr-1712890239893)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上大数据开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注大数据获取)**
[外链图片转存中...(img-tJjl8bJF-1712890239893)]

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值