大数据面试-20210312

目录

 

基础题

 

1、介绍一下拉链表的原理,以及适用于哪些场景?

 

2、如果使用spark遇到了 OOM ,你会怎么处理?

智力题

 

3、A 文件有 50 亿条 URL,B 文件也有 50 亿条 URL,每条 URL 大小为 64B,在一台只有 4G 内存的机器上,怎么找出 A、B 中相同的 URL?


基础题

 

1、介绍一下拉链表的原理,以及适用于哪些场景?

拉链表是一种数据模型,主要是针对数据仓库设计中表存储数据的方式而定义的;顾名思义,所谓拉链表,就是记录历史,记录一个事务从开始一直到当前状态的所有变化的信息。

拉链表可以避免按每一天存储所有记录造成的海量存储问题,同时也是处理缓慢变化数据(SCD2)的一种常见方式。

原理:说白了就是在原有表基础上增加两个字段,一个start_time,一个end_time

数据如果不变就不动,如果有新数据进来,就将原数据的end_time天数-1(改成前天),start_time不变,新数据的start_time写成今天,end_time设置成9999-12-31 这其中的操作都在新建的两张临时表(update表和tmp表)中进行,它适合最大程度节省存储空间,又能满足数据历史状态的场景

 

思考题

 

2、如果使用spark遇到了 OOM ,你会怎么处理?

Driver OOM

  • driver端生成大对象
  • 将大对象转换成Executor端加载,比如调用sc.textfile
  • 评估大对象占用的内存,增加dirver-memory的值

collect数据收集导致

  • 本身不建议将大的数据从executor端,collect回来。建议将driver端对collect回来的数据所作的操作,转换成executor端rdd操作,若无法避免,估算collect需要的内存,相应增加driver-memory的值。

Executor OOM

  • java.lang.OutOfMemoryError: Java heap space
  • 原因:1、数据量太大,申请的Executor资源不足以支撑。2.单分区的数据量过大,和分区数过多导致执行task和job存储的信息过多导致Driver OutOfMemoryError
  • 解决方法:1、尽量不要使用collect操作。2、查看数据是否有倾斜,增加shuffle的并行度,加大Executor内存
  • shuffle 报 org.apache.spark.shuffle.FetchFailedException: Direct buffer memory
  • 原因:堆外内存不够导致,直接内存
  • 解决方法:增大JVM 参数-XX:MaxDirectMemorySize(如:spark.executor.extraJavaOptions = -XX:MaxDirectMemorySize=xxxm)
  • java.lang.OutOfMemoryError:GC overhead limit exceeded
  • 当 Java 进程花费 98% 以上的时间执行 GC,但只恢复了不到 2% 的内存,且该动作连续重复了 5 次,就会抛出 这个报错。此类问题的原因与解决方案跟 Javaheap space 非常类似,参考上面的。

Permanent Generation OOM

永久代存储对象主要包括以下几类:

  • 加载/缓存到内存中的 class 定义,包括类的名称,字段,方法和字节码;
  • 常量池
  • 对象数组、类型数组所关联的 class
  • 解决办法
  • 修改-XX:MaxPermSize 启动参数,调大永久代空间。
  • 如果上述无法解决,可以用 jmap 命令 dump 内存快照,然后用 Eclipse MAT 功能分析开销最大的 classloader 和重复的 class。
  • Permanent Generation OOM
  • 该错误表示 Metaspace 已被用满,通常是因为加载的 class 数目太多或体积太大。此类问题的原因与解决方法跟 Permgenspace 非常类似,可以参考上文。需要特别注意的是调整 Metaspace 空间大小的启动参数为 -XX:MaxMetaspaceSize
  • Spark on Yarn
  • Driver 经常被 container kill(container的物理和虚拟内存不够)
  • Container [pid=1151,containerID=container_1578970174552_5615_01_000001] is running beyond physical memory limits. Current usage: 4.3 GB of 4 GB physical memory used; 7.8 GB of 8.4 GB virtual memory used. Killing container.增大spark.yarn.driver.memoryoverhead 值,默认此参数是 1GB。
  • container_1578970174552_5615_01_000001: 4.3 GB of 4 GB physical memory used; 7.8 GB of 8.4 GB virtual memory used. 增加虚拟内存的比例,虚拟内存上限 = 物理内存上限 x yarn.nodemanager.vmem-pmem-ratio(Apache版本默认是2.1)

Executor 经常被 container kill(container的物理和虚拟内存不够)

  • Container [pid=1151,containerID=container_1578970174552_5615_01_000004] is running beyond physical memory limits. Current usage: 4.3 GB of 4 GB physical memory used; 7.8 GB of 8.4 GB virtual memory used. Killing container.增大spark.yarn.executor.memoryoverhead 值,默认此参数是 1GB。
  • container_1578970174552_5615_01_000005: 4.3 GB of 4 GB physical memory used; 7.8 GB of 8.4 GB virtual memory used. 增加虚拟内存的比例,虚拟内存上限 = 物理内存上限 x yarn.nodemanager.vmem-pmem-ratio(Apache版本默认是2.1)

当然还有一种办法,不过不推荐使用,把检查物理内存和虚拟的内存的参数都关闭

大数据面试-20210312_第1张图片

  • 注意 :container_xx_000001 是 driver 所在的 container
  • Executor 自动 dump命令

–conf spark.executor.extraJavaOptions=“-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/srv/Bigdata/spark.bin”

Driver 自动 dump 命令

–conf spark.driver.extraJavaOptions=“-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/srv/Bigdata/spark.bin”

  • 如果增加了内存,或者调整了heap ,老年代,新生代,永久代这些比例后,还是经常出现 OOM,建议在 Spark 提交脚本里面增加上述的命令,方便复现 OOM,然后用 Eclipse MAT 分析,或者用 Parfma 社区提供的工具分析,也当然可以用阿里开源的 Arthas 工具分析。

总结

先调整参数值,调整的过程是逐渐调整,不要一下参数值变化很多(一般变化2倍就行),如果调整过1,2次还是出现 OOM,则需要 heap dump内存快照,然后用自己喜欢的工具对应分析,看是代码啥地方的问题。

 

智力题

 

3、A 文件有 50 亿条 URL,B 文件也有 50 亿条 URL,每条 URL 大小为 64B,在一台只有 4G 内存的机器上,怎么找出 A、B 中相同的 URL?

本题来源:https://mp.weixin.qq.com/s/u5LoPxhXpKbx9CUR5qqQqg 大数据肌肉猿

针对这种大数据量的问题,通常要想到「分而治之」。为了方便讲解,我这里就先计算一下。

 

50 亿条 URL 文件的大小:50 * 10^8 * 64 Byte ≈ 32 * 10^10 Byte ≈ 320G

 

用流程图表示:

 

大数据面试-20210312_第2张图片

 

 

借助 Hash 函数,依次扫描 A、B 两个文件,将 URL 分别存储到 1000 个小文件中,那么每个文件大约 300M,满足内存的需求,文件以 0-999 的数字结尾作为编号,下面说下具体过程。

 

首先遍历 A 文件,对每个 URL 取 hash(url)%1000 的值,该值就是 URL 要存储到小文件的编号,最终所有 URL 分别存储在 1000 个小文件中,文件名记成以下形式: a0、a1、…、a999。

 

再遍历 B 文件,用同样的方法将 B 文件的 URL 分别存储在 b0、b1、…、b999 这 1000 个小文件中。

 

我们知道 Hash 的一个特点:相同的 key,hash 之后的 value 一定是相同的。所以,对于 A、B 文件中相同的 URL,Hash 之后,一定会存储到相同下标的文件中。

 

如果 Hash 函数设计合理,将数据均匀分散,每个文件大致 300M。

我们再读取相同下标的小文件到内存中,判断是否存在相同的 URL 即可

 

你可能感兴趣的:(大数据之Spark,大数据之面试,大数据之Hive,spark,hive,hadoop)