大数据问题

目录

一、HDFS

1. HDFS的读流程

2. HDFS的写流程

3. Hadoop有哪些配置文件?

4. 小文件过多会造成什么影响?

5. block为什么设置成128M,为什么不建议设置太大,或者太小?

6. namenode对元数据的管理

7. checkpiont 触发条件?

8. DFSZKFailoverController的作用?

9. MapReduce哪里使用了combiner?

10. MapReduce中partition的作用?

11. MapReduce中map,reduce数量如何决定,怎么配置?

12. MapReduce优化

13. 用mapreduce怎么处理数据倾斜问题?

14. Hadoop高可用HA模式

二、YARN

 1. 集群资源分配参数(项目中遇到的问题)

 2. yarn的几种调度器

3. yarn提交任务的流程

4. yarn中的 vcores 是什么意思?

三、HIVE

四、HBase

1. RegionServer上部署多少个region合适?

五、Kafka

 1. 如何优雅的关闭kafka,并且这样的好处是什么?

其他更多kafka面试题:

六、Zookeeper

七、spark

1. spark on Yarn,Yarn cluster 和 Yarn client模式区别:

2. spark常见的算子:

3. repartition 和 coalesce 的区别?

4. map 、flatMap 和 mapPartitions 的区别?

5. spark读取hdfs文件的分区数

6. SparkSession 和 SparkContext 关系

7. 使用 saveAsHadoopFile 时生产 _SUCCESS 文件问题

8. 关于 Spark Streaming 中 LocationStrategies 的设置

八、Java

1. intern()

九、linux

1. 找出/data/目录下大于10k的文件,并将其移动到/databak下

2. 设置linux 默认的文件权限

十、杂谈

1. http 错误状态码:

2. kerberos 主备切换,数据同步问题


一、HDFS

1. HDFS的读流程

  1.  客户端向NameNode发起读数据请求;
  2.  NameNode响应请求并告诉客户端要读的文件的数据块位置(存在哪个DataNode上);
  3.  客户端到对应DataNode读取数据,当数据读取到达末端,关闭与这个DataNode的连接,并查找下一个数据块,直到文件数据全部读完;
  4.  最后关闭输出流。

2. HDFS的写流程

  1.     客户端向NameNode发起写数据请求;
  2.  NameNode相应请求(NameNode会检查要创建的文件是否已经存在,创建者是否有权限,成功会创建一个记录,失败会报异常); 
  3.  客户端将文件进行切片(分成数据块),然后上传数据块,按照一个一个的形式进行发送,每个数据块都要写到三个DataNode上;
  4.  成功后DataNode会返回一个确认队列给客户端,客户端进行效验,然后客户端上传下一个数据块到DataNode,直到所有数据块写入完成;
  5.  当所有数据块全部写入成功后,客户端会向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负荷比较大。

解决方案:

  1. 采用har归档方式,将小文件归档
  2. 采用CombineTextInputFormat
  3. 有小文件场景开启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提交任务的流程

  1. 用户向YARN 中提交应用程序, 其中包括ApplicationMaster 程序、启动ApplicationMaster 的命令、用户程序等。

  2. ResourceManager 为该应用程序分配第一个Container, 并与对应的NodeManager 通信,要求它在这个Container 中启动应用程序的ApplicationMaster。

  3. ApplicationMaster 首先向ResourceManager 注册, 这样用户可以直接通过ResourceManage 查看应用程序的运行状态,然后它将为各个任务申请资源,并监控它的运行状态,直到运行结束,即重复步骤4~7。

  4. ApplicationMaster 采用轮询的方式通过RPC 协议向ResourceManager 申请和领取资源。

  5.  一旦ApplicationMaster 申请到资源后,便与对应的NodeManager 通信,要求它启动任务。

  6. NodeManager 为任务设置好运行环境(包括环境变量、JAR 包、二进制程序等)后,将任务启动命令写到一个脚本中,并通过运行该脚本启动任务。

  7. 各个任务通过某个RPC 协议向ApplicationMaster 汇报自己的状态和进度,以让ApplicationMaster 随时掌握各个任务的运行状态,从而可以在任务失败时重新启动任务。在应用程序运行过程中,用户可随时通过RPC 向ApplicationMaster 查询应用程序的当前运行状态。

  8.  应用程序运行完成后,ApplicationMaster 向ResourceManager 注销并关闭自己。

4. yarn中的 vcores 是什么意思?

在yarn中使用的是虚拟CPU,考虑到不同节点的CPU性能可能不同,每个CPU具有的计算能力不一,比如某个物理CPU的计算能力可能是另外一个物理CPU的2倍,这时候,你可以通过为第一个物理CPU多配置几个虚拟CPU弥补这种差异。用户提交作业时,可以指定每个任务需要的虚拟CPU个数。

三、HIVE

四、HBase

1. RegionServer上部署多少个region合适?

这个问题我觉得没有一个标准答案,可以从以下几方面进行阐述:

  1. memStore,因为每个region的每个列簇都有一个memStore,所以region过多,可能导致会频繁触发regionServer级别的阻塞flush,这个时候,基本数据写入服务会被阻塞,而且会带来小文件过多的问题。
  2. RS故障恢复,region的迁移 需要切分的hlog也过多。线程压力大
  3. BlockCache, 在一个jvm下,lru会频繁的进行block置换。
  4. 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 :

  1. map
  2. flatmap
  3. mapPartitions
  4. sample(抽样)
  5. groupByKey
  6. reduceByKey
  7. union
  8. distinct
  9. join
  10. sortByKey
  11. repartition
  12.  coalesce

Action:

  1. count(统计个数)
  2. collect(将结果收集到driver,容易oom)
  3. saveAsText
  4. take (提取前n个元素)
  5. first   =  take(1)
  6. reduce -> 将RDD内部的数据集按照顺序两两合并,直到产生最后一个值为止,并将其返回。即首先合并前两个元素,将结果与第三个元素合并,以此类推。
  7. 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

  1. 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 错误状态码:

  1. 500 服务器内部错误,代码级别的
  2. 502 错误网关 
  3. 403 - 禁止访问
  4. 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大包是主要是测试网络传输能力


故:网络联通不等于网络传输性能好

posted @ 2022-11-10 19:26  彬在俊  阅读(289)  评论(0编辑  收藏  举报