大数据面试题
Hadoop
分布式系统基础架构,主要是为了解决海量数据的存储和
和海量数据的分析计算
问题
Hadoop的特点
| 高可靠性:Hadoop底层维护多个数据副本,即使Hadoop某个计算元素或存储出现故障,也不会 导致数据的丢失 |
| |
| 高扩展性:集群分配任务数据,可方便扩展数以千计的节点 |
| |
| 高效性:并行工作,加快任务处理速度 |
| |
| 高容错性:能够自动将失败的任务重新分配 |
HDFS面试重点
1.HDFS的架构
1)HDFS Client
| 1、文件切分。文件上传HDFS的时候,Client将文件切分成一个个block,进行存储 |
| 2、于NN交互,获取文件位置信息 |
| 3、与DN交互,读/写数据 |
| 4、Client提供一些命令来管理HDFS |
2)NameNode(NN):Master
| 1、管理HDFS的命名空间 |
| 2、管理数据块(block)映射信息 |
| 3、配置副本策略 |
| 4、处理客户端读写请求 |
3)DataNode(DN):Slave
4)Secondary NameNode(NN2)
| 1、辅助NN,分担其工作量 |
| 2、定期合并Fsimage和Edites,并推送给NN |
| 3、在紧急情况下,辅助恢复NN |
2.HDFS的读写流程
hdfs读流程
| 1、Client通过Distributed FileSystem模块向NN请求上传文件,NN检查目标文件是否已存在,父目录是否存在 |
| 2、NN返回是否可以上传 |
| 3、Client请求第一个block上传哪几个DN服务器上 |
| 4、NN返回3个DN节点,分别为DN1、DN2、DN3 |
| 5、Client通过FSDataOutputStream模块请求DN1建立传输通道,DN1收到请求会继续调用DN2,DN2继续调用DN3 |
| 6、DN3应答DN2,DN2应答DN1,DN1应答Client |
| 7、Client开始往DN1上传第一个block(先从磁盘上读取数据放到一个本地磁盘缓存),以packet为单位,DN1收到一个packet就会上传给DN2,DN2传给DN3;DN1每传一个packet会放入一个应答队列等待应答 |
| 8、当一个block传输完成后,Client会再次请求NN上传第二个block的服务器,重复执行3-7 |
hdfs写流程
| 1、Client通过Distributed FileSystem模块向NN请求下载文件,NN通过查询元数据,找到文件的DN地 |
| 址 |
| 2、Client挑选一台最近的DN,请求读取数据 |
| 3、DN开始传输数据给Client(从磁盘里读取数据输入流,以packet为单位做校验) |
| 4、Client以packet为单位接收,先在本地缓存,然后写入目标文件 |
3.HDFS中,文件为什么以block块的方式存储
block:
HDFS 将Block块设置为128M
| 磁盘有一个 Block Size的 概念,它是磁盘读/写数据的最小单位。文件系统的块通常是磁盘块的整数倍。 |
| |
| HDFS也有 Block 的概念,像磁盘中的文件系统一样,HDFS中的文件按块大小进行分解,HDFS中一个块只存储一个文件的内容 |
| 目的:减少磁盘寻道的时间。 |
| |
| (1)、不设置block:因为数据是分散的存放磁盘上的,读取数据时需要不停的进行磁盘寻道,开销比较大。 |
| |
| (2)、使用block:一次可以读取一个block中的数据,减少磁盘寻道的次数和时间。 |
4.小文件过多有什么危害,你知道的解决办法有哪些
小文件:文件大小小于或者等于30M的文件
hdfs小文件带来危害
| (1)HDFS不适合大量小文件的存储,因namenode将文件系统的元数据存放在内存中,因此存储的文件数目受限于 namenode的内存大小。HDFS中每个文件、目录、数据块占用150Bytes。如果存放的文件数目过多的话会占用很大的内存甚至撑爆内存 |
| (2)HDFS适用于高吞吐量,而不适合低时间延迟的访问。如果同时存入大量的小文件会花费很长的时间。hive或者spark计算的时候会影响他们的速度,因为spark计算时会将数据从硬盘读到内存,零碎的文件将产生较多的寻道过程。 |
| (3) 流式读取的方式,不适合多用户写入,以及任意位置写入。如果访问小文件,则必须从一个datanode跳转到另外一个datanode,这样大大降低了读取性能。 |
解决方案
| Hadoop Archive 小文件归档:一个高效地将小文件放入HDFS块中的文件存档工具,能够将多个小文件打包成 一个HAR文件,允许对文件进行透明访问 |
| |
| Sequence file:由一系列的二进制key/value组成。如果以key为小文件名,value为文件内容,则 可以将大批小文件合并成一个大文件 |
| |
| CombineFileInputFormat<K,V> 小文件合并:一种新的inputformat,用于将多个文件合并成一个单独的split。 |
| |
| 开启JVM重用:一个Map运行在一个JVM上,开启重用,该map在JVM运行完毕之后,JVM继续运行其Map(mapreduce.job.jvm.numtasks)。对于大量小文件的Job,可以减少45%的运行时间。 |
| |
| 手动合并,先将hdfs上的文件copy到本地,本地合并后在上传到hdfs |
| |
5.在NameNode HA中,会出现脑裂问题吗?怎么解决脑裂
NameNode HA: NameNode High Availability即高可用
脑裂:指当HA集群中的两个NameNode实例无法正常通信时,会导致两个实例都认为自己是活动的主NameNode,从而导致集群状态出现不一致的情况,进而影响数据的一致性和可用性。指当HA集群中的两个
措施:
| 1. 心跳机制:设置节点之间的心跳检测,一旦检测到心跳异常就会触发自动切换至备用节点。 |
| |
| 2. 仲裁机制:利用第三方仲裁节点,监控节点间的通信情况,并根据各节点的状态进行选举,确保只有一个主节点。 |
| zooleeper |
| |
| 3. 拆分服务:将不同的服务在不同的节点上运行,避免单个节点崩溃影响整个系统。 |
| |
| 4. 数据冲突检测与处理:在节点间发生通信异常之后,需要对数据进行冲突检测并进行相应的处理,以避免数据的不一致性。 |
6.简述hadoop压缩和解压缩的框架
| Hadoop压缩和解压缩的框架是一种对Hadoop分布式系统中的数据进行压缩和解压缩的工具,主要包括以下几个组成部分: |
| |
| 1.压缩编解码器(Compression Codec):Hadoop内置了多种压缩编解码器,包括Deflate、Gzip、Bzip2、Snappy等。这些压缩编解码器可以用于对大量数据进行压缩和解压缩操作。 |
| |
| 2.压缩格式(Compression Format):Hadoop支持多种压缩格式,包括SequenceFile、MapFile、Avro、Parquet等。这些压缩格式可以提高数据存储和传输的效率。 |
| |
| 3.压缩/解压缩任务(Compression/Decompression Task):Hadoop的压缩/解压缩框架可以通过MapReduce任务或基于Hadoop IO的API实现。压缩/解压缩任务可以在HDFS中对数据进行处理。 |
| |
| 4.压缩输出格式(Compressed Output Format):Hadoop的压缩输出格式可以在压缩后输出结果到HDFS上。这样可以在节约存储空间的同时,保证数据的可靠性和高效性。 |
7.namenode的安全模式有了解吗
| NameNode的安全模式是一个特殊的状态,在这种状态下,Hadoop系统将防止对文件系统的写操作,直到管理员将其手动关闭。此模式通常用于在出现某些问题时,防止进一步的数据损坏,例如由于数据节点故障或磁盘故障导致数据丢失。 |
| |
| 在安全模式下,NameNode将控制文件系统中文件的可用性,以避免数据丢失。在这种状态下,管理员可以执行特定的管理操作,例如修复文件系统的损坏部分,清除无用数据或在损坏节点上执行维护操作。 |
| |
| 在大多数情况下,NamNode的安全模式是自动启用的。只有在特定情况下,管理员需要手动将系统置于此状态。 |
8.Secondary NameNode 了解吗,它的工作机制是怎样的
| Secondary NameNode是一个辅助节点,旨在协助管理Hadoop集群中的NameNode。它的主要作用是帮助NameNode提高稳定性和可靠性,以及提高集群的性能。 |
| |
| Secondary NameNode的工作机制是这样的:它定期从NameNode上复制编辑日志和文件系统元数据,并将其保存为本地副本。编辑日志是一个HDFS中记录每个文件的更改的日志,包括添加,删除和修改。通过定期保存这些元数据和日志文件,Secondary NameNode可以从NameNode上恢复数据,并且在NameNode失败时,可以帮助快速恢复。 |
| |
| Secondary NameNode还有另一个重要的作用,即合并编辑日志。在HDFS中,编辑日志被当做单独的文件存储,如果这些文件的数量过多,则会降低系统性能。Secondary NameNode可以定期合并这些文件来提高性能并减少存储空间的使用。 |
| |
| 总的来说,Secondary NameNode与NameNode密切合作,通过复制,备份和编辑日志汇总等工作来提高集群的稳定性和可靠性。 |
9.在上传文件的时候,其中一个 DataNode 突然挂掉了怎么办
| 客户端上传文件时与 DataNode 建立 pipeline 管道,管道正向是客户端向DataNode 发送的数据包,管道反向是 DataNode 向客户端发送 ack 确认,也就是正确接收到数据包之后发送一个已确认接收到的应答, |
| 当 DataNode 突然挂掉了,客户端接收不到这个 DataNode 发送的 ack 确认,客户端会通知 NameNode,NameNode 检查该块的副本与规定的不符,NameNode 会通知 DataNode 去复制副本,并将挂掉的 DataNode 作下线处理,不再让它参与文件上传与下载 |
10.在读取文件的时候,其中一个块突然损坏了怎么办
| 当出现块损坏的情况时,HDFS会自动从副本中选择一个可用的副本进行读取。在默认情况下,HDFS会在每个节点上保存三个副本,即使其中一个块损坏了,也可以从其他副本中读取数据。如果没有可用的副本,HDFS会将故障节点视为失败,并执行相应的故障转移。 |
| |
| 如果希望尽早检测到损坏的块并进行故障转移,则可以考虑增加块的副本数。这可以通过修改HDFS的配置文件来实现。 还可以使用HDFS的工具来检测块损坏和修复块。Hadoop集群管理者可以使用Hadoop fsck命令来检测损坏的块。该命令可以列出损坏的块并提供有关修复块的建议。同时,还可以使用Hadoop balancer命令来重新平衡HDFS中的数据并确保每个节点上的块数量相等,从而提高数据可靠性和可用性。 |
| |
11.介绍namenode宕机的数据恢复过程
| 如果写入文件过量造成NameNode宕机。那么调高Kafka的存储大小,控制从Kafka到HDFS的写入速度。高峰期的时候用Kafka进行缓存,高峰期过去数据同步会自动跟上。 |
| 1. 检查namenode的故障原因:包括硬件故障、系统错误、网络连接等方面,以确定是否需要更换硬件或对系统进行修复。 |
| |
| 2. 启动namenode备用节点(Secondary Namenode):这是Hadoop系统中的一种备用节点,通常在主节点发生故障时起到主节点的补救作用。在namenode发生故障时,可以通过启动备用节点来恢复数据。 |
| |
| 3. 重新分配block:当主节点出现故障时,备用节点会收集到跟踪块分配情况的日志数据,并对数据块进行重新分配,以确保数据的完整性和正确性。 |
| |
| 4. 恢复元数据(Metadata):元数据是Hadoop中与存储数据相关的数据信息,包括数据块的个数、位置、权限、副本数量等等。在主节点发生故障时,备用节点会根据元数据信息重新构建数据块,使其重新组成数据文件,并将数据文件拷贝到各个数据节点上。 |
| |
| 5. 同步元数据:一旦备用节点完成恢复数据的过程,它会将元数据同步回主节点,代替宕机的主节点恢复集群的控制权和储存结构。 |
12.NameNode 在启动的时候会做哪些操作
| 1. 读取 Hadoop 配置信息:NameNode 在启动时会读取 Hadoop 配置信息,其中包括文件系统的名称、数据节点的地址等关键信息。 |
| |
| 2. 加载 fsimage 和 editlogfile:NameNode 在启动时会加载 fsimage 和 editlogfile 文件,这两个文件记录了 HDFS 文件系统中所有文件和目录的元数据信息。 |
| |
| 3. 恢复 fsimage 和 editlogfile:NameNode 在加载 fsimage 和 editlogfile 文件后,会对其进行恢复,并使用它们来重构文件系统的元数据信息。 |
| |
| 4. 注册 DataNode:NameNode 在启动时会向 DataNode 发送心跳信号,进行通信,并将 DataNode 注册到其管理节点列表中。 |
| |
| 5. 初始化文件系统的安全性:NameNode 在启动时会初始化文件系统的安全性,包括配置 Hadoop 安全性,启动 Kerberos 和在配置 SSL。 |
| |
| 6. 启动 RPC 服务:NameNode 在启动时会启动 RPC 服务,以便客户端和其他节点可以通过网络访问 NameNode。 |
| |
| 7. 启动WebUI:NameNode 在启动时会启动 WebUI 并打开特定的端口,用于以图形化的方式查看 HDFS 文件系统的状态和信息。 |
| |
| 8. 持久化元数据:NameNode 在启动时会将元数据持久化到硬盘中,以保证元数据信息不会丢失。 |
| |
| 9. 启动 SecondaryNameNode:NameNode 在启动时会启动 SecondaryNameNode,用于定期备份 fsimage 文件和 editlogfile。 |
| |
| 10. 日志记录:NameNode 在启动时会记录各种关键信息到日志文件中,以便管理员分析和排除问题。 |
MapReduce面试重点
MapReduce是一种广泛使用的大数据处理框架,它能够处理海量的数据集并且能够高效地运行在分布式系统上。
1.简述MapReduce整个流程
| MapReduce 处理数据过程主要分成 2 个阶段: map 阶段和 reduce 阶段 |
| 先执行 map 阶段,再执行 reduce 阶段。 |
| 1) 在正式执行 map 函数前,需要对输入进行“分片”(就是将海量数据分成大概相等的“块”, hadoop 的一个分片默认是 64M ),以便于多个 map 同时工作,每一个 map 任务处理一个“分片”。 |
| 2) 分片完毕后,多台机器就可以同时进行 map 工作了。 map 函数要做的事情,相当于对数据进行“预处理”,输出所要的“关切”。 map 对每条记录的输出以 pair 的形式输出。 |
| 3) 在进入 reduce 阶段之前,还要将各个 map 中相关的数据( key 相同的数据)归结到一起,发往一个 reducer 。 |
| 4) 接下来进入 reduce 阶段。相同的 key 的 map 输出会到达同一个 reducer 。 |
| reducer 对 key 相同的多个 value 进行“ reduce 操作”,最后一个 key 的一串 value 经过 reduce 函数的作用后,变成了一个 value 。 |
2.手写wordcount
3.join原理
| 在MapReduce中,join是将两个或多个数据集合并在一起的操作。它有两种基本类型:Map-side join和Reduce-side join。 |
| |
| Map-side join是在Map阶段将多个输入数据集连接起来。它的基本想法是将两个数据集按照某个公共键进行分组,然后对每组的记录进行笛卡尔积操作。由于Map阶段是并行执行的,因此需要使用分布式缓存(distributed cache)来加载所有需要连接的数据集。 |
| |
| Reduce-side join是在Reduce阶段将多个数据集合并在一起。它的基本想法是将两个数据集按照某个公共键进行分组,并将相同键值的记录合并在一起。Reduce阶段的处理是串行执行的,因此不需要使用分布式缓存来加载所有需要连接的数据集。 |
| |
| 在MapReduce中,join操作有两个基本的实现方式:Sort-Merge Join和Hash Join。 |
| |
| Sort-Merge Join是在MapReduce框架中使用的一种传统的连接操作。首先对输入数据进行排序,然后按照连接键进行合并。这种方法适用于数据量较大的情况,但是需要进行两次排序操作,耗费大量的时间和计算资源。 |
| |
| Hash Join是一种基于哈希表的连接操作。它首先将两个数据集按照连接键进行哈希分桶,并将相同键值的记录放在同一个桶中。然后遍历每个桶,将相同键值的记录进行连接。这种方法比Sort-Merge Join更快,但是需要占用大量的内存空间。 |
| |
| 总之,MapReduce中的join操作是一种将不同数据源的数据集合并在一起的操作,可以通过分布式缓存来加载多个数据源,在Map阶段将分组后的数据集进行笛卡尔积操作或者在Reduce阶段将含有相同键值的数据集进行合并操作。同时,MapReduce中的join操作也有多种实现方式,包括Sort-Merge Join和Hash Join。 |
| |
4.MapReduce中的文件切片相关问题
文件切片
| 在MapReduce中,文件切片是将大型文件分割成小块的过程。它是MapReduce的第一步。在文件切片期间,MapReduce将文件分成连续的块,每个块的大小通常为64MB。这样可以将文件分割成多个块,每个块可以在不同的计算节点上并行处理。这个过程是自动完成的,不需要人工干预。 |
| |
| 文件切片过程中,MapReduce会依据文件的格式和大小,选择合适的切片方法。对于文本文件,通常是按行进行切分。对于二进制文件,可以按字节或固定大小的块进行切分。在进行Map任务之前,MapReduce会将切片分配给不同的Map任务进行处理。每个Map任务只处理其分配的切片,从而实现了数据的并行处理。 |
| |
| 文件切片是MapReduce中非常重要的一个组成部分,它可以有效提高计算效率和任务并行度。 |
| 1. 什么是MapReduce中的文件切片? |
| MapReduce中的文件切片是指将大文件分割成多个小文件,按照文件大小或记录数等条件进行分割,以便于并行处理和优化计算。 |
| |
| 2. 文件切片的作用是什么? |
| 文件切片将大文件分割成多个小文件,实现分布式处理,提高处理效率和计算速度。同时,文件切片有利于分散文件存储,降低磁盘的IO负载,减轻系统的压力。 |
| |
| 3. 文件切片的切割规则是什么? |
| 文件切片的切割规则通常是按照文件大小或记录数来进行的,切割后的文件大小通常为Hadoop默认块大小,即128MB或256MB。文件切片时需要考虑数据的平衡性,尽量避免某个块的数据过多或过少。 |
| |
| 4. 如何设置文件切片的大小? |
| 文件切片的大小可以通过修改Hadoop的配置文件来设置,通常是通过修改配置参数dfs.blocksize来实现的。根据实际情况设置文件切片大小,避免数据倾斜和磁盘IO负载过高。 |
| |
| 5. 文件切片的切割粒度对计算速度有响吗? |
| 文件切片的切割粒度会影响计算速度,过小的切割粒度会导致过多的切片,增加了网络传输和启动任务的开销,降低了计算效率。过大的切割粒度则会导致数据倾斜和磁盘IO压力。因此,需要根据实际情况设置合理的切割粒度。 |
5.环形缓冲区的底层实现
| MapReduce中环形缓冲区的底层实现通常使用循环队列。循环队列是一种经典的数据结构,其底层使用一个具有固定大小的数组来保存元素,并使用两个指针front和rear来标记队首和队尾位置。环形缓冲区实际上就是一个循环队列,但其实现过程会更加复杂,因为存在多个线程同时对缓冲区进行读写操作。 |
| |
| MapReduce中的环形缓冲区通常由两个线程共同维护:生产者线程和消费者线程。生产者线程将分割后的数据写入环形缓冲区,而消费者线程则从环形缓冲区中读取数据进行计算。为了保证数据的正确性和一致性,必须使用一些同步机制来协调不同线程之间的读写操作。 |
| |
| 使用循环队列实现环形缓冲区时,需要考虑以下问题: |
| |
| 1. 环形缓冲区的大小需要根据实际情况进行合理设置,以保证能够容纳并发处理的数据量。 |
| |
| 2. 由于多个线程同时对缓冲区进行读写操作,需要采用同步机制来避免并发问题,例如使用互斥锁或信号量等同步原语。 |
| |
| 3. 当环形缓冲区已满时,需要采取相应的处理策略,例如等待生产者写入后再进行消费,或者丢弃一部分数据以保证缓冲区空间。 |
| |
| 4. 在使用循环队列进行数据读写时,需要保证指针的正确移动,避免出现指针越界或位置错误等问题。 |
| |
| 总之,MapReduce中环形缓冲区的底层实现需要充分考虑数据的正确性、一致性以及并发处理的效率,采用合适的数据结构和同步机制可以提高系统的性能和稳定性。 |
6 .全排序
| MapReduce能够进行全排序,也就是将所有的输入数据按照指定的顺序排列输出。实现全排序的原理是,通过多次MapReduce作业完成。 |
| |
| 首先,在第一个MapReduce作业中,将输入数据切分成小块分别排序。这些小块可以是单行或者多行,按照键值排序后输出。 |
| |
| 接着,在第二个MapReduce作业中,将前一次输出的小块再次进行排序,形成更大的块。这个过程是递归进行的,直到所有的数据被排序完毕。 |
| |
| 实现全排序的关键是在MapReduce作业中对数据进行切分和排序。对于切分,可以采用Range Partitioner算法,将数据按照键值范围划分到不同的Reducer中。对于排序,可以使用Quick Sort算法或者Merge Sort算法等。 |
| |
| 需要注意的是,全排序算法的效率非常低,尤其是在处理大量数据时。因此,需要进行优化,如使用Combiner、使用In-Mapper Combining和增加Reducer数量等。 |
7.MapReduce实现TopK算法
TopK算法也是一种常见的算法,它经常被用来查找数据集中的最大/最小K个数。
| MapReduce框架可以用来实现TopK算法。下面是一种基本的实现方式: |
| |
| 1. Map阶段:将数据集中的每个元素映射成与该元素对应的键值对,其中键为该元素的值,而值则为1。 |
| |
| 2. Shuffle阶段:将Map产生的键值对通过键值对中的键进行排序和分组。在这个例子中,Map产生的键即为元素的值,因此同样大小的元素会被分到同一个组中。 |
| |
| 3. Reduce阶段:对于每个组,Reduce函数会对键值对中的值进行累加,从而计算出该组中元素的出现次数。然后,将该组的键值对存储到一个最大/最小堆中,以便找到该组中出现次数最多/最少的元素。如果堆的大小大于K,则将堆中最小/最大元素弹出,从而保证堆的大小为K。 |
| |
| 4. 最终输出:Reduce函数输出所有的TopK元素。为了保证输出的顺序,可以对输出的元素进行排序。 |
具体的实现可以参考下面的代码:
Map函数实现:
| def mapper(key, value): yield (value, 1) |
Reduce函数实现:
| def reducer(key, values): |
| heap = [] |
| for value in values: |
| heapq.heappush(heap, value) |
| if len(heap) > K: |
| heapq.heappop(heap) |
| return (key, heap) |
Yarn面试重点
1. 简述yarn 集群的架构
Yarn主要包含:ResourceManager(RM)、NodeManager(NM)、ApplicationMaster和Container 模块
| RM: |
| 处理客户端请求 |
| 监控NM |
| 启动或监控ApplicationMaster |
| 资源的分配与调度 |
| NM: |
| 管理单个节点上的资源 |
| 处理来自RM的命令 |
| 处理来自ApplicationMaster的命令 |
| ApplicationMaster: |
| 为应用程序申请资源并分配给内部的任务 |
| 任务的监督与容错 |
| Containr: |
| 是Yarn中的资源抽象,封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络等 |
2.yarn 的任务提交流程是怎样的
1.作业提交
| (1)Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 |
| (2)Client向RM申请一个作业id。 |
| (3)RM给Client返回该job资源的提交路径和作业id。 |
| (4)Client提交jar包、切片信息和配置文件到指定的资源提交路径。 |
| (5)Client提交资源后,向RM申请运行MrAppMaste |
2.作业初始化
| (6)当RM收到Client的请求后,将该job添加到容量调度器中。 |
| (7)某一个空闲的NM领取到该Job。 |
| (8)该NM创建Container,并产生MRAppmaster。 |
| (9)下载Client提交的资源到本地。 |
3.任务分配
| (10)MrAppMaster向RM申请运行多个MapTask任务资源。 |
| (11)RM将运行MapTask任务分配给另外两个NodeManager,另两个NodeManager分别领取任务并 创建容器。 |
4.任务运行
| (12)MR向两个接收到任务的NodeManager发送程序启动脚本,这两个NodeManager分别启动 MapTask,MapTask对数据分区排序。 |
| (13)MrAppMaster等待所有MapTask运行完毕后,向RM申请容器,运行ReduceTask。 |
| (14)ReduceTask向MapTask获取相应分区的数据。 |
| (15)程序运行完毕后,MR会向RM申请注销自己。 |
5.进度和状态更新
| YARN中的任务将其进度和状态(包括counter)返回给应用管理器, 客户端每秒(通过 mapreduce.client.progressmonitor.pollinterval设置)向应用管理器请求进度更新, 展示给用户。 |
6.作业完成
| 除了向应用管理器请求作业进度外, 客户端每5秒都会通过调用waitForCompletion()来检查作业是否完 成。时间间隔可以通过mapreduce.client.completion.pollinterval来设置。作业完成之后, 应用管理器 和Container会清理工作状态。作业的信息会被作业历史服务器存储以备之后用户核查。 |
| Yarn 的任务提交流程如下: |
| |
| 1. 使用者编写代码并打包成一个或多个应用程序。 |
| |
| 2. 在运行时,Yarn 客户端向 Yarn ResourceManager 提交一个作业请求,该请求包括应用程序的位置、资源需求和应用程序启动命令等信息。 |
| |
| 3. Yarn ResourceManager 接收到作业请求后,会为该作业分配一个 ApplicationMaster(AM),并分配所需的资源。 |
| |
| 4. ApplicationMaster 启动并请求 ResourceManager 分配所需资源,如 CPU、内存等。 |
| |
| 5. ResourceManager 为 ApplicationMaster 分配所需资源。 |
| |
| 6. ApplicationMaster 启动后,会与 Yarn NodeManager 通信,以便获得集群中可用节点的信息。 |
| |
| 7. ApplicationMaster 启动并分配任务(如 MapReduce 任务)给 NodeManager,然后等待任务完成。 |
| |
| 8. NodeManager 接收到任务并启动它。 |
| |
| 9. 任务启动后,在所分配的节点上运行,最终将结果返回给 ApplicationMaster。 |
| |
| 10. ApplicationMaster 将结果收集并整合,最终将结果返回给 Yarn 客户端。 |
| |
| 11. 当作业完成后,ApplicationMaster 会向 ResourceManager 报告成功完成,然后释放所需资源。 |
| |
| 12. Yarn 客户端收到作业完成的消息后,可以获取结果并进行处理。 |
3.yarn的资源调度的三种模型
FIFO、容量(Capacity Scheduler)和公平(Fair Scheduler)
| FIFO: 先进先出调度器 |
| |
| 容量调度器:多队列;每个队列内部先进先出,同一时间队列中只有一个任务在执行。队列的并行度为队列的个数 |
| |
| 公平调度器:多队列;每个队列内部按照缺额大小分配资源启动任务,同一时间队列中有多个任务执行。队列的并行度大于等于队列的个数。 |
Hive
简述hive
| 基于Hadoop一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的 sql 查询功能,可以将 sql 语句转换为 MapReduce 任务进行运行。适合数据仓库的统计分析。 |
简述hive读写文件机制
| Hive支持两种文件格式:文本文件和序列文件。当Hive读取文本文件时,其会将文件按行读取,然后解析成Hive表的行数据。当Hive读取序列文件时,其会根据序列化的格式将文件解析成Hive表的行数据。 |
| |
| 在Hive中,表数据存储在HDFS上,每个表对应一个目录。Hive会将表的数据分成多个块存储在多个文件中,并且每个块的大小可以配置。当Hive写入数据时,其会将数据写入内存缓存中,当缓存达到一定大小时,Hive会将缓存中的数据写入HDFS中的文件。同时,Hive还支持动态分区,即在写入数据时,根据数据的某些属性值将数据分区存储,这样可以提高查询效率。 |
| |
| 总的来说,Hive的读写文件机制是基于Hadoop的文件系统HDFS的,其支持文本文件和序列文件格式,并且支持动态分区 |
hive和传统数据库之间的区别
| Hive是一个基于Hadoop的数据仓库工具,它使用类SQL语言(HiveQL)来查询和管理大规模分布式数据集。而传统数据库是指关系型数据库,使用SQL语言来管理和查询数据。 |
| |
| 以下是Hive和传统数据库之间的一些不同之处: |
| |
| 1.存储方式:传统数据库通常使用B+树等索引结构来存储数据,而Hive将数据存储在Hadoop分布式文件系统(HDFS)中。 |
| |
| 2.处理方式:传统数据库通常是单机或小型集群,而Hive是基于Hadoop分布式计算框架的,可以在大规模集群上运行。 |
| |
| 3.查询语言:传统数据库使用SQL语言,而Hive使用HiveQL语言,类似于SQL语言但有一些不同之处,例如HiveQL支持在查询中引用非关系型数据。 |
| |
| 4.数据类型:传统数据库支持多种数据类型,例如整数、浮点数、字符串等,而Hive支持更多的数据类型,包括复杂数据类型如数组、结构体等。 |
| |
| 5.执行效率:传统数据库通常具有较高的执行效率,可以快速处理大量数据,而由于Hive是基于Hadoop的,因此可能不如传统数据库在处理小规模数据时效率高。 |
hive的内部表和外部表的区别
| 内部表:加载数据到 hive 所在的 hdfs 目录,删除时,元数据和数据文件都删除 |
| 外部表:不加载数据到 hive 所在的 hdfs 目录,删除时,只删除表结构 |
| |
| 内部表是通过create table创建的,外部表是create external table进行创建的 |
| |
| 外部表需要通过location指定表格映射的文件夹 |
hive静态分区和动态分区的区别
| 1. 静态分区可以load data和insert两种方式添加数据,动态只能通过insert的方式添加数据 |
| |
| 2. 静态需要自己指定分区的内容,动态是通过查询结果自动指定和分配的 |
| |
| 3. 动态需要打开动态分区和非严格模式的开关 |
| |
| set hive.exec.dynamic.partition=true; |
| |
| set hive.exec.dynamic.partition.mode=nonstrict; |
| |
| 4. 一般情况下都是使用静态分区,动态的处理数据的速度相对慢一点 |
| |
内连接、左外连接、右外连接的区别
| 内连接是指在两个表中具有匹配值的行之间建立连接。这意味着只有在两个表中都存在匹配值的行才会被连接在一起。 |
| |
| 左外连接是指左表中的所有行都将与右表中的匹配行连接在一起。如果右表中没有匹配项,则左表中的行仍将保留,但是这些行中的所有右表列都将为NULL。 |
| |
| 右外连接是指右表中的所有行都将与左表中的匹配行连接在一起。如果左表中没有匹配项,则右表中的行仍将保留,但是这些行中的所有左表列都将为NULL。 |
| |
| 综上所述,内连接只返回匹配的行,左外连接返回左表中的所有行和右表中的匹配行以及右表中没匹配到的行(NULL填充),右外连接返回右表中的所有行和左表中的匹配行以及左表中没匹配到的行(NULL填充)。 |
hive的join底层实现
| Hive的join底层实现是基于MapReduce的。在进行join操作时,Hive会将数据按照join条件进行分区,并在分区内进行本地join操作。然后,将不同分区的数据进行合并,并通过MapReduce进行全局的join操作。 |
| |
| 具体来说,Hive的join操作分为两个阶段,分别是Map阶段和Reduce阶段。Map阶段会读取数据、进行分区和本地join操作,同时将结果存储到中间文件中。Reduce阶段会将中间文件中的数据按照join条件进行合并,并输出最终的结果。 |
| |
| 为了提高join的性能,Hive在实现中采用了一些优化措施。例如,将小表加载到内存中,利用Hash表进行join操作,减少了磁盘IO的消耗;另外,如果数据量较小,Hive会采用Map端join的方式,避免了Reduce阶段的执行。 |
| |
| 总的来说,Hive的join底层实现是基于MapReduce的,在实现中采用了许多优化措施,以提高join操作的性能和效率。 |
Order By和Sort By的区别
| Order By和Sort By的区别 指的是在数据库中对数据进行排序时,使用的两种不同的语句 |
| Order By 是SQL语句中的关键词,用于按照指定的字段对查询结果进行升序或降序排列; |
| Sort By 是一种在编程语言中常用的函数或方法,用于对数组、列表或集合等数据结构进行排序。 |
| |
| Order By在SQL语句中通常用于查询语句的末尾,其语法为:SELECT column1, column2, ... FROM table_name ORDER BY column1 ASC|DESC, column2 ASC|DESC, ...;其中,ASC表示升序排列,DESC表示降序排列。通过Order By语句,可以对查询结果进行排序,使其更加符合实际需求。 |
| |
| 与之不同的是,Sort By是一种编程语言中常见的排序函数或方法,通常用于对数组、列表或集合等数据结构进行排序。在使用Sort By时,可以指定排序的规则,例如升序或降序,或者按照某个特定的属性进行排序。与Order By相比,Sort By更加灵活,可以对各种不同类型的数据进行排序,不仅局限于数据库查询结果。 |
| |
行转列和列转行函数
| 行转列函数包括PIVOT、TRANSPOSE和STACK |
| 列转行函数包括UNPIVOT、TRANSPOSE和EXPLOD |
Hive的执行流程
| 1.(执行查询操作)Execute Query |
| 命令行或Web UI之类的Hive接口将查询发送给Driver(任何数据库驱动程序,如JDBC、ODBC等)以执行。 |
| 2.(获取计划任务)Get Plan |
| Driver借助查询编译器解析查询,检查语法和查询计划或查询需求 |
| 3.(获取元数据信息)Get Metadata |
| 编译器将元数据请求发送到Metastore(任何数据库)。 |
| 4.(发送元数据)Send Metadata |
| Metastore将元数据作为对编译器的响应发送出去。 |
| 5.(发送计划任务)Send Plan |
| 编译器检查需求并将计划重新发送给Driver。到目前为止,查询的解析和编译已经完成 |
| 6.(执行计划任务)Execute Plan |
| Driver将执行计划发送到执行引擎。 |
| 7.(执行Job任务)Execute Job |
| 在内部,执行任务的过程是MapReduce Job。执行引擎将Job发送到ResourceManager, |
| ResourceManager位于Name节点中,并将job分配给datanode中的NodeManager。在这里,查询执行MapReduce任务. |
| 7.1.(元数据操作)Metadata Ops |
| 在执行的同时,执行引擎可以使用Metastore执行元数据操作。 |
| 8.(拉取结果集)Fetch Result |
| 执行引擎将从datanode上获取结果集; |
| 9.(发送结果集至driver)Send Results |
| 执行引擎将这些结果值发送给Driver。 |
| 10.(driver将result发送至interface)Send Results |
| Driver将结果发送到Hive接口 |
Hive 有哪些方式保存元数据,各有哪些特点
| Hive 支持三种不同的元存储服务器,分别为:内嵌式元存储服务器、本地元 |
| 存储服务器、远程元存储服务器,每种存储方式使用不同的配置参数。 |
| 内嵌式元存储主要用于单元测试,在该模式下每次只有一个进程可以连接到 |
| 元存储,Derby 是内嵌式元存储的默认数据库。 |
| 在本地模式下,每个 Hive 客户端都会打开到数据存储的连接并在该连接上请 |
| 求 SQL 查询。 |
| 在远程模式下,所有的 Hive 客户端都将打开一个到元数据服务器的连接,该 |
| 服务器依次查询元数据,元数据服务器和客户端之间使用 Thrift 协议通信 |
grouping_sets、cube和rollup
| 在Hive中,grouping sets、cube和rollup都是用来实现多维度聚合的功能。它们都可以将多个维度的聚合结果合并成一个结果。 |
| |
| 1. grouping sets(分组集) |
| |
| grouping sets是一种常用的多维度聚合操作,它可以按照多个列进行分组聚合,并且可以指定多个维度的不同组合方式。通过使用grouping sets,可以将多个不同维度的聚合结果合并成一个结果集。 |
| |
| 假设一个表包含两个列A、B,分别为数字和日期类型,使用grouping sets语句进行如下查询: |
| |
| ``` |
| SELECT A,B,SUM(C) FROM table GROUP BY grouping sets ((A,B),(A),(B),()) |
| ``` |
| |
| 上述语句中,通过grouping sets指定了四种情况下的分组聚合方式,分别是按照A、B共同分组、按照A分组、按照B分组、不分组。 |
| |
| 2. cube(立方体) |
| |
| cube是一种更加复杂的多维度聚合操作,它可以对指定的列进行“立方体”般的多维度聚合。与grouping sets不同的是,cube会根据指定的列生成所有可能的组合方式进行聚合。通过使用cube,可以更加灵活地进行多维度聚合操作。 |
| |
| 假设一个表包含三个列A、B、C,使用cube语句进行如下查询: |
| |
| ``` |
| SELECT A,B,C,SUM(D) FROM table GROUP BY cube (A,B,C) |
| ``` |
| |
| 上述语句中,通过cube指定了对A、B、C三个列进行“立方体”聚合的操作,会生成所有可能的组合方式进行聚合,包括(A,B,C)、(A,B)、(A,C)、(B,C)、(A)、(B)、(C)、()等八种情况。 |
| |
| 3. rollup(增量式立方体) |
| |
| rollup是一种增量式的多维度聚合操作,它可以对指定的列进行多维度聚合,并依次增加聚合维度。与cube不同的是,rollup会根据指定的列生成一组递增的聚合方式进行聚合。通过使用rollup,可以在保证计算准确性的前提下,大大减少计算量和存储空间。 |
| |
| 假设一个表包含三个列A、B、C,使用rollup语句进行如下查询: |
| |
| ``` |
| SELECT A,B,C,SUM(D) FROM table GROUP BY rollup (A,B,C) |
| ``` |
| |
| 上述语句中,通过rollup指定了对A、B、C三个列进行增量式的聚合操作,会生成一组递增的聚合方式进行聚合,包括(A,B,C)、(A,B)、(A)、()等四种情况。在计算时,rollup会依次增加聚合维度,计算出每一个聚合维度对应的结果,最终得到所有聚合维度的结果集。 |
UDF、UDAF、UDTF 的区别
| UDF:单行进入,单行输出 |
| UDAF:多行进入,单行输出,聚集函数 |
| UDTF:单行输入,多行输出 |
完成步骤:
| 1)导入依赖 |
| 2)创建一个类,继承于Hive自带的UDF |
| 3)打成jar包上传到linux服务器 |
| 4)将jar包添加到hive的classpath |
| 5)创建临时函数与开发好的java class关联 |
hive3的新特性有了解过吗
| 1. ACID事务支持:Hive3引入了ACID全称原子,一致,隔离和持久的特性。这种特性使得多个并发用户可以在同一时间对同一个表进行修改,并且每个修改都是独立的,不会影响到其他用户的修改。 |
| |
| 2. 向量化查询引擎:向量化查询引擎可以在同一次查询中同时处理多个数据,从而提高查询效率,使得Hive3可以更快地处理大规模数据。 |
| |
| 3. 改进的存储格式:Hive3支持新的ORC存储格式,这种格式可以显著提高查询速度和压缩比率。同时,Hive3还支持Parquet存储格式和AVRO存储格式,这使得Hive3可以更好地集成到Hadoop生态系统中。 |
| |
| 4. 增强的SQL语言支持:Hive3支持更多的SQL语法,例如窗口函数和分析函数,从而使得用户可以更方便地进行数据分析。 |
| |
| 5. 更好的安全性和认证:Hive3引入了一些新的安全特性,例如列级别的安全、资源调度和控制、权限管理等,从而使得用户可以更好的保护其数据 |
hive小文件过多怎么办
| 小文件太多的出现: |
| 源数据本身有很多小文件 |
| 动态分区产生很多小文件 |
| reduce个数越多,小文件越多 |
| 按分区插入数据产生很多小文件,文件个数=maptask个数*分区数 |
| |
| 小文件太多的影响: |
| 从Hive角度看,会启动很很多map,一个map需要一个JVM去执行,任务的初始化浪费资源 |
| HDFS存储太多小文件,导致NN元数据特别多,占有其太多内存 |
解决方案:
| 1、通过调整参数合并 |
| |
| 2、针对分区插入数据的时候产生的大量小文件问题,使用DISTRIBUTE BY rand()将数据随机分配给Reduce,使每个Reduce处理的数据大体一致 |
| |
| 3、使用Sequencefile作为表存储格式 |
| |
| 4、使用Hadoop的archhive归档 |
Hive开窗函数
| 分析函数:用于计算基于组的某种聚合值 |
| 开窗函数:指定分析函数工作的数据窗口大小 |
| |
| 分析函数(sum(),max(),row_number()...) + 窗口自己(over函数) |
| 1、SUM函数 |
| sum()根据每一行的窗口返回各自行对应的值,有多少行记录就有多少个sum值 |
| |
| 2、NTILE函数 |
| NTILE(n)用于将分区数据按照顺序切分成n片,返回当前切片值 |
| 如果切片不均匀,默认增加第一个切片的分布 |
| 不支持ROWS BETWEEN |
| |
| 3、ROW_NUMBER函数 |
| ROW_NUMBER()从1开始,按照顺序,生成分组内记录的序列 |
| |
| 4、RANK和DENSE_RANK函数 |
| RANK()生成数据项在分组中的排名,排名相等会在名次中留下空位 |
| DENSE_RANK()生成数据项在分组中的排名,排名相等在名次中不会留下空位 |
| |
| 5、CUME_DIST函数 |
| CUME_DIST()返回小于等于当前值的行数/分组内总行数 |
| |
| 6、PERCENT_RANK函数 |
| PERCENT_RANK分组当前行的rank值-1/分组内总函数-1 |
| |
| 7、LAG和LEAD函数 |
| LAG(col,n,DEFAULT)用于统计窗口内往上第n行值 |
| LEAD(col,n,DEFAULT)用于统计窗口内往下第n行值 |
| col:列名 n:往上第n行 DEFALUT:往上第n行为NULL时,取默认值,不指定为NULL |
| |
| 8、FIRST_VALUE和LAST_VALUE函数 |
| FIRST_VALUE()取分组内排序后,截止到当前行第一个值 |
| LAST_VALUE()取分组内排序后,截止到当前行最后一个值 |
Hive优化
| -- 尽可能减少查询和运算过程中的数据量 |
| |
| 分区、分桶、查询列不要使用*、先筛选再聚合和连接表。 |
| |
| -- 修改表格存储的结构和压缩的方法 |
| |
| 小表:textfile gzip |
| |
| 中大表:orc zlib |
| |
| -- 设置不同的map和reduce数量 |
| |
| -- 有一些不同的hive数据库的set开关 |
| |
| aggr 聚合开关 |
| |
| parallel 并行开关等 |
| |
Hive 表关联查询,如何解决数据倾斜的问题
| 1)倾斜原因:map 输出数据按 key Hash 的分配到 reduce 中,由于 key 分布不均匀、业务数据本身的特、建表时考虑不周、等原因造成的 reduce 上的数据量差异过大。 |
| (1)key 分布不均匀; |
| (2)业务数据本身的特性; |
| (3)建表时考虑不周; |
| (4)某些 SQL 语句本身就有数据倾斜; |
| 如何避免:对于 key 为空产生的数据倾斜,可以对其赋予一个随机值。 |
| 2)解决方案 |
| (1)参数调节: |
| hive.map.aggr = true |
| hive.groupby.skewindata=true |
| 有数据倾斜的时候进行负载均衡,当选项设定位 true,生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。 |
| (2)SQL 语句调节: |
| ① 选用 join key 分布最均匀的表作为驱动表。做好列裁剪和 filter 操作,以达到两表做 join 的时候,数据量相对变小的效果。 |
| ② 大小表 Join: |
| 使用 map join 让小的维度表(1000 条以下的记录条数)先进内存。在map 端完成 reduce。 |
| ③ 大表 Join 大表: 把空值的 key 变成一个字符串加上随机数,把倾斜的数据分到不同的reduce 上,由于 null 值关联不上,处理后并不影响最终结果。 |
| ④ count distinct 大量相同特殊值: count distinct 时,将值为空的情况单独处理,如果是计算 countdistinct,可以不用处理,直接过滤,在最后结果中加 1。如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行 union. |
补充:
| 1.Hive的主要特点是什么? |
| Hive是一个基于Hadoop的数据仓库工具,它能够将结构化数据映射到Hadoop的分布式存储中。Hive的主要特点包括: |
| |
| 支持SQL查询语言,使得非专业人员也能够使用Hadoop进行数据查询和分析。 |
| 支持MapReduce任务,可以将查询转化为MapReduce任务,加速查询效率。 |
| 可以与其他Hadoop生态系统工具(如HBase和Spark)无缝集成。 |
| 2.Hive中的分区是什么? |
| Hive中的分区是将数据按照指定的列进行分组管理的一种机制。分区可以提高查询效率,因为查询只需要扫描指定分区的数据,而不需要扫描整个数据集。 |
| |
| 例如,可以将一张表按照日期列分为不同的分区,每个分区包含该日期的所有数据。这样,当查询某个日期的数据时,只需要扫描该分区,而不需要扫描整个表。 |
| 3.Hive中的Bucket是什么? |
| Hive中的Bucket是将数据按照指定列的值进行划分为多个部分,每个部分称为一个Bucket。Bucket可以提高数据查询的效率,因为Hive可以在查询时只扫描特定的Bucket,而不是整个数据集。 |
| |
| 例如,可以将一张表按照用户ID列进行Bucket操作,将用户ID相同的数据放在同一个Bucket中。这样,在查询某个用户ID的数据时,只需要扫描该Bucket,而不需要扫描整个表。 |
| |
| 4.Hive中的UDF是什么?有哪些类型? |
| UDF(User Defined Function)是用户自定义函数,可以在Hive中自定义函数来满足特定的查询需求。Hive中的UDF分为以下几类: |
| |
| 内置函数:Hive自带的函数,如数学函数、字符串函数等。 |
| 简单自定义函数:用户自己编写的简单函数,可以使用Java或Python编写。 |
| 复杂自定义函数:用户自己编写的复杂函数,需要继承Hive UDF类并实现指定的方法。 |
| 5.Hive中的Join有哪些类型? |
| Hive中的Join有以下几种类型: |
| Map-side Join:当一个表很小,可以将其全部加载到内存中时,可以使用Map-side Join。这种Join不需要Shuffle和Reduce操作,因此效率较高。 |
| Reduce-side Join:当一个表很大,不能全部加载到内存中时,需要使用Reduce-side Join。这种Join需要进行Shuffle和Reduce操作,因此效率较低。 |
| Semi Join:当只需要返回某个表中满足条件的记录时,可以使用Semi Join。这种Join只返回一个表中符合条件的记录,而不返回另一个表的数据。 |
| Map Join:当一个表很小,但是由于其它原因不能使用Map-side Join时,可以使用Map Join。这种Join将小表加载到内存中,然后将大表切分为多个部分,每个部分与小表进行Join操作。这种Join能够充分利用内存,因此效率较高。 |
| |
| 4个By: |
| (1)Order By |
| 全局排序,只有一个Reducer。 |
| (2)Sort By |
| 分区内有序,其在数据进入 reducer 前完成排序 |
| (3)Distrbute By |
| 类似MR中Partition,进行分区,结合sort by使用,按照指定的字段对数据进行划分输出到不同的 reduce 中。 |
| (4) Cluster By |
| 当Distribute by和Sorts by字段相同时,可以使用Cluster by方式。Cluster by除了具有Distribute by的功能外还兼具Sort by的功能。但是排序只能是升序排序,不能指定排序规则为ASC或者DESC。在生产环境中Order By用的比较少,容易导致OOM。 |
| 在生产环境中Sort By+ Distrbute By用的多 |
| |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性