大数据面试题题库
01、hadoop部分
1.1 简述hadoop安装过程
安装ssh,jdk,hadoop软件包,分发安装包与配置文件,hadoop集群模式有本地模式、伪分布式、完全分布式三种。
启动hadoop集群。
1.2 列举hadoop有哪些进程,分别是什么作用?
namenode
datanode
secondary namenode
ResourceManager
Nodemanager
JournalNode
ZookeeperFailoverController
1.3 Hadoop实现连接的两种方式
map连接和reduce端连接,map端连接不需要reduce过程,适合大表 + 小表,reduce端join适用于大表 + 大表情况。
1.4 hadoop二次排序实现
二次排序是对value进行排序,value无法排序,只能将value做到key中,通过key的排序来完成,因此需要自定义key,定义排序
1.5 hadoop shuffle过程
MR要确保给每个reducer的输入都是按照key排序的。系统执行这一排序过程并将map的输出传输给reduce作为输入,这一过程称为shuffle。
map端过程
map函数产生的输出会进入buffer中并进行预排序。每个map任务都有一个环形缓冲区用于将输出内容写入,缓冲区默认是100m空间(可通过mapreduce.task.io.sort.mb进行修改),当缓冲区内容达到80%的阈值(可以通过mapreduce.-map.sort.spill.percent进行修改)时,就会启动一个后台线程将buffer中内容溢出到磁盘。溢出发生期间,buffer仍会持续写入。但如果在此期间,buffer满了,map就会被阻塞直到溢出完成。溢出内容会以轮询方式向特定目录(可通过mapreduce.cluster.local.dir修改)中进行写入。
在写入磁盘之前,该线程会按照reducer数据对数据进行分区。在每个分区内,后台线程会对数据在内存中进行按key排序,如果有combiner函数,还会在排序的输出结构上进行combine。运行combiner函数会让map的输出更加紧凑,减少本地磁盘的数据写入量和传输给reducer的数据量。
每当缓冲到达溢出的阈值,就会创建一个新的溢出文件,因此在map任务将所有输出结果写如果,会产生多个溢出文件。在task完成之前,这些溢出的文件需要合并到一个分区化的、排序的输出文件中。属性mapreduce.task.io.sort.factor用来控制一次合并的文件数,默认是10。
如果存在至少3个(mapreduce.map.combine.minspills控制)溢出文件,在ouput文件写入前,会再次执行combiner过程,如果只有一个或两个溢出文件的话,map端就不值得运行combiner过程。
map的输出写入文件时进行压缩是不错的想法,这可以使得写入更快、更节省磁盘空间,也会减少传输到reducer的数据量。默认输出是没有启用压缩的,可以通过mapreduce.map.output.compress设置为true开启,压缩算法可以使用mapreduce.map.output.compress.codec设置。
输出文件的分区通过http协议供reduce使用,用来处理文件分区的工作线程数由mapreduce.shuffle.max.threads控制,概述形式针对每个NodeManager的,而不是每个Map任务。默认为0表示设置为主机处理器个数的2倍大小。
reduce端过程
reduce任务需要跨越整个cluster从几个map任务的输出中找出特定的分区来获取数据。map任务完成的时间各不相同,一旦map任务完成,reduce任务就开始复制其输出数据。这称之为reduce任务的复制阶段,reduce任务有少量的拷贝线程,以便它能够并行抓取map的输出。默认是5个线程,可通过mapreduce.reduce.shuffle.parallelcopies进行配置。
reducer如何知道map的输出来自于哪台主机?
map成功完成时,会使用心跳机制通知appmaster,因此appmaster就在map输出和host之间做一个映射,reducer中的一个线程会周期性询问master中的这些映射数据,直到全部检索到他们为止。
第一个reducer检索到map输出后,并不会从磁盘中立刻将map的输出删除,因为后续很可能reducer会失败。事实上,他们会等待,直到收到appmaster的delete指令为止,而这是在job完成后发生的。
如果数据量很少,map的数据就会拷贝到reduce的内存中(缓冲区大小可以通过mapreduce.reduce.shuffle.input.b-uffer.percent控制,该属性指定的是占用堆内存的比例)。否则化,会复制到磁盘。当内存缓冲区达到阈值(可由map-reduce.reduce.shuffle.merge.percent指定)或者达到map输出个数的阈值(mapreduce.reduce.merge.inmem.-threshold),就会合并并溢出到磁盘。如果指定了combiner,合并期间就会执行来减少写入磁盘的数据量。
在磁盘上复制文件累积过程中,后台线程会将他们合并成一个大、排过序的文件。这回节省后期合并的时间。注意,任何在map端进行压缩的输出都要进行解压缩才能够进行对他们进行合并。
当所有的map都复制完成,reduce就进入排序阶段(正确叫法应该是合并节点,排序一词被map端占用了),这将会合并map的输出,保持他们的有序性。通过轮询完成这一个过程。比如有50个map输出文件,合并因子是10(mapreduce.-task.io.sort.factor),表示进行5次循环,每次合并10文件到一个文件中,最后会有5个中间文件。最后阶段不是将5个文件合并成一个,而是包含了内存和磁盘文件段的混合过程。
1.6 hadoop配置调优
1.6.1 大量小文件
大量小文件会占用namenode的空间,每个文件大概占用150个字节,文件很小,导致namenode内存耗尽,服务变慢。优化手段是进行归档或者合并成sequence文件。减少内存消耗。
1.6.2 文件数太多
如果即时文件归档或合并后,还是有大量的文件,仍然会导致namenode的性能降低。这是可以引入fedeartion机制,对名称节点进行扩容,将逻辑上的文件系统名字空间映射到不同的namenode簇中,有效实现namenode的负载均衡。
1.6.3 禁用任务推断
任务推断是hadoop觉得task执行过慢,就会在其他的节点运行同样的任务,一旦有一个成功,就会杀死其他的task。这些任务的执行都需要占用slot,可通过mapred.map.tasks.speculative.execution=false关闭推断执行。 这样可以提高效率。表现方式就是不会产生杀死的 Task Attempts。配置方式如下:
[mapred-site.xml]
<property> <name>mapred.map.tasks.speculative.execution</name> <value>false</value></property>
1.6.4 机架感知
hadoop副本存放策略是本地存放一份,同一机架内的其他节点存放一份,不同机架上的节点存放一份。界定是否是同一机架是通过机架感知技术实现的,可以自定义机架感知类,也可以配置一个脚本,该脚本接受一个参数,通常是ip地址,输出一个字符串机架地址。脚本可以通过topology.script.file.name配置,该属性位于core-site.xml文件中。脚本文件只需要放置到namenode节点,不需要分发。hadoop默认使用的就是基于脚本的机架感知,因此只要配置好所有的是哪个脚本文件即可。如下所示:
[soft/hadoop/etc/hadoop/myrackaware.sh]
#!/bin/baship=$1n4=`echo ${ip} | awk -F "." '{print $4}'`if (($n4<10)) ; then echo rack1 ; elif (($n4>20)) ; then echo rack3 ; else echo rack2 ; fi
<property> <name>topology.script.file.name</name> <value>/soft/hadoop/etc/hadoop/myrackaware.sh</value></property>
1.6.5 修改map端buffer大小
map端buffer默认是100m,如果map端数据量很大,会发生频繁溢出,磁盘IO性能较低,可以增大该buffer的值,使用mapred.child.java.opts配置。
1.6.6 map个数设置
map的个数有切片等计算得来,一个原则就是尽可能利用整个集群的算力,即map个数等于NM节点数,所有节点同时开始读取,每个节点读取一片。
1.6.7 reducer数量
每个reduce计算量在1g ~ 10g之间,个数太少计算时间必然较长,个数太多,增加网络调度的开销,同时map端的分区也会很多,并且一个NM上可能需要启动多个reduce。推荐reduce个数也是NM节点数,通常不超过map数,刚好每个节点都要启动一个reduce task,计算起来要快。如果较少还需要对节点资源倒排序,过多还需要启动多次reduce,同时还要衡量在哪个节点启动多次。
1.6.8 压缩中间数据
压缩中间数据,减少网络传输和磁盘空间。mapred.compress.map.output,压缩算法采用LZO性价比较高。
1.6.9 设置combiner
如果可以combiner的话,设置combiner可以有效降低传输和存储。
1.6.10 尽可能使用IntWritable
hadoop中Text使用utf8方式存储并还要存放长度等信息,占用空间较大。耗费cpu的运算时间。
1.7 腾讯hadoop大规模集群
TDW(Tencent distributed Data Warehouse,腾讯分布式数据仓库)基于开源软件Hadoop和Hive进行构建,打破了传统数据仓库不能线性扩展、可控性差的局限,并且根据腾讯数据量大、计算复杂等特定情况进行了大量优化和改造。
DW服务覆盖了腾讯绝大部分业务产品,单集群规模达到4400台,CPU总核数达到10万左右,存储容量达到100PB;每日作业数100多万,每日计 算量4PB,作业并发数2000左右;实际存储数据量80PB,文件数和块数达到6亿多;存储利用率83%左右,CPU利用率85%左右。经过四年多的持 续投入和建设,TDW已经成为腾讯最大的离线数据处理平台。折合单机是32核cpu,20T硬盘。
1.7.1 建设大群的原因
- 数据共享。TDW之前在多个IDC部署数十个集群,主要是根据业务分别部署,这样当一个业务需要其他业务的数据,或者需要公共数据时,就需要跨集群或者跨 IDC访问数据,这样会占用IDC之间的网络带宽。为了减少跨IDC的数据传输,有时会将公共数据冗余分布到多个IDC的集群,这样又会带来存储空间浪 费。
- 计算资源共享。当一个集群的计算资源由于某些原因变得紧张时,例如需要数据补录时,这个集群的计算资源就捉襟见肘,而同时,另一个集群的计算资源可能空闲,但这两者之间没有做到互通有无。
- 减轻运营负担和成本。十几个集群同时需要稳定运营,而且当一个集群的问题解决时,也需要解决其他集群已经出现的或者潜在的问题。一个Hadoop版本要在 十几个集群逐一变更,监控系统也要在十几个集群上部署。这些都给运营带来了很大负担。此外,分散的多个小集群,资源利用率不高,机器成本较大。