面试题(3)

https://blog.csdn.net/wdr2003/article/details/79597527

2.13. 简述hadoop的调度器

FIFO schedular:默认,先进先出的原则

Capacity schedular:计算能力调度器,选择占用最小、优先级高的先执行,依此类推

Fair schedular:公平调度,所有的job具有相同的资源。

2.14. 列出你开发mapreduce的语言

java

2.15. 书写程序

wordcount

mapper:

String vStr = value.toString().split(",")[3];

ctx.write(new Text(vStr),new IntWriteble(1));

reducer :

for(IntWriteble v : value){

ctx.write(key,v);

}

2.16. 不同语言的优缺点

你认为用Java,Streaming,pipe方式开发map/reduce,各有哪些优缺点。

hadoop是java写的,java的集成效果最好,并且平台环境统一。

2.17. hive有哪些保存元数据的方式,各有什么特点。

 内存数据库derby,安装小,但是数据存在内存,不稳定

 mysql数据库,数据存储模式可以自己设置,持久化好,查看方便。

2.18. combiner和partition的作用

combiner是reduce的实现,在map端运行计算任务,减少map端的输出数据。作用就是优化。但是combiner的使用场景是mapreduce的map

输出结果和reduce输入输出一样。

partition的默认实现是hashpartition,是map端将数据按照reduce个数取余,进行分区,不同的reduce来copy自己的数据。partition

的作用是将数据分到不同的reduce进行计算,加快计算效果。

2.19. hive内部表和外部表的区别

内部表:加载数据到hive所在的hdfs目录,删除时,元数据和数据文件都删除

外部表:不加载数据到hive所在的hdfs目录,删除时,只删除表结构。

2.20. hbase的rowkey怎么创建好?列族怎么创建比较好?

hbase存储时,数据按照Row key的字典序(byte order)排序存储。设计key时,要充分排序存储这个特性,将经常一起读取的行存储放到一起。

(位置相关性)

一个列族在数据底层是一个文件,所以将经常一起查询的列放到一个列族中,列族尽量少,减少文件的寻址时间。

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

数据倾斜:map /reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,

这是因为某一个key的条数比其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量比其他节点就大很多,

从而导致某几个节点迟迟运行不完,此称之为数据倾斜。

用hadoop程序进行数据关联时,常碰到数据倾斜的情况,这里提供一种解决方法。

自己实现partition类,用key和value相加取hash值:

方式1:

源代码:

public int getPartition(K key, V value,int numReduceTasks) {

    return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;

}

修改后

public int getPartition(K key, V value,int numReduceTasks) {

    return (((key).hashCode()+value.hashCode()) & Integer.MAX_VALUE) % numReduceTasks;

}

方式2:

public class HashPartitioner<K, V> extends Partitioner<K, V> {

    private int aa= 0;

    /** Use {@link Object#hashCode()} to partition. */

    public int getPartition(K key, V value,int numReduceTasks) {

    return (key.hashCode()+(aa++) & Integer.MAX_VALUE) % numReduceTasks;

}

方式3:

重新设计key

2.22. hadoop框架中怎么来优化

 从应用程序角度进行优化。由于mapreduce是迭代逐行解析数据文件的,怎样在迭代的情况下,编写高效率的应用程序,是一种优化思路。

 对Hadoop参数进行调优。当前hadoop系统有190多个配置参数,怎样调整这些参数,使hadoop作业运行尽可能的快,也是一种优化思路。

 从系统实现角度进行优化。这种优化难度是最大的,它是从hadoop实现机制角度,发现当前Hadoop设计和实现上的缺点,然后进行源码级

地修改。该方法虽难度大,但往往效果明显。

 linux内核参数调整

2.22.1. 从应用程序角度进行优化

(1) 避免不必要的reduce任务

如果mapreduce程序中reduce是不必要的,那么我们可以在map中处理数据, Reducer设置为0。这样避免了多余的reduce任务。

(2) 为job添加一个Combiner

为job添加一个combiner可以大大减少shuffle阶段从map task拷贝给远程reduce task的数据量。一般而言,combiner与reducer相同。

(3) 根据处理数据特征使用最适合和简洁的Writable类型

Text对象使用起来很方便,但它在由数值转换到文本或是由UTF8字符串转换到文本时都是低效的,且会消耗大量的CPU时间。当处理那些非

文本的数据时,可以使用二进制的Writable类型,如IntWritable, FloatWritable等。二进制writable好处:避免文件转换的消耗;

使map task中间结果占用更少的空间。

(4) 重用Writable类型

很多MapReduce用户常犯的一个错误是,在一个map/reduce方法中为每个输出都创建Writable对象。例如,你的Wordcout mapper方法可能

这样写:

public void map(...) {

  …

    for (String word : words) {

        output.collect(new Text(word), new IntWritable(1));

    }

}

这样会导致程序分配出成千上万个短周期的对象。Java垃圾收集器就要为此做很多的工作。更有效的写法是:

class MyMapper … {

    Text wordText = new Text();

    IntWritable one = new IntWritable(1);

    public void map(...) {

        for (String word: words) {

            wordText.set(word);

            output.collect(wordText, one);

        }

    }

}

(5) 使用StringBuffer而不是String

当需要对字符串进行操作时,使用StringBuffer而不是String,String是read-only的,如果对它进行修改,会产生临时对象,

而StringBuffer是可修改的,不会产生临时对象。

2.22.2.  对参数进行调优

查看linux的服务,可以关闭不必要的服务

ntsysv

停止打印服务

#/etc/init.d/cups stop

#chkconfig cups off

关闭ipv6

#vim /etc/modprobe.conf

添加内容

alias net-pf-10 off

alias ipv6 off

调整文件最大打开数

查看: ulimit -a    结果:open files (-n) 1024

临时修改: ulimit -n 4096

持久修改:

vi /etc/security/limits.conf在文件最后加上:

* soft nofile 65535

* hard nofile 65535

* soft nproc 65535

* hard nproc 65535

修改linux内核参数

vi /etc/sysctl.conf

添加

net.core.somaxconn = 32768

#web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128,而nginx定义的NGX_LISTEN_BACKLOG默认为511,

所以有必要调整这个值。

调整swap分区什么时候使用:

查看:cat /proc/sys/vm/swappiness

设置:vi /etc/sysctl.conf 

            在这个文档的最后加上这样一行: vm.swappiness=10

            表示物理内存使用到90%(100-10=90)的时候才使用swap交换区

关闭noatime

vi /etc/fstab

/dev/sda2    /data     ext3  noatime,nodiratime  0 0

设置readahead buffer

blockdev --setra READAHEAD 512 /dev/sda

以下是修改mapred-site.xml文件

修改最大槽位数

槽位数是在各个tasktracker上的mapred-site.xml上设置的,默认都是2

<property>

    <name>mapred.tasktracker.map.tasks.maximum</name>  

    <!--maptask的最大数-->

    <value>2</value>  

</property>                  

<property>  

    <name>mapred.tasktracker.reduce.tasks.maximum</name>     

    <!--reducetask的最大数-->

    <value>2</value>  

</property>

调整心跳间隔

集群规模小于300时,心跳间隔为300毫秒

mapreduce.jobtracker.heartbeat.interval.min  心跳时间

mapred.heartbeats.in.second  集群每增加多少节点,时间增加下面的值

mapreduce.jobtracker.heartbeat.scaling.factor 集群每增加上面的个数,心跳增多少

启动带外心跳

mapreduce.tasktracker.outofband.heartbeat  默认是false

配置多块磁盘

mapreduce.local.dir

配置RPC hander数目

mapred.job.tracker.handler.count 默认是10,可以改成50,根据机器的能力

配置HTTP线程数目

tasktracker.http.threads  默认是40,可以改成100 根据机器的能力

选择合适的压缩方式

以snappy为例:

<property>  

    <name>mapred.compress.map.output</name>

    <value>true</value>  

</property>                  

<property>  

    <name>mapred.map.output.compression.codec</name>

    <value>org.apache.hadoop.io.compress.SnappyCodec</value>  

</property>

启用推测执行机制

推测执行(Speculative Execution)是指在分布式集群环境下,因为程序BUG,负载不均衡或者资源分布不均等原因,造成同一个job的多个

task运行速度不一致,有的task运行速度明显慢于其他task(比如:一个job的某个task进度只有10%,而其他所有task已经运行完毕),

则这些task拖慢了作业的整体执行进度,为了避免这种情况发生,Hadoop会为该task启动备份任务,让该speculative task与原始task同时

处理一份数据,哪个先运行完,则将谁的结果作为最终结果。

推测执行优化机制采用了典型的以空间换时间的优化策略,它同时启动多个相同task(备份任务)处理相同的数据块,哪个完成的早,则采用哪个task的结果,这样可防止拖后腿Task任务出现,进而提高作业计算速度,但是,这样却会占用更多的资源,在集群资源紧缺的情况下,设计合理的推测执行机制可在多用少量资源情况下,减少大作业的计算时间。

mapred.map.tasks.speculative.execution  默认是true

mapred.rduce.tasks.speculative.execution  默认是true

设置是失败容忍度

mapred.max.map.failures.percent   作业允许失败的map最大比例  默认值0,即0%

mapred.max.reduce.failures.percent  作业允许失败的reduce最大比例  默认值0,即0%

mapred.map.max.attemps  失败后最多重新尝试的次数 默认是4

mapred.reduce.max.attemps  失败后最多重新尝试的次数 默认是4

启动jvm重用功能

mapred.job.reuse.jvm.num.tasks  默认值1,表示只能启动一个task,若为-1,表示可以最多运行数不限制

设置任务超时时间

mapred.task.timeout  默认值600000毫秒,也就是10分钟。

合理的控制reduce的启动时间

mapred.reduce.slowstart.completed.maps  默认值0.05  表示map任务完成5%时,开始启动reduce任务

跳过坏记录

当任务失败次数达到该值时,才会进入skip mode,即启用跳过坏记录数功能,也就是先试几次,不行就跳过

mapred.skip.attempts.to.start.skipping 默认值 2

map最多允许跳过的记录数

mapred.skip.map.max.skip.records 默认值0,为不启用

reduce最多允许跳过的记录数

mapred.skip.reduce.max.skip.records 默认值0,为不启用

换记录存放的目录

mapred.skip.out.dir  默认值${mapred.output.dir}/_logs/

猜你喜欢

转载自blog.csdn.net/qq_39142369/article/details/88893666