最近面试了一家公司,大数据平台研发的。面试的内容主要是运维和运维开发工作,排查项目中的问题点,目的是提高hadoop集群的性能,我把面试题总结了一下。虽然开发工程不会全面的遇到下面的问题,就做个总结,分享一下,供个人的知识部分吧。
原因可能如下:
1.负载过重:在集群中的任务过多,可能会导致任务的负载过重,并导致频繁切换。
2。内存不足:当集群中处理的数据量多大,可能会导致内存不足,并导致namenode频繁切换。
3.垃圾回收:如果jvm的回收频率过高,也可能导致namenode频繁切换。
4.网络问题:如果namenode和datanode之间的网络连接出现问题,可能会导致namenode的频繁切换。
解决办法
1.增加集群资源:通过增加节点或调整配置来增加集群资源,从而降低负载;
2.调整jvm参数:可以尝试减少垃圾回收的频率,提高namenode性能;
3.检查网络连接:检查是否稳定,如ping操作
案例:在短时间内创建或删除了大量文件,引发了active NN节点频繁更新本地内存的数据结构,这会导致RPC的处理时长增加,CallQueue中的rpcCall堆积(严重的情况下会撑满CallQueue),从而导致active状态的NN长时间不响应ZKFC的HealthMonitor子进程,于是ActiveStandbyElector就会断开与ZooKeeper的连接,从而释放锁,于是master2节点上的ActiveStandbyElector就会从zookeeper争抢锁,抢到锁之后的NN就会从standby转换成active状态。
案例解决办法:先调高NameNode的参数ha.health-monitor.rpc-timeout.ms值,该参数位于core-site.xml文件中,此参数是指ZKFC的健康检查超时的时长,默认值45000ms,现已修改为120000ms(2分钟)。改完NN参数后,需要重启相关的NameNode。另外,如果内存足够,可以顺便把两个NameNode的heap size适当调大一些。
参考:案例参考地址
如何保持主和备NameNode的状态同步,并让Standby在Active挂掉后迅速提供服务,namenode启动比较耗时,包括加载fsimage和editlog(获取file to block信息),处理所有datanode第一次blockreport(获取block to datanode信息),保持NN的状态同步,需要这两部分信息同步。
脑裂(split-brain),指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,本来为一个整体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会导致系统混乱,数据损坏。
ZKFC的设计
1. FailoverController实现下述几个功能
(a) 监控NN的健康状态
(b) 向ZK定期发送心跳,使自己可以被选举。
(c) 当自己被ZK选为主时,active FailoverController通过RPC调用使相应的NN转换为active。
2. 为什么要作为一个deamon进程从NN分离出来
(1) 防止因为NN的GC失败导致心跳受影响。
(2) FailoverController功能的代码应该和应用的分离,提高的容错性。
(3) 使得主备选举成为可插拔式的插件。
3. FailoverController主要包括三个组件,
(1) HealthMonitor 监控NameNode是否处于unavailable或unhealthy状态。当前通过RPC调用NN相应的方法完成。
(2) ActiveStandbyElector 管理和监控自己在ZK中的状态。
(3) ZKFailoverController 它订阅HealthMonitor 和ActiveStandbyElector 的事件,并管理NameNode的状态。
1)NameNode内存计算
每个文件块大概占用150byte,一台服务器128G内存为例,能存储多少文件块呢?
128 * 1024 * 1024 * 1024 / 150Byte ≈ 9.1亿
G MB KB Byte
2)Hadoop2.x系列,配置NameNode内存
NameNode内存默认2000m,如果服务器内存4G,NameNode内存可以配置3g。在hadoop-env.sh文件中配置如下。
HADOOP_NAMENODE_OPTS=-Xmx3072m
3)Hadoop3.x系列,配置NameNode内存
(1)hadoop-env.sh中描述Hadoop的内存是动态分配的
# The maximum amount of heap to use (Java -Xmx). If no unit
# is provided, it will be converted to MB. Daemons will
# prefer any Xmx setting in their respective _OPT variable.
# There is no default; the JVM will autoscale based upon machine
# memory size.
# export HADOOP_HEAPSIZE_MAX=
# The minimum amount of heap to use (Java -Xms). If no unit
# is provided, it will be converted to MB. Daemons will
# prefer any Xms setting in their respective _OPT variable.
# There is no default; the JVM will autoscale based upon machine
# memory size.
# export HADOOP_HEAPSIZE_MIN=
HADOOP_NAMENODE_OPTS=-Xmx102400m
(2)查看NameNode占用内存
[hadoop102 ~]$ jps
3088 NodeManager
2611 NameNode
3271 JobHistoryServer
2744 DataNode
3579 Jps
[hadoop102 ~]$ jmap -heap 2611
Heap Configuration:
MaxHeapSize = 1031798784 (984.0MB)
(3)查看DataNode占用内存
jmap -heap 2744
查看发现hadoop102上的NameNode和DataNode占用内存都是自动分配的,且相等。不是很合理。
export HDFS_NAMENODE_OPTS="-Dhadoop.security.logger=INFO,RFAS -Xmx1024m"
export HDFS_DATANODE_OPTS="-Dhadoop.security.logger=ERROR,RFAS -Xmx1024m"
1)hdfs-site.xml
The number of Namenode RPC server threads that listen to requests from clients. If dfs.namenode.servicerpc-address is not configured then Namenode RPC server threads listen to requests from all nodes.
NameNode有一个工作线程池,用来处理不同DataNode的并发心跳以及客户端并发的元数据操作。
对于大集群或者有大量客户端的集群来说,通常需要增大该参数。默认值是10。
dfs.namenode.handler.count
21
企业经验:dfs.namenode.handler.count=20×〖log〗_e^(Cluster Size),比如集群规模(DataNode台数)为3台时,此参数设置为21。可通过简单的python代码计算该值,代码如下。
[hadoop102 ~]$ sudo yum install -y python
[hadoop102 ~]$ python
Python 2.7.5 (default, Apr 11 2018, 07:36:10)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import math
>>> print int(20*math.log(3))
21
>>> quit()
开启回收站功能,可以将删除的文件在不超时的情况下,恢复原数据,起到防止误删除、备份等作用。
1)回收站工作机制
2)开启回收站功能参数说明
(1)默认值fs.trash.interval = 0,0表示禁用回收站;其他值表示设置文件的存活时间。
(2)默认值fs.trash.checkpoint.interval = 0,检查回收站的间隔时间。如果该值为0,则该值设置和fs.trash.interval的参数值相等。
(3)要求fs.trash.checkpoint.interval <= fs.trash.interval。
3)启用回收站
修改core-site.xml,配置垃圾回收时间为1分钟。
fs.trash.interval
1
4)查看回收站
回收站目录在HDFS集群中的路径:/user/root/.Trash/….
5)注意:通过网页上直接删除的文件也不会走回收站。
6)通过程序删除的文件不会经过回收站,需要调用moveToTrash()才进入回收站
Trash trash = New Trash(conf);
trash.moveToTrash(path);
7)只有在命令行利用hadoop fs -rm命令删除的文件才会走回收站。
[hadoop102 hadoop-3.1.3]$ hadoop fs -rm -r /user/root/input
2021-07-14 16:13:42,643 INFO fs.TrashPolicyDefault: Moved: 'hdfs://hadoop102:9820/user/atguigu/input' to trash at: hdfs://hadoop102:9820/user/atguigu/.Trash/Current/user/atguigu/input
8)恢复回收站数据
[hadoop102 hadoop-3.1.3]$ hadoop fs -mv
/user/atguigu/.Trash/Current/user/atguigu/input /user/atguigu/input
1、提高内存配置:提高内存可以降低磁盘的访问次数,缩短IO等待的时间,提高系统的IO处理能力,提高数据节点的性能。
2、增加磁盘数量或更换更快的存储设备:增加磁盘数量可以将数据分散到不同的磁盘上,减少I/O竞争,提高磁盘的吞吐量;更换更快的存储设备可以提高数据节点的性能。
3、修改配置文件:针对datanode空间不足的情况,可以调整dfs.datanode.du.reserved和dfs.datanode.max.xcievers配置,以保证文件系统的稳定性,提高数据节点的性能。
4、调整block size:调整block size可以提高磁盘I/O的效率,提高数据节点的性能。
5、禁用磁盘预读:禁用磁盘预读可以减少磁盘I/O的次数,提高数据节点的性能。
1、优化NameNode
(1)增大NameNode的内存
由于大量的文件操作,NameNode的内存压力会变得很大,要提高NameNode的性能,首先要考虑的是增大NameNode的内存。可以通过更改hadoop-env.sh文件中的HADOOP_NAMENODE_OPTS参数来增大NameNode的内存。
(2)增大NameNode的存储空间
为了支持更多的文件操作,可以考虑增加NameNode的存储空间,这样可以提高hdfs的性能。可以通过更改hdfs-site.xml文件中的dfs.name.dir参数来增加NameNode的存储空间。
2、优化DataNode
(1)增大DataNode的内存
DataNode的内存压力也会很大,可以通过更改hadoop-env.sh文件中的HADOOP_DATANODE_OPTS参数来增大DataNode的内存。
(2)增大DataNode的存储空间
为了支持更多的数据存储,可以考虑增加DataNode的存储空间,这样可以提高hdfs的性能。可以通过更改hdfs-site.xml文件中的dfs.data.dir参数来增加DataNode的存储空间。
(3)增加DataNode的数量
为了提高hdfs的性能,可以考虑增加DataNode的数量,这样可以提高文件存储和访问的性能。可以通过更改hdfs-site.xml文件中的dfs.datanode.data.dir参数来增加DataNode的数量。
3、优化文件系统
(1)增大文件系统的块大小
为了提高文件的访问性能,可以考虑增大文件系统的块大小,这样可以减少文件存储和访问的次数,提高hdfs的性能。可以通过更改hdfs-site.xml文件中的dfs.block.size参数来增大文件系统的块大小。
(2)减少文件系统
1.块大小调整:hdfs默认块大小是128mb,根据不同应用的数据访问模式和节点硬件特性等因素,可能需要调整块大小。如果文件的访问模式以顺序读取为主,那么增大块大小可以提高I/O吞吐量;如果文件的访问模式以读取为主,那么缩小块大小可以减少数据的读取延迟。
2.副本数的设置:副本数指的是每个数据块在hdfs中存储的备份数,默认为3.可以根据数据的重要性,节点的可靠性等因素来设置副本数。
3.数据压缩:对于一些数据类型可以使用压缩技术,如snappy,lzo等。在保证数据可读性的前提下,通过压缩可以减少磁盘空间占用和网络传输带宽。
4.预热机制:通过预先将热点数据放置到内存中,可以避免冷启动时数据加载导致的性能问题。这可以通过使用Hadoop cache 或者memcached等工具实现。
5. 节点管理优化:包括优化节点的磁盘和内存配置,以及定期进行节点健康度检查和数据块均衡等。
6. 使用SSD:如果条件允许,可以将部分数据或元数据存储在 SSD上,以提高 HDFS的访问速度。
对于 YARN 的优化,可以从以下几个方面入手:
(1)根据HDFS的应用场景调整HDFS配置参数,使其可以满足应用场景的要求;
(2)调优时要注意参数之间的依赖性关系,避免出现调优参数之间的冲突;
(3)调优时需要考虑硬件环境,例如网络带宽、服务器内存、CPU等;
(4)尽可能少的调整HDFS配置参数,相同参数可以使用相同的值;
(5)不要过度调优,调优以后应该全面检查系统的稳定性和性能,确认是否达到调优的目标。
(1)dfs.namenode.handler.count:HDFS的NameNode处理请求的线程数,默认是10;
(2)dfs.namenode.max.objects:HDFS的NameNode在内存中存储的文件最多数量,默认是10 000;
(3)dfs.namenode.replication.min:HDFS的NameNode最小副本数,默认是1;
(4)dfs.datanode.max.transfer.threads:HDFS的DataNode的最大传输线程数,默认是40;
(5)dfs.datanode.socket.write.timeout:HDFS的DataNode写Socket超时时间,单位为毫秒,默认是180000;
(6)dfs.blocksize:HDFS的块大小,单位为字节,默认是67108864;
(7)dfs.namenode.safemode.threshold-pct:HDFS的NameNode安全模式的阈值,单位为百分比,默认是0.999;
(8)dfs.namenode.safemode.extension:HDFS的NameNode安全模式的延长时间,单位为秒,默认是30000;
(9)dfs.namenode.accesstime.precision
在Linux 系统中,可以通过 top 命令查看当前系统的进程情况,并按照 CPU 占用率进行排序。
具体操作如下:
HDFS 查询慢的原因可能有很多,以下是一些常见的原因:
解决这些问题的方法可能包括:
在大数据处理中,数据倾斜是指某个或某些任务所处理的数据量远远大于其他任务的情況。判断数据倾斜可以从以下几个方面入手:
集群重启任务自动重启的实现方式可以通过在集群管理系统中设置自动重启策略,具体包括以下几个步骤:
1.在集群管理系统中创建一个自动重启策略。
2. 将需要自动重启的任务添加到该重启策略中。
3. 配置任务自动重启的规则,如自动重启次数、时间间隔等。
4. 启用自动重启策略,使其生效。
这样配置后,当集群重启时,自动重启策略会自动将任务重新启动,确保任务的连续性和稳定性。
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
1)NameNode的本地目录可以配置成多个,且每个目录存放内容相同,增加了可靠性
2)具体配置如下
(1)在hdfs-site.xml文件中添加如下内容
dfs.namenode.name.dir
file://${hadoop.tmp.dir}/dfs/name1,file://${hadoop.tmp.dir}/dfs/name2
注意:因为每台服务器节点的磁盘情况不同,所以这个配置配完之后,可以选择不分发
(2)停止集群,删除三台节点的data和logs中所有数据。
[hadoop102 hadoop-3.1.3]$ rm -rf data/ logs/
[hadoop103 hadoop-3.1.3]$ rm -rf data/ logs/
[hadoop104 hadoop-3.1.3]$ rm -rf data/ logs/
(3)格式化集群并启动。
[hadoop102 hadoop-3.1.3]$ bin/hdfs namenode -format
[hadoop102 hadoop-3.1.3]$ sbin/start-dfs.sh
3)查看结果
[hadoop102 dfs]$ ll
总用量 12
drwx------. 3 root root4096 12月 11 08:03 data
drwxrwxr-x. 3 root root 4096 12月 11 08:03 name1
drwxrwxr-x. 3 root root 4096 12月 11 08:03 name2
检查name1和name2里面的内容,发现一模一样。
1)DataNode可以配置成多个目录,每个目录存储的数据不一样(数据不是副本)
2)具体配置如下
在hdfs-site.xml文件中添加如下内容
dfs.datanode.data.dir
file://${hadoop.tmp.dir}/dfs/data1,file://${hadoop.tmp.dir}/dfs/data2
3)查看结果
[root @hadoop102 dfs]$ ll
总用量 12
drwx------. 3 root root 4096 4月 4 14:22 data1
drwx------. 3 root root 4096 4月 4 14:22 data2
drwxrwxr-x. 3 root root 4096 12月 11 08:03 name1
drwxrwxr-x. 3 root root 4096 12月 11 08:03 name2
4)向集群上传一个文件,再次观察两个文件夹里面的内容发现不一致(一个有数一个没有)
[root @hadoop102 hadoop-3.1.3]$ hadoop fs -put wcinput/word.txt /
HDFS 的源码主要包括以下几个部分:
大数据组件异常定位可以通过以下几个步骤来实现:
可以通过以下几个步骤来实现:
常见的HDFS二次开发内容包括:
总之,HDFS二次开发需要熟悉Hadoop生态圈和API接口,并根据需求和目标编写相应的代码逻辑,最终进行测试、调试、部署和运行。
我当时回答的是写入3个(默认副本数为3的情况下)
他笑了笑说一个(当时感觉被嫌弃了哈哈)。。。emmm 我记得也是达到副本个数才算成功