大数据问题
目录
5. block为什么设置成128M,为什么不建议设置太大,或者太小?
8. DFSZKFailoverController的作用?
11. MapReduce中map,reduce数量如何决定,怎么配置?
1. RegionServer上部署多少个region合适?
1. spark on Yarn,Yarn cluster 和 Yarn client模式区别:
3. repartition 和 coalesce 的区别?
4. map 、flatMap 和 mapPartitions 的区别?
6. SparkSession 和 SparkContext 关系
7. 使用 saveAsHadoopFile 时生产 _SUCCESS 文件问题
8. 关于 Spark Streaming 中 LocationStrategies 的设置
1. 找出/data/目录下大于10k的文件,并将其移动到/databak下
一、HDFS
1. HDFS的读流程
- 客户端向NameNode发起读数据请求;
- NameNode响应请求并告诉客户端要读的文件的数据块位置(存在哪个DataNode上);
- 客户端到对应DataNode读取数据,当数据读取到达末端,关闭与这个DataNode的连接,并查找下一个数据块,直到文件数据全部读完;
- 最后关闭输出流。
2. HDFS的写流程
- 客户端向NameNode发起写数据请求;
- NameNode相应请求(NameNode会检查要创建的文件是否已经存在,创建者是否有权限,成功会创建一个记录,失败会报异常);
- 客户端将文件进行切片(分成数据块),然后上传数据块,按照一个一个的形式进行发送,每个数据块都要写到三个DataNode上;
- 成功后DataNode会返回一个确认队列给客户端,客户端进行效验,然后客户端上传下一个数据块到DataNode,直到所有数据块写入完成;
- 当所有数据块全部写入成功后,客户端会向NameNode发送一个反馈并关闭数据流。
3. Hadoop有哪些配置文件?
core-site.xml hdfs-site.xml mapred-site.xml yarn-site.xml slaves container-executor.cfg(会默认禁止root等用户提交任务)
4. 小文件过多会造成什么影响?
因为文件的存放位置数据(元数据)存在于NameNode的内存,1个文件块,占用namenode内存大概150-200字节,小文件过多,对nn负荷比较大。
解决方案:
- 采用har归档方式,将小文件归档
- 采用CombineTextInputFormat
-
有小文件场景开启JVM重用;如果没有小文件,不要开启JVM重用,因为会一直占用使用到的task卡槽,直到任务完成才释放。
JVM重用可以使得JVM实例在同一个job中重新使用N次,N的值可以在Hadoop的mapred-site.xml文件中进行配置。通常在10-20之间
5. block为什么设置成128M,为什么不建议设置太大,或者太小?
block大小设置原则:
1. 减少硬盘寻道时间:
2. 减少NameNode内存消耗:NameNode需要在内存FSImage文件中记录DataNode中数据块信息,若block size太小,那么需要维护的数据块信息会更多。
3. map崩溃问题:若Map任务崩溃,重新启动执行需要重新加载数据,数据块越大,数据加载时间将越长,恢复时间越长。
4. 网络传输问题: 在数据读写计算的时候,需要进行网络传输.如果block过大会导致网络传输时间增长,程序卡顿/超时/无响应.
如果块设置过大:
第一点: 从磁盘传输数据的时间会明显大于寻址时间,导致程序在处理这块数据时,变得非常慢;
第二点: mapreduce中的map任务通常一次只处理一个块中的数据,如果块过大运行速度也会很慢。
第三点: 在数据读写计算的时候,需要进行网络传输.如果block过大会导致网络传输时间增长,程序卡顿/超时/无响应. 任务执行的过程中拉取其他节点的block或者失败重试的成本会过高.
第四点: namenode监管容易判断数据节点死亡.导致集群频繁产生/移除副本, 占用cpu,网络,内存资源.
如果块设置太小:
第一点: 存放大量小文件会占用NameNode中大量内存来存储元数据
第二点: 文件块过小,寻址时间增大,导致程序一直在找block的开始位置
为什么设置为128M:
时间和空间的权衡,磁盘的传输速度大概在100M,寻址时间大概在1s,而且千兆网卡传输速度在100M/s 所以大概为100M
6. namenode对元数据的管理
namenode对数据的管理采用了三种存储形式:
-
内存元数据(NameSystem)
-
磁盘元数据镜像文件(fsimage镜像)
-
数据操作日志文件(可通过日志运算出元数据)(edit日志文件)
7. checkpiont 触发条件?
每隔一段时间,会由secondary namenode将namenode上积累的所有edits和一个最新的fsimage下载到本地,并加载到内存进行merge(这个过程称为checkpoint)
- 两次检查点创建之间的固定时间间隔,默认3600,即1小时。
- 检查的事务数量。若检查事务数达到这个值,也触发一次
8. DFSZKFailoverController的作用?
它是一个守护进程,它负责和ZK通信,并且时刻检查NameNode的健康状况。它通过不断的ping,如果能ping通,则说明节点是健康的。然后ZKFC会和ZK保持一个持久通话,及Session对话,并且ActiveNode在ZK里面记录了一个"锁",这样就会Prevent其它节点成为ActiveNode,当会话丢失时,ZKFC会发通知给ZK,同时删掉"锁",这个时候其它NameNode会去争抢并建立新的“锁”,这个过程叫ZKFC的选举。
9. MapReduce哪里使用了combiner?
combiner的作用是在Map端把同一个key的键值对合并在一起并计算
- 数据在环形缓存区根据分区排序完成,在溢写文件之前会执行一次combiner
- 多个溢写文件在进行merge合并时,也会触发一次combiner
10. MapReduce中partition的作用?
partition的主要作用将map阶段产生的所有kv对分配给不同的reducer task处理,可以将reduce阶段的处理负载进行分摊。
HashPartitioner是mapreduce的默认partitioner。
- 当map输出的时候,写入缓存之前,会调用partition函数,计算出数据所属的分区,并且把这个元数据存储起来。
- 把属与同一分区的数据合并在一起。
11. MapReduce中map,reduce数量如何决定,怎么配置?
1. map数量
- 默认map个数
(1)如果不进行任何设置,默认的map个数是和blcok_size相关的。
default_num = total_size / block_size;
(2)用户指定mapreduce.map.tasks
exp_num = max(exp_num, default_num)
(3)获取分片大小mapreduce.min.split.size
split_max_size = max(mapreduce.min.split.size , block_size)
(4) 获取分片个数
split_num = total_size / split_max_size
(5) 获取真实的map个数
real_num = min(split_num, exp_num)
- 如果想增加map个数,则设置mapred.map.tasks 为一个较大的值。减少mapred.min.split.size的值
- 如果想减小map个数,则设置mapred.min.split.size 为一个较大的值。减小mapred.map.tasks 为一个较小的值。
2. reduce数量
- 默认为-1,代表系统根据需要自行决定reduce个数(根据一个reduce能够处理的数据量来决定)
- 手动设置
12. MapReduce优化
数据输入:
- 在进行map任务前,合并小文件,大量的小文件会产生大量的map任务
- 采用combineTextInputformat来作为输入
Map阶段:
- 减少溢写(spill)次数:io.sort.mb 和 .sort.spill.percent 增大内存上限和溢写百分比
- 减少合并(merge)次数:调整io.sort.factor ,增大merge文件数目,减少merge次数
- 在map后,再不影响业务逻辑的情况下,先进行combiner处理
Reduce阶段:
- 设置合理的map和reduce数量:设置太少导致task任务等待,延长处理时间,太多会导致任务间资源竞争
- 增加每个Reduce去Map中拿数据的并行数
- 集群性能可以的前提下,增大 Reduce 端存储数据内存的大小。
I/O传输:
- 采用数据压缩的方式,减少网络 IO 的的时间。安装 Snappy 和 LZOP 压缩编码器。
- 使用orc,parquet,sequenceFile等文件格式
整体:
- MapTask 默认内存大小为 1G,可以增加 MapTask 内存大小为 4-5g
- ReduceTask 默认内存大小为 1G,可以增加 ReduceTask 内存大小为 4-5g
- 可以增加 MapTask 的 cpu 核数,增加 ReduceTask 的 CPU 核数
- 增加每个 Container 的 CPU 核数和内存大小
- 调整每个 Map Task 和 Reduce Task 最大重试次数
13. 用mapreduce怎么处理数据倾斜问题?
数据倾斜:map /reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,这是因为某一个key的条数比其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完,此称之为数据倾斜。
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
14. Hadoop高可用HA模式
HDFS高可用原理:
Hadoop HA(High Available)状态分别是Active和Standby. Standby Namenode作为热备份,从而允许在机器发生故障时能够快速进行故障转移,同时在日常维护的时候使用优雅的方式进行Namenode切换。Namenode只能配置一主一备,不能多于两个Namenode。
主Namenode处理所有的操作请求(读写),维护尽可能同步的状态,为了使Standby Namenode与Active Namenode数据保持同步,两个Namenode都与一组Journal Node进行通信。当主Namenode进行任务的namespace操作时,都会确保持久会修改日志到Journal Node节点中。Standby Namenode持续监控这些edit,当监测到变化时,将这些修改同步到自己的namespace。
当进行故障转移时,Standby在成为Active Namenode之前,会确保自己已经读取了Journal Node中的所有edit日志,从而保持数据状态与故障发生前一致。
确保任何时刻只有一个Namenode处于Active状态非常重要,否则可能出现数据丢失或者数据损坏。当两台Namenode都认为自己的Active Namenode时,会同时尝试写入数据(不会再去检测和同步数据)。为了防止这种脑裂现象,Journal Nodes只允许一个Namenode写入数据,内部通过维护epoch数来控制,从而安全地进行故障转移。
二、YARN
1. 集群资源分配参数(项目中遇到的问题)
集群有30台机器,跑mr任务的时候发现5个map任务全都分配到了同一台机器上,这个可能是由于什么原因导致的吗?
解决方案:yarn.scheduler.fair.assignmultiple 是否允许NodeManager一次分配多个容器 这个参数 默认是开的,需要关掉
2. yarn的几种调度器
FIFO: 单队列,先进先出,(生产环境一般不用)
CapacityScheduler(容量调度):多队列,队列内部任务先进先出 CDH默认
FairScheduler(公平调度):支持多队列,保证每个任务公平享有队列资源。apache 和 HDP 默认
3. yarn提交任务的流程
-
用户向YARN 中提交应用程序, 其中包括ApplicationMaster 程序、启动ApplicationMaster 的命令、用户程序等。
-
ResourceManager 为该应用程序分配第一个Container, 并与对应的NodeManager 通信,要求它在这个Container 中启动应用程序的ApplicationMaster。
-
ApplicationMaster 首先向ResourceManager 注册, 这样用户可以直接通过ResourceManage 查看应用程序的运行状态,然后它将为各个任务申请资源,并监控它的运行状态,直到运行结束,即重复步骤4~7。
-
ApplicationMaster 采用轮询的方式通过RPC 协议向ResourceManager 申请和领取资源。
-
一旦ApplicationMaster 申请到资源后,便与对应的NodeManager 通信,要求它启动任务。
-
NodeManager 为任务设置好运行环境(包括环境变量、JAR 包、二进制程序等)后,将任务启动命令写到一个脚本中,并通过运行该脚本启动任务。
-
各个任务通过某个RPC 协议向ApplicationMaster 汇报自己的状态和进度,以让ApplicationMaster 随时掌握各个任务的运行状态,从而可以在任务失败时重新启动任务。在应用程序运行过程中,用户可随时通过RPC 向ApplicationMaster 查询应用程序的当前运行状态。
-
应用程序运行完成后,ApplicationMaster 向ResourceManager 注销并关闭自己。
4. yarn中的 vcores 是什么意思?
在yarn中使用的是虚拟CPU,考虑到不同节点的CPU性能可能不同,每个CPU具有的计算能力不一,比如某个物理CPU的计算能力可能是另外一个物理CPU的2倍,这时候,你可以通过为第一个物理CPU多配置几个虚拟CPU弥补这种差异。用户提交作业时,可以指定每个任务需要的虚拟CPU个数。
三、HIVE
四、HBase
1. RegionServer上部署多少个region合适?
这个问题我觉得没有一个标准答案,可以从以下几方面进行阐述:
- memStore,因为每个region的每个列簇都有一个memStore,所以region过多,可能导致会频繁触发regionServer级别的阻塞flush,这个时候,基本数据写入服务会被阻塞,而且会带来小文件过多的问题。
- RS故障恢复,region的迁移 需要切分的hlog也过多。线程压力大
- BlockCache, 在一个jvm下,lru会频繁的进行block置换。
- hbase:meta 表维护的region过多,压力有点大。
五、Kafka
1. 如何优雅的关闭kafka,并且这样的好处是什么?
使用 kill -s term $KAFKA_PID 或者 kill -15 $KAFKA_PID 来进行关闭kafka,kafka程序入口有个钩子函数,待 Kafka 进程捕获终止信号的时候会执行这个关闭钩子中的内容。
好处:
- 将日志同步到磁盘里,当重启时,以避免需要做任何的日志恢复。日志恢复需要时间,所以这样可以加快启动。
- 将所有leader分区服务器移动到其他的副本,并且把每个分区不可用的几毫秒的时间降至更低。
其他更多kafka面试题:
https://www.cnblogs.com/erlou96/p/14401394.html
六、Zookeeper
七、spark
1. spark on Yarn,Yarn cluster 和 Yarn client模式区别:
Yarn cluster模式中,一般用于线上生产。应用程序都作为Yarn框架所需要的主应用程序(Application Master),并通过Yarn资源管理器(Yarn ResourceManager)为其分配的一个随机节点上运行。
Yarnclient模式中,一般用于本地代码调试,因为该模型下Spark上下文(Spark-Context)会运行在本地,如Spark Shell和Shark等。
2. spark常见的算子:
spark算子分为transform 和 action :
Transform :
- map
- flatmap
- mapPartitions
- sample(抽样)
- groupByKey
- reduceByKey
- union
- distinct
- join
- sortByKey
- repartition
- coalesce
Action:
- count(统计个数)
- collect(将结果收集到driver,容易oom)
- saveAsText
- take (提取前n个元素)
- first = take(1)
- reduce -> 将RDD内部的数据集按照顺序两两合并,直到产生最后一个值为止,并将其返回。即首先合并前两个元素,将结果与第三个元素合并,以此类推。
- foreach 函数func应用在数据集的每一个元素上,通常用于更新一个累加器,或者和外部存储系统进行交互,例如Redis.
3. repartition 和 coalesce 的区别?
4. map 、flatMap 和 mapPartitions 的区别?
5. spark读取hdfs文件的分区数
spark读hdfs文件的分区数由hdfs文件占用的文件块数决定。
例如:如果读取的一个hdfs文件大小为1280MB,可能是存储为10块,那么spark读取这个文件的分区数就是10。
spark的并行度是同一时刻进行任务计算的task的最大数量。如果分区数超过了并行度,那么就会排队计算。
比如读取的文件分区数是10,spark任务的并行度是5,同一时刻只会计算5个分区的内容,当某个分区计算完成空出资源之后才会计算其他分区。
6. SparkSession 和 SparkContext 关系
SparkSession是Spark 2.0引如的新概念。 我们通过sparkcontext来创建和操作RDD。对于每个其他的API,我们需要使用不同的context。 例如,对于Streming,我们需要使用StreamingContext;对于sql,使用sqlContext;对于Hive,使用hiveContext。 SparkSession内部封装了sparkContext,所以计算实际上是由sparkContext完成的。
7. 使用 saveAsHadoopFile 时生产 _SUCCESS 文件问题
使用 saveAsHadoopFile 保存文件时,有时候会产生 _SUCCESS 文件。使用下面的设置就可以不产生这个文件:
sparkConf.set(“spark.hadoop.mapreduce.fileoutputcommitter.marksuccessfuljobs”, “false”);
8. 关于 Spark Streaming 中 LocationStrategies 的设置
- LocationStrategies.PreferBrokers():仅仅在你 spark 的 executor 在相同的节点上,优先分配到存在 kafka broker 的机器上;
- LocationStrategies.PreferConsistent():大多数情况下使用,一致性的方式分配分区所有 executor 上。(主要是为了分布均匀)
- LocationStrategies.PreferFixed():如果你的负载不均衡,可以通过这两种方式来手动指定分配方式,其他没有在 map 中指定的,均采用 preferConsistent() 的方式分配;
9. spark vs mapreduce
- Spark vs Mapreduce 内存 vs 磁盘
spark 和 mapreduce 计算都是发生在内存中,区别在于:Mapreduce 需要将中间计算的结果写入磁盘,然后再读取磁盘,从而导致了频繁的磁盘io。
spark则不需要将中间计算结果保存在磁盘,得益于RDD(弹性分布式数据集)和DAG(有向无环图)
DAG记录了job的stage以及在job执行过程中父RDD和子RDD之间的依赖关系。
中间结果能够以RDD的形式存放在内存中,且能够从DAG中恢复,大大减少了磁盘IO。
2.spark和MapReduce Shuffle,两者至少有一点不同:
MapReduce在Shuffle时需要花费大量时间进行排序,排序在MapReduce的Shuffle中似乎是不可避免的;
Spark在Shuffle时则只有部分场景才需要排序,支持基于Hash的分布式聚合,更加省时;
3.多进程模型 vs 多线程模型的区别
MapReduce采用了多进程模型,而Spark采用了多线程模型。
多进程模型的好处是便于细粒度控制每个任务占用的资源,但每次任务的启动都会消耗一定的启动时间。就是说MapReduce的Map Task和Reduce Task是进程级别的,而Spark Task则是基于线程模型的。
mapreduce 中的 map 和 reduce 都是 jvm 进程,每次启动都需要重新申请资源,消耗了不必要的时间(假设容器启动时间大概1s,如果有1200个block,那么单独启动map进程事件就需要20分钟)
Spark则是通过复用线程池中的线程来减少启动、关闭task所需要的开销。
八、Java
1. intern()
String str1=new StringBuilder("58").append("58").toString();
System.out.println(str1.intern() == str1); // true
String str2=new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern() == str2); // false
九、linux
1. 找出/data/目录下大于10k的文件,并将其移动到/databak下
find /data -size +10k -exec mv {} /databak \;
2. 设置linux 默认的文件权限
umask 0022 // 文件默认755,文件夹默认644(少一个可执行)
十、杂谈
1. http 错误状态码:
- 500 服务器内部错误,代码级别的
- 502 错误网关
- 403 - 禁止访问
- 404 - 无法找到文件
2. kerberos 主备切换,数据同步问题
1. 使用kdb5_util dump 备份kdc数据库
2. 在使用kprop -f /var/kerberos/krb5kdc/kdc.dumpkerberos2.example.com
以上命令,可以封装成一个bash,定时运行,即定时更新slave上的database。
3. ping小包和ping大包的区别,有什么用?
ping小包是主要是测试连通性
ping大包是主要是测试网络传输能力
故:网络联通不等于网络传输性能好