赞
踩
先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注大数据)
本地模式: 单机运行
伪分布模式: 也是单机运行,但是具备Hadoop集群的所有功能,一台服务器模拟一个分布式的环境。
完全分布模式: 多台服务器组成分布式的环境。
Hadoop是指Hadoop框架本身;Hadoop生态系统是指Hadoop及能够保证Hadoop正常运行的其他框架。如Zookeeper, Flume, Hive等。
1)Zookeeper: 它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护,名字服务,分布式同步等。
2)HBase: 它是一个分布式的,面向列的开源数据库。它是一个适合非结构化数据存储的数据库。
3)Hive: 它是一个基于Hadoop的数据仓库工具,提供简单的SQL语句,可以将SQL语句转换为MapReduce任务进行运行。可以将结构化的数据文件映射为一张表,并提供类 SQL 查询功能。
4)Flume: 它是一个高可用的,高可靠的,分布式的海量日志采集,聚合和传输的系统。
5)Sqoop: 主要用于Hadoop,Hive和MySQL之间数据的传递。
6)Spark: 开源大数据内存计算框架。
NameNode: 存储文件的元数据(如文件名,文件目录结构,文件属性)
DataNode: 在本地文件系统存储文件块数据
SecondaryNameNode: 每隔一段时间对NameNode元数据备份
NodeManager: 执行任务
ResourceManager: 负责调度DataNode上的工作
它是一个文件系统,用于存储文件,通过目录树来定位文件;它是分布式的,有很多服务器联合起来实现其功能;适合一次写入,多次读出的场景,且不支持文件的修改。适合用来做数据分析,并不适合用来做网盘应用。
优点:
1)高容错性:数据自动保存多个副本;某一个副本丢失后,可以自动恢复。
2)适合处理大数据。
3)可构建在廉价机器上,通过多副本机制,提高可靠性。
缺点:
1)不适合低延时数据访问,比如毫秒级的存储数据,是做不到的。
2)无法高效的对大量小文件进行存储。
3)不支持文件并发写入,一个文件只能有一个写,不允许多个线程同时写。
3)仅支持数据append(追加),不支持文件的随机修改。
HDFS的文件在物理上是分块储存(Block),块的大小通过配置参数配置(dfs.blocksize),默认大小在Hadoop2.x版本中是128MB,老版本中是64M。
(1)如果HDFS块的大小设置太小,则会增加寻址时间,程序一直在寻找块的开始位置;
(2)如果块的大小设置太大,从磁盘传输数据的时间会明显大于定位这个块开始位置所需要的时间。导致程序处理非常慢。
(3)HDFS块的大小设置取决于磁盘传输速率。
#1.命令大全: bin/hadoop fs #2.启动Hadoop集群: sbin/start-dfs.sh sbin/start-yarn.sh #3.输出某一命令参数 hadoop fs -help rm #4.创建文件夹 hadoop fs -mkdir bigdata #5.上传操作 #5.1 从本地剪切粘贴到HDFS上 hadoop fs -moveFromLocal #5.2 从本地系统拷贝到HDFS上 hadoop fs -copyFromLocal #5.3 等同于copyFromLocal hadoop fs -put #5.4 追加一个文件到已经存在的文件末尾 hadoop fs -appendToFile #6.下载操作 #6.1 从HDFS拷贝到本地 hadoop fs -copyToLocal hadoop fs -get #7.直接操作 显示目录信息 hadoop fs -ls /shu 显示文件内容 hadoop fs -cat 文件名字 修改文件属性 -chmod -chown 创建路径 -mkdir 从HDFS的一个路径拷贝到另一个路径 -cp 在HDFS中移动文件 -mv 设置文件的副本数量 -setrep
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步)。
1)客户端通过分布式系统模块(Distributed FileSystem)向NameNode请求下载文件,NameNode通过查询元数据,找到文件所在的DataNode地址。
2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。
3)DataNode开始传输数据给客户端(从磁盘里面读取数据流,以Packet为单位做校验)
4)客户端以Packet为单位接收,现在本地缓存,然后写入目标文件。
1)Fsimage文件: NameNode 内存中元数据序列化后形成的文件,用于在磁盘中备份元数据。
2)Edits文件: 每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits文件中;记录客户端更新元数据信息的每一步操作(可通过 Edits 运算出元数据)。
一旦NameNode断电,就会合并Fsimage文件和Edits文件,合成元数据。引入的Secondary NameNode 专门用于合并两个文件。
第一阶段: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。
小文件的定义:
文件大小小于或者等于30M的文件
HDFS小文件带来危害:
(1)小文件数量过多(例如图片)会占用批量占用Namenode的内存,因为每个存储在HDFS中的文件的元数据(包括目录树,位置信息,命名空间镜像fsimage,文件编辑信息edits)都会在Namenode中占用150B的内存,如果Namenode存储空间满了,就不能继续存储新文件了。
(2)如果有多小文件,会造成寻道时间>=读取文件时间(传输文件时间 = 寻道时间+读取文件时间),这与HDFS的原理相违背,HDFS的设计是为了减小寻道时间,使其远小于读取文件的时间。Hive或者Spark计算的时候会影响他们的速度,因为Spark计算时会将数据从硬盘读到内存,零碎的文件将产生较多的寻道过程。
(3)流式读取的方式,不适合多用户写入,以及任意位置写入。如果访问小文件,则必须从一个Datanode跳转到另外一个Datanode,这样大大降低了读取性能。
HDFS默认的数据存储块是64MB,现在新版本的hadoop环境(2.7.3版本后),默认的数据存储块是128MB。
一个文件如果小于128MB,则按照真实的文件大小独占一个数据存储块,存放到DataNode节点中。同时 DataNode一般默认存三份副本,以保障数据安全。 同时该文件所存放的位置也写入到NameNode的内存中,如果有Secondary NameNode高可用节点,也可同时复制一份过去。NameNode的内存数据将会存放到硬盘中,如果HDFS发生重启,将产生较长时间的元数据从硬盘读到内存的过程。
如果一个文件大于128MB,则HDFS自动将其拆分为128MB大小,存放到HDFS中,并在NameNode内存中留下其数据存放的路径。不同的数据块将存放到可能不同的DataNode中。
Hadoop文件格式学习
HDFS的文件存储格式以及HDFS异构存储和存储策略
大数据存储数据,99%以上的场景都是使用的是列式存储。
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函数的输出是一个单词及其在文档中出现的总次数。
1)MapReduce运算程序一般分成两个阶段,Map阶段和Reduce阶段。
2)Map阶段的Map Task并发实例,完全并发运行,互不相干。
3)Reduce阶段的Reduce Task并发实例互不相干,但是他们的数据依赖于上一个阶段的所有Map Task并发实例的输出。
4)MapReduce编程模型只能包含一个Map阶段和一个Reduce阶段,如果用户的业务逻辑非常复杂,那就只能多个MapReduce程序,串行运行。
一个完整的MapReduce程序在分布式运行时有三类实例进程:
1) MrAppMaster: 负责整个程序的过程调度及状态协调。
2) MapTask: 负责Map阶段的整个数据处理流程。
3) ReduceTask: 负责Reduce阶段的整个数据处理流程。
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必须能排序。
1)MapTask并行度决定机制
数据块: Block是HDFS物理上把数据分成一块一块,数据块是HDFS的数据存储单位。
数据切片: 数据切片是MapReduce程序计算输入数据的单位,一个切片会对应启动一个MapTask。
2)FileInputFormat切片源码解析
3)切片大小的参数配置:
计算切片大小的公式:Math.max(minSize,Math.min(maxSize,blockSize))
切片大小的设置:
maxSize(切片最大值):参数如果调得比blockSize小,则会让切片变小,而且就等于配置的这个参数的值。
minSize(切片最小值):参数调得比blockSize大,则会让切片变得比blockSize大。
1)map数量由处理的数据分成的block数量决定,
default_num = total_size / split_size
。
2)reduce数量由job.setNumReduceTasks(x)
决定。
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 最终只生成一个数据文件,可避免同时打开大量文件和同时读取大量
小文件产生的随机读取带来的开销。
1)Copy阶段: ReduceTask 从各个 MapTask 上远程拷贝一片数据,并针对某一片数据,如果其大小超过一定阈值,则写到磁盘上,否则直接放到内存中。
2)Merge阶段: 在远程拷贝数据的同时,ReduceTask 启动了两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或磁盘上文件过多。
3)Sort阶段: 按照 MapReduce 语义,用户编写 reduce()函数输入数据是按 key 进行聚集的一组数据。为了将 key 相同的数据聚在一起,Hadoop 采用了基于排序的策略。由于各个 MapTask 已经实现对自己的处理结果进行了局部排序,因此,ReduceTask 只需对所有数据进行一次归并排序即可。
4)Reduce阶段: reduce()函数将计算结果写到 HDFS 上。
ReduceTask 的并行度同样影响整个 Job 的执行并发度和执行效率,但与 MapTask 的并
发数由切片数决定不同,ReduceTask 数量的决定是可以直接手动设置:
// 默认值是 1,手动设置为 4
job.setNumReduceTasks(4);
Map方法之后,Reduce方法之前的数据处理过程称之为Shuffle。
分区、排序、溢写、然后拷贝到对应Reduce机器上,可以选择增加Combiner,压缩溢写的文件。
combiner的作用:
combiner对每一个MapTask的输出进行局部汇总,以减小网络传输量。
combiner在每一个MapTask所在的节点运行;
reduce是接收全局所有map的输出结果。
1)将统计结果按照条件输出到不同分区中。
2)在没有自定义分区的情况下,数据被送到reduce端前如何分区?
根据默认的HashPartitioner
,逻辑是根据key
的哈希值和numReduces
来返回一个分区号,key.hashCode()
&Integer.MAXVALUE % numReduces
3)自定义Partition分区步骤:
步骤1:自定义类继承Partitioner,重写getPartition()方法。
步骤2:在Job驱动中,设置自定义Partitioner。
步骤3:自定义Partitioner后,要根据自定义Partitioner的逻辑设置相应数量的ReduceTask。
1.使用场景
Map Join 适用于一张表十分小、一张表很大的场景。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
插入图片描述](https://img-blog.csdnimg.cn/81d45b1b791d4a0bac2e0ba6ed3ba56e.png)
1.使用场景
Map Join 适用于一张表十分小、一张表很大的场景。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)
[外链图片转存中…(img-hBkrZDoy-1713183963523)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。