其他
一个月面试近 20 家,拿下阿里 Offer!
The following article is from 三太子敖丙 Author 三太子敖丙
面试准备
Hadoop
如果在现场,我可以手绘 MapReduce 从 InputFormat 到 OutputFormat 的流程,一边画图一边说。如果讲到环形缓冲区那里,是不是有很多调优的方式、combiner 也可以考虑讲一下。
至少自己集群的配置、框架的技术选型是不是都要清楚的明明白白。
1、HDFS 小文件的影响 、输入输入时的小文件的处理 2、Map 阶段 和 Reudce 阶段的调优 3、数据压缩(LZO \Snappy) 和 存储优化(Orcfile) 关于压缩怎么配的,几种存储格式有什么区别是不是都要搞清楚
FIFO 、Capacity Scheduler(容量调度器)和 Fair Sceduler(公平调度器)三种需要区分清楚,还有在实际开发环境中,一般不用FIFO哦。
1、提前在 map 进行 combine,减少传输的数据量 2、导致数据倾斜的 key 加盐、提升 Reducer 并行度 ...
步骤很多,理理清楚然后再由条理的进行回答。
Hive
数据存储位置、数据更新、执行延迟、数据规模等方面来比较。
hive表中的数据是HDFS上的文件,可是hive怎么知道这些文件的内容都对应哪个字段,对应哪个分区呢?就是hive的元数据管理着这一切。通常在hive-site.xml中的元数据库配置成MySQL,替换Derby。
常规的数据解决方式,结合业务,随便讲个三四种不过分吧。
1、压缩存储优化 2、表设计优化 3、SQL参数优化 4、SQL语句优化 分四个方向,大概十几种优化的方式,自己都得做些了解吧
ORC:行分块,列式存储,压缩快,存取快,压缩率最高,RCfile升级版。然后再和其他三种存储方式比较一下。
Flume
Source、Channel、Sink ,想想Flume的架构。Taildir Source、Memory Channel什么的,各自适合用在什么场景下,有什么区别。
可以在讲项目时讲,算是一个小亮点,可以自定义ETL 拦截器和区分类型拦截器等等
Replicating Channel Selector (default)和Multiplexing Channel Selector 这两种Selector的区别是:Replicating 会 将source过来的events发往所有channel,而 Multiplexing可以选择该发往哪些Channel。
要知道flume-ng agent包括source、channel、sink三个部分,这三部分都运行在JVM上,而JVM运行在linux操作系统之上。因此,对于flume的性能调优,就是对这三部分及影响因素调优。
Kafka
顺序写入、Memory Mapped Files、零拷贝(Zero Copy)、批量发送和数据压缩。
ACK 机制 、 设置分区、关闭 unclean leader 选举等等。
如果是 Kafka 消费能力不足,则可以考虑增加 Topic 的分区数,并且同时提升消费 组的消费者数量,消费者数=分区数。(两者缺一不可) 如果是下游的数据处理不及时:提高每批次拉取的数量。批次拉取数据过少(拉取 数据/处理时间<生产速度),使处理的数据小于生产的数据,也会造成数据积压。
副本数据同步策略、ISR、OSR、Leader 选举机制(它的和Zookeeper的半数选举机制可不同哦)。
幂等性+ack-1+事务 Kafka 数据重复,可以再下一级:SparkStreaming、redis 或者 hive 中 dwd 层去重,去重的手段:分组、按照 id 开窗只取第一个值。
HBase
三个设计原则,id+时间戳反转 什么的,结合你的业务场景讲讲。
1、列簇的数量对flush的影响 2、列簇的数量对split的影响 3、列簇的数量对compaction的影响 4、列簇的数量对HDFS的影响 5、列簇的数量对RegionServer内存的影响 。根据实际生产需求,能够用一个列簇解决的就尽量用一个列簇,当两个列簇的数量相差悬殊时,可以将其两个列簇的数据拆分为两个表的单个列簇。
HBase中的每张表都通过行键按照一定的范围被分割成多个子表(HRegion),默认一个HRegion超过256M就要被分割成两个,由HRegionServer管理,管理哪些HRegion由HMaster分配。
1、预分区 2、rowkey 优化 3、减少 Column Family 数量
Spark
Spark 的运行模式有 Local(也称单节点模式),Standalone(集群模式),Spark on Yarn(运行在Yarn上)有 yarn-client 和 yarn-cluster 两种模式,主要区别在于:Driver 程序的运行节点。
coalesce 和 repartition / BroadCast join 广播 join / 控制 Spark reduce 缓存 调优 shuffle / 使用高性能算子 等等。
RDD任务切分中间分为:Application、Job、Stage和Task ,再详细讲述各自的联系。
map、flatmap、union、filter ----> 窄依赖 groupByKey,reduceByKey,sortByKey,join 各种Bykey都是shuffle阶段 -----> 宽依赖 reducebyKey会先在本地机器上进行局部聚合,然后在移动数据,进行全局聚合 ---> 性能更好
都是做 RDD 持久化的 cache:内存,不会截断血缘关系,使用计算过程中的数据缓存。checkpoint:磁盘,截断血缘关系,在 ck 之前必须没有任何任务提交才会生效,ck 过 程会额外提交一次任务。
memory_only、disk_only、memory_Anddisk_only 像cache() 默认 memory_only 什么的。
这种情况下去定位出问题的代码就比较容易了。我建议直接看 yarn-client 模式下本地log 的异常栈,或者是通过 YARN 查看 yarn-cluster 模式下的 log 中的异常栈。一般来说,通过异常栈信息就可以定位到你的代码中哪一行发生了内存溢出。然后在那行代码附近找找,一般也会有 shuffle 类算子,此时很可能就是这个算子导致了数据倾斜。但是大家要注意的是,不能单纯靠偶然的内存溢出就判定发生了数据倾斜。因为自己编 写的代码的 bug,以及偶然出现的数据异常,也可能会导致内存溢出。因此还是要按照上面所讲的方法,通过 Spark Web UI 查看报错的那个 stage 的各个 task 的运行时间以及分配的数据量,才能确定是否是由于数据倾斜才导致了这次内存溢出。
使用 Hive ETL 预处理数据 、 过滤少数导致倾斜的 key 、 提高 shuffle 操作的并行度 、两阶段聚合(局部聚合+全局聚合) 、 将 reduce join 转为 map join 、使用随机前缀和扩容 RDD 进行 join 等等,方法很多,大家可以再深入的了解。
1 加内存, 简单粗暴 2 将rdd的数据写入磁盘不要保存在内存之中 3 如果是collect操作导致的内存溢出, 可以增大 Driver的 memory 参数
累加器(accumulator)是 Spark 中提供的一种分布式的变量机制,其原理类似于 mapreduce,即分布式的改变,然后聚合这些改变。累加器的一个常见用途是在调试时对作业执行过程中的事件进行计数。而广播变量用来高效分发较大的对象。
通过 spark.streaming.kafka.maxRatePerPartition 参数来设置 Spark Streaming 从 kafka 分区每秒拉取的条数。
把 spark.streaming.backpressure.enabled 参数设置为 ture,开启背压机制后 Spark Streaming 会根据延迟动态去 kafka 消费数据,上限由 spark.streaming.kafka.maxRatePerPartition 参数控制,所以两个参数一般会一起使用。
基于 Receiver 的方式 基于 Direct 的方式 -----> 简化并行读取 高性能
数仓
结合业务,对数仓设计的过程做个概述,例如我的就是常见的四层的一个模型,ODS、ODW... 层 ,这其中我对业务数据做了哪些操作,都得了然于心吧。
数据质量管理系统,主键唯一、非空、数据波动。
写在最后
更多精彩推荐
☞华为海思超越高通,一季度国内占有率第一;苹果 iOS 13.5 优化 Face ID;Ruby 2.4 结束支持 | 极客头条
☞程序员内功修炼系列:10 张图解谈 Linux 物理内存和虚拟内存