1.你处理过的最大的数据量?你是如何处理他们的?处理的结果。
1000万条数据(10G);为了加快解析速度,使用redis作为缓存,MR运行只与redis交互,解析完成后统一在hbase中持久化存储.
2.在处理大数据过程中,如何保证得到期望值?
对数据进行清洗,过滤和排序以达到期望值
3.如何让一个网络爬虫速度更快、抽取更好的信息以及更好总结数据从而得到一干净的数据库?
多个账号,多窗口操作;定向抽取数据需求数据
4.点击流数据应该是实时处理?为什么?哪部分应该实时处理?
点击流数据是用户浏览网站持续轨迹,是持续的行为(数据具有时效性?);
访问,浏览,点击行为应该实时处理
购物车,足迹,评论,收藏,订单数据采集到kafka后进行实时处理.
5.你最喜欢的编程语言是什么?为什么?
我认为编程语言是程序员得基本功,不论是java,scala还是sql,只有熟练掌握才能够写出简洁高效的代码.
6.如何把非结构化的数据转换成结构化的数据?这是否真的有必要做这样的转换?把数据存成平面文本文件是否比存成关系数据库更好?
对源数据设置统一的切割符,清洗冗余数据,无效数据;
源数据没有结构化,不会直接应用使用,不利于分析,容易导致数据倾斜,转换后的数据便于后期的使用和开发;
文本文件不利于管理和维护,并且文件会占用存储空间
7.如何判别mapreduce过程有好的负载均衡?什么是负载均衡?
当有大文件或大量数据的时候,就会体现出mapreduce的负载均衡,其中mapreduce核心shuffle过程实现的负载均衡;
扩展网络设备和服务器的带宽,增加吞吐量,加强网络数据处理能力,增加网络的灵活性和可用性.(这里可以通过MR的shuffle,阐述spark的shuffle,做一个对比,然后怎样调优)
8.Spark和Hive的区别,以及Spark和Hive的数据倾斜调优问题?
区别:
spark拥有mapreduce所具备的优点,但不同于mapreduce的是job中间输出结果保存在内存中,从而不再读写hdfs.
hive是基于Hadoop的工具,提供sql语句运行mapreduce,核心为mapreduce处理数据,需要进行频繁的io操作.
hive数据倾斜:
参数调节:
进行负载均衡
sql语句调节:
选用join key分布最均匀的表作为驱动表.
使用map join 让小的维度表先进内存.在map端完成reduce
把空值加上随机数,把倾斜的数据分到不同的reduce上,null值不影响最终的处理结果
countdistinct 大量相同特殊值:将值为空的单独处理,相同的不用处理直接过率,在最后结果中加1;
还有其它计算,需要进行group by,可以先将值为空的记录单独处理,在和其它计算结果进行union]
spark数据倾斜:
数据倾斜是由于少数task执行时间过长导致的,shuffle过程出现此问题
distinct,groupByKey,reduceByKey,aggregateByKey,join,cogroup,repartition
数据倾斜原因:
key本身分布不均匀
key的设置不合理,(我之前公司的key是怎么设计的)
如果是其它情况具体情况具体分析
如果是业务导致的数据正常分布
spark下:
spark时的并发度不够
计算方式有误
解决:key分布问题则清除无效的key
如果是有效数据正常分布
隔离执行,将异常的key过滤出来单独处理,最后与正常数据的处理结果进行union操作
将task过多的key添加随机值,进行操作,去掉随机值,在进行操作
shuffle问题,sparksql和dataframe可以设置增加shuffle并行度;使用map join 代替reduce join
9.Hive和Hbase的区别?
共同点:hbase与hive都是架构在Hadoop上,都是用hadoop作为底层存储.
区别:
hive是建立在hadoop上为了减少mapreduce job编写工作的批处理系统,HBase是支持hadoop的实时操作的缺陷;
当操作RMDB数据库,如果是全表扫描,就用Hive+hadoop,如果是索引访问采用Hbase+hadoop;
hivequery mapreduce 从5分钟到数小时,hbase是非常高效的,比hive快;
Hive本身不存储数据和计算数据,完全依赖HDFS和mapreduce,借用mapreduce完成命令执行,hive表纯逻辑
hbase是物理表,列存储,非逻辑表,提供大内存hash表,搜索引擎通过它来存储索引,方便查询操作.
hdfs作为底层存储,是存放文件的系统,而Hbase负责组织文件.
hive需要用到hdfs存储文件,需要用到Mapreduce计算框架.
10.MapReduce的思想,以及MapReduce调优问题?
mapReduce是一个分布式运算程序的编程框架,分而治之的思想,(阐述mapreduce的整个流程),
配置mapred-site.xml参数
默认开启的reduce数量,多台机器分担一台机器的压力,增加数量
环形缓冲区所占内存大小默认100M,增加到200M
环形缓冲区的阀值
ReduceTask中合并小文件时,增加一次合并的文件数据
map输出是否进行压缩,如果压缩就会多耗cpu,但是减少传输时间,如果不压缩,就需要较多的传输带宽。
设置http传输的的并行数
以下的主要思想就是增加内存:
Map阶段,增加map端的内存分配
增加Map端启用JVM所占用的内存
增加reduce阶段,reduce端的内存分配
增加reduce端启用JVM所占用的内存
shuffle调优:
调整缓冲区的大小,将缓冲区调大.
阈值降低到60%,80%会刷磁盘浪费io,达到减少io的效果
11.谈谈数据倾斜,它如何发生的,并给出优化方案!
首先谈一下什么是数据倾斜? 答:map /reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长。现象是: 进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成;查看未完成的子任务,可以看到本地读写数据量积累非常大,通常超过10GB可以认定为发生数据倾斜。
如何发生的?数据的倾斜主要是两个的数据相差的数量不在一个级别上 ,这是因为某一个key的条数比其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完。
优化方案 :
方式一 :reduce 本身的计算需要以合适的内存作为支持,在硬件环境容许的情况下,增加reduce 的JVM内存大小显然有改善数据倾斜的可能,这种方式尤其适合数据分布第一种情况,单个值有大量记录, 这种值的所有纪录已经超过了分配给reduce 的内存,无论你怎么样分区这种情况都不会改变. 当然这种情况的限制也非常明显, 1.内存的限制存在,2.可能会对集群其他任务的运行产生不稳定的影响。
方式二 : 这个对于数据分布第二种情况有效,情况(一值较多,单个唯一值的记录数不会超过分配给reduce 的内存). 如果发生了偶尔的数据倾斜情况,增加reduce 个数可以缓解偶然情况下的某些reduce 不小心分配了多个较多记录数的情况. 但是对于第一种数据分布无效。
方式三: 一种情况是某个领域知识告诉你数据分布的显著类型,比如<<hadoop权威指南>> 里面的温度问题,一个固定的组合(观测站点的位置和温度) 的分布是固定的,对于特定的查询如果前面两种方式都没用,实现自己的partitioner 也许是一个好的方式。
总结 : 数据倾斜没有一劳永逸的方式可以解决,了解你的数据集的分布情况,然后了解你所使用计算框架的运行机制和瓶颈,针对特定的情况做特定的优化,做多种尝试,观察是否有效。
12.datanode 首次加入 cluster 的时候,如果 log 报告不兼容文件版本,那需要namenode 执行格式化操作,这样处理的原因是?
(可以当成工作中遇到的问题!) 这样处理是不合理的,因为那么 namenode 格式化操作,是对文件系统进行格式化,namenode 格式化时清空 dfs/name 下空两个目录下的所有文件,之后,会在目录 dfs.name.dir 下创建文件。文本不兼容,有可能时 namenode 与 datanode 的 数据里的 namespaceID、clusterID 不一致,找到两个 ID 位置,修改为一样即可解决。
13.简述HDFS数据存储机制?
HDFS是解决海量数据存储问题的存储系统。具有高可靠,读写效率高等特点。通过将大文件拆分成一个一个block块,Hadoop2.x默认是128M,分布式的存储到各个DataNode节点中并且备份,通过横向扩展解决了纵向扩展的问题,大大提升了读写的效率和降低了成本。同时,通过设置NameNode主节点来记录每个block的元数据信息,包括块名,所在DataNode节点,备份所在位置,大小等等信息,实现文件的高可靠存储和高效率读取。而且在Hadoop2.0以上版本,通过HA解决了NameNode的单点故障问题,使得HDFS更为可靠。
14.如何实现小文件的合并?
先将这些小文件保存到本地的一个路径中同一个文件中,通过shell脚本,可以设置这个新文件达到多大再上传,一般设置为128M,上传到HDFS中,这样就实现了小文件上传之前的合并。还有,一般当天的日志和数据都存在一个HDFS路径中,如果没有达到上传大小,可以设置每天凌晨对前一天的本地文件路径的扫描,如果发现有文件,不管多大,都上传到前一天的HDFS文件目录下。
15.Hadoop的Shuffer过程
map ----> partition(分区默认,可修改) ----> sort(排序默认,可修改) -----> combiner(map阶段排序,可选) -----> spill (溢写,默认不可改) -----> meger(合并文件,默认,不可改) -----> compress(压缩,可选) -----> Copy 阶段----->Merge 阶段----->Sort 阶段。这是整个MapReduce阶段, 而Map 产生输出开始到Reduce取得数据作为输入之前的过程称shuffle阶段
1 . Collect阶段 : 将MapTask的结果输出到默认大小为100M的环形缓冲区 . 保存的是key/value ,Partition分区信息等。
2 . Spill阶段 : 当内存中的数据量达到一定的阈值的时候,就会将数据写入到本地磁盘 , 在将数据写入到磁盘之前需要对数据进行一次排序的操作。如果配置了combiner,还会将相同分区号和key的数据进行排序。
3 . Merge阶段 : 把所有的溢出的临时文件进行一次合并操作 , 以确保一个MapTask最终只产生一个中间数据文件。
4 . Copy阶段 : ReduceTask启动Fetcher线程到已经完成MapTask的节点上复制一份属于自己的数据 , 这些数据默认会保存到内存的缓冲区中 , 当内存的缓冲区达到一定的阈值的时候,就会将数据写到磁盘之上
5 . 在reduceTask远程复制数据的同时 , 会在后台开启两个线程对内存到本地的数据文件进行合并操作
6 . Sort阶段 : 在对数据进行合并的同时 , 会进行排序操作 , 由于MapTask阶段已经对数据进行了局部的排序 , ReduceTask只需要保证Copy的数据最终整体有效性即可。
Shuffer中的缓冲区大小会影响到MapReduce程序的执行效率 , 原则上说 , 缓冲区越大 , 磁盘IO的次数越少,执行速度越快.
16.两个文件合并的问题
给定a、b两个文件,各存放50亿个url,每个url各占用64字节,内存限制是4G,如何找出a、b文件共同的url?主要的思想是把文件分开进行计算,在对每个文件进行对比,得出相同的URL,因为以上说是含有相同的URL所以不用考虑数据倾斜的问题。详细的解题思路为:可以估计每个文件的大小为5G*64=300G,远大于4G。所以不可能将其完全加载到内存中处理。考虑采取分而治之的方法。
遍历文件a,对每个url求取hash(url)%1000,然后根据所得值将url分别存储到1000个小文件(设为a0,a1,...a999)当中。这样每个小文件的大小约为300M。遍历文件b,采取和a相同的方法将url分别存储到1000个小文件(b0,b1....b999)中。这样处理后,所有可能相同的url都在对应的小文件(a0 vs b0, a1 vs b1....a999 vsb999)当中,不对应的小文件(比如a0 vs b99)不可能有相同的url。然后我们只要求出1000对小文件中相同的url即可。 比如对于a0 vs b0,我们可以遍历a0,将其中的url存储到hash_map当中。然后遍历b0,如果url在hash_map中,则说明此url在a和b中同时存在,保存到文件中即可。
如果分成的小文件不均匀,导致有些小文件太大(比如大于2G),可以考虑将这些太大的小文件再按类似的方法分成小小文件即可。
17.当场java或者scala手写word count。(会一种)
18.YARN的调度策略
FIFO: 先进先出. 小任务会被大任务阻塞
· Capacity: 容量调度器(默认).
按照你的队列的形式!给不同的队列划分不同的百分比,当然如果一个队列空闲!那么另外一个队列就会不断的“吞噬”剩下的资源直至达到(自己设定的最大“吞噬”量的百分比),如果这个时候被吞噬的资源又开始忙的话!那么就会释放资源!最终达到自己设定的那个动态的平衡点!
例子 :
Root
队列一 : prod 40% 剩余25%
队列二 :env 60% 剩余75%
队列二的子队列 : mapreduce 50%
队列二的子队列 : spark 50%
动态平衡点 : 队列一:40% 队列二占60% 当队列一空闲 或者队列二空闲的时候 , 另外一个不空闲的队列最多吞噬到75% 。
而队列二的子队列 的50%+50% 等于队列二的60%
FAIR: 公平调度器
当第一个任务提交的时候,假如只有这一个任务,就会把集群所有资源给这一个任务。第二个任务提交的时候,RM会分配给一半的资源给第二个任务。但是第二个任务从提交到执行会有一定的延迟,需要等待第一个任务释放了container容器。但有个好处就是,能够充分的让每一个任务利用集群的资源
·默认调度器是Capacity
·1、容量调度器
·Vi yarn-site.xml中配置
· <property>
· <name>yarn.resourcemanager.scheduler.class</name>
· <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
· </property>
· 然后在/etc/hadoop/capacity-scheduler.xml中配置容量调度器的参数
· 1、
· Name:yarn.scheduler.capacity.maximum-applications
· Value:10000
· 集群或者队列中(all)同时处于等待和运行状态的应用程序数目上限,这是一个强限制,一旦集群中应用程序数目超过该上限,后续提交的应用程序将被拒绝,默认值为10000
· 2、
· Name:yarn.scheduler.capacity.maximum-am-resource-percent
· Value:0.1
· 集群中可用于运行application master的资源比例上限,这通常用于限制并发运行的应用程序数目
· 3、
· Name:yarn.scheduler.capacity.resource-calculator
· Value:org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator
· 资源调度器resourceManager在做计算的时候,会考虑资源的调度。默认的方式只考虑到内存。如果使用DominantResourceCalculator则进行多维度比较:CPU,内存等
· 4、
· Name:yarn.scheduler.capacity.root.queues
· Value:default或者Q1,Q2,Q3(以,分割)
· 用来指定队列的。容量调度器预先给root开启了一个队列,如果是默认的话,就表示只有一个队列。可以指定当前root下有那些队列的,不指定就一个
· 5、
· Name:yarn.scheduler.capacity.root.default.capacity
· Value:100
· 指定默认队列的容量
· 如果要制定其他队列容量的话只需要:
· Name:yarn.scheduler.capacity.root.Q1.capacity
· Value:100
· 6、
· Name:yarn.scheduler.capacity.root.default.user-limit-factor
· Value:1
· 每个队列可使用的资源的限制
· 7、
· Name:yarn.scheduler.capacity.root.default.maximum-capacity
· Value:100
· Default队列可使用的资源上限.
19.MR相关的调优(结合自己的项目场景,记住三四个)
主要使用的硬件 :CPU+memory 如果当前进程是进行存储的 , 对CPU和内存要求并不是很高。如果当前进程是进行计算的,那么对CPU和memory的要求都是很高的 硬件的主要配置有:memory 当CPU不够的话:程序执行运算会慢一点,当内存不够的:会导致heap溢出,GC。因为在内存不够的时候,Yarn里面有一个动态的线程就会检测到,然后就给你杀死了
20.hive是怎样保存元数据的
保存元数据的方式有:内存数据库Derby,特点 : 保存数据小,不稳定。本地MySQL数据库, 特点 :储存方式可以自己设定,持久化好,一般企业开发都用mysql做支撑。远程mysql数据库,但是本地的mysql数据用的比较多,因为本地读写速度都比较快。内置数据库不使用!
21.什么是Hive的内部表和外部表?
未被external修饰的是内部表,被external修饰的是外部表。内部表数据由Hive自身管理,外部表数据由HDFS管理。内部表数据存储的位置是warehouse的路径,外部表数据的存储文职由自己指定。删除内部表会直接删除元数据以及存储的数据,删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除。对内部表的修改会将修改直接同步给元数据,对外部表的表结构和分区进行修改的话,则需要修复:MSCK REPAIR TABLE 表名
22.Hive 的 sort by 和 order by 的区别
order by 会对输入做全局排序,因此只有一个reducer(多个reducer无法保证全局有序)只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。
sort by不是全局排序,其在数据进入reducer前完成排序.
因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1, 则sortby只保证每个reducer的输出有序,不保证全局有序。
网友评论