mapReduce体系结构和各种算法
Mapreduce的工作机制
任务执行优化
推测式执行:jobtracker会将执行慢的任务kill掉,启动一个新的相同备份任务
在mapred-site.xml中设置map和reduce任务的开启和关闭
Mapred.map.tasks.speculative.execution
Mapred.reduce.tasks.speculative.execution
重用jvm,可以省去启的新jvm的消耗时间,在mapred-site.xml中配置
Mapred.job.reuse.jvm.num.tasks设置单个jvm运行的最大任务数(1,>1,-1)
忽略模式:
任务在读取失败2次后,会通知jobtracker重新启动该任务,在遇到坏数据时直接跳过,默认为关闭,可以用skipbadrecord方法打开
错误处理
A硬件故障
硬件故障:jobtracker或tasktracker
Jobtracker是单点,提高机器性能
Jobtracker通过心跳信号来检测tracktracker
Jobtracker会从任务节点列表中移除问题tasktracker
如果tasktracker正在执行map任务,jobtracker会要求其他节点重新执行
如果tasktracker正在执行reduce任务,jobtracker会用其他节点继续执行未完成任务
B任务失败
代码问题进程死掉
Jvm自动退出,会向tasktracker父进程发送信息,写入日志
Tasktracker监听程序会将问题进程标记为失败
标记任务失败后,任务计数器减1,通过心跳信号通知jobtracker
Jobtrack收到通知后,将任务放入调度队列,重新执行
如果一个任务失败4次,将不会再执行,作业失败
打开审计日志
在hadoop*/conf/log4j.propertites文件中,修改如下:
Log4j.logger.org.apache.hadoop.fs.FSNamesystem.audit=WARN改为INFO
调整log4j的日志级别
http://localhost:50070/logLevel
运维第三方工具
Ganglia
Chukwa
Openstack
作业跟踪器:jobTracker
处理用户提交的作业
决定有哪些文件参与处理,切割task并分配节点
监控task,重启失败的task
每个集群只有吟唯一一个jobTracker位于master节点
任务跟踪器:taskTracker
位于slave节点,与datanode结合
管理各节点上的task(由jobtracker分配)
每个节点只有一个taskTracker,但一个taskTracker可以启动多个jvm,用于执行map 或reduce任务
与jobTracker交互
性能调优
作业需要的reducer
输入的数据:大文件要优于小文件
减少网络传输:压缩map输出
优化每个节点的任务数:默认值为2
Mapred.tasktracker.map.tasks.maximum
Mapred.tasktracker.reduce.tasks.maximum
HadoopAPI开发步骤
示例代码如下:
/**
*Copyright(C)2015
*
*FileName:Test_1.java
*
*Author:<ahref="mailto:zhenhuayue@sina.com">Retacn</a>
*
*CreateTime:2015-10-5
*/
//PackageInformation
packagecn.yue.test;
importjava.io.IOException;
importorg.apache.hadoop.conf.Configuration;
importorg.apache.hadoop.conf.Configured;
importorg.apache.hadoop.fs.Path;
importorg.apache.hadoop.io.LongWritable;
importorg.apache.hadoop.io.NullWritable;
importorg.apache.hadoop.io.Text;
importorg.apache.hadoop.mapreduce.Job;
importorg.apache.hadoop.mapreduce.Mapper;
importorg.apache.hadoop.mapreduce.lib.input.FileInputFormat;
importorg.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
importorg.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
importorg.apache.hadoop.util.Tool;
importorg.apache.hadoop.util.ToolRunner;
/**
*分词
*
*@version
*
*@Description:
*
*@author<ahref="mailto:zhenhuayue@sina.com">Retacn</a>
*
*@since2015-10-5
*
*/
publicclassTest_1extendsConfiguredimplementsTool{
enumcounter{
LINESKIP,//出错的行
};
@Override
publicintrun(String[]args)throwsException{
Configurationconf=getConf();
//任务名
Jobjob=newJob(conf,"Test_1");
//指定class
job.setJarByClass(Test_1.class);
//输入路径
FileInputFormat.addInputPath(job,newPath(args[0]));
//输出路径
FileOutputFormat.setOutputPath(job,newPath(args[1]));
//指定mapper类
job.setMapperClass(MyMapper.class);
job.setOutputFormatClass(TextOutputFormat.class);
//指定输出key和value的格式
job.setOutputKeyClass(NullWritable.class);
job.setOutputValueClass(Text.class);
returnjob.isSuccessful()?0:1;
}
publicstaticclassMyMapperextendsMapper<LongWritable,Text,//输出的key和value的格式
NullWritable,Text>{//输出的key和value的格式
publicvoidmap(LongWritablekey,Textvalue,Contextcontext)throwsIOException,InterruptedException{
//读取源数据
Stringline=value.toString();
try{
//数据处理
String[]lineSplit=line.split("");
String month=lineSplit[0];
Stringtime=lineSplit[1];
Stringmac=lineSplit[6];
Textout=newText(month+""+time+""+mac);
//数据输出
context.write(NullWritable.get(),out);
}catch(Exceptione){
//出错令计数器加1
context.getCounter(counter.LINESKIP).increment(1);
return;
}
}
}
publicstaticvoidmain(String[]args)throwsException{
intres=ToolRunner.run(newConfiguration(),newTest_1(),args);
System.exit(res);
}
}
执行程序:
先配置运行环境runconfigurations在arguments中添加如下(指定输入目录和输出目录):
hdfs://localhost:9000/user/root/inhdfs://localhost:9000/user/root/out
在运行前查看hdfs中输出目录out不能存在
Run执行可以在out目录中看到输出结果
示例程序
倒排序,代码如下:
/**
*Copyright(C)2015
*
*FileName:Test_2.java
*
*Author:<ahref="mailto:zhenhuayue@sina.com">Retacn</a>
*
*CreateTime:2015-10-6
*/
//PackageInformation
packagecn.yue.test;
importjava.io.IOException;
importorg.apache.hadoop.conf.Configuration;
importorg.apache.hadoop.conf.Configured;
importorg.apache.hadoop.fs.Path;
importorg.apache.hadoop.io.LongWritable;
importorg.apache.hadoop.io.NullWritable;
importorg.apache.hadoop.io.Text;
importorg.apache.hadoop.mapreduce.Job;
importorg.apache.hadoop.mapreduce.Mapper;
importorg.apache.hadoop.mapreduce.Reducer;
importorg.apache.hadoop.mapreduce.lib.input.FileInputFormat;
importorg.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
importorg.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
importorg.apache.hadoop.util.Tool;
importorg.apache.hadoop.util.ToolRunner;
/**
*倒序
*
*@version
*
*@Description:
*
*@author<ahref="mailto:zhenhuayue@sina.com">Retacn</a>
*
*@since2015-10-6
*
*/
publicclassTest_2extendsConfiguredimplementsTool{
enumCounter{
LINESKIP,//出错的行
};
@Override
publicintrun(String[]args)throwsException{
Configurationconf=getConf();
//任务名
Jobjob=newJob(conf,"Test_2");
//指定class
job.setJarByClass(Test_2.class);
//输入路径
FileInputFormat.addInputPath(job,newPath(args[0]));
//输出路径
FileOutputFormat.setOutputPath(job,newPath(args[1]));
//指定mapper类
job.setMapperClass(MyMapper.class);
//指定reducer类
job.setReducerClass(MyReducer.class);
job.setOutputFormatClass(TextOutputFormat.class);
//指定输出key和value的格式
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
//TODO为何添加?
job.waitForCompletion(true);
returnjob.isSuccessful()?0:1;
}
publicstaticclassMyMapperextendsMapper<LongWritable,Text,Text,Text>{
publicvoidmap(LongWritablekey,Textvalue,Contextcontext)throwsIOException,InterruptedException{
Stringline=value.toString();
try{
String[]lineSplit=line.split("");
Stringcaller=lineSplit[0];
Stringreciver=lineSplit[1];
context.write(newText(reciver),newText(caller));
}catch(Exceptione){
context.getCounter(Counter.LINESKIP).increment(1);
return;
}
}
}
publicstaticclassMyReducerextendsReducer<Text,Text,Text,Text>{
publicvoidreduce(Textkey,Iterable<Text>values,Contextcontext)throwsIOException,InterruptedException{
StringvalueString;
Stringout="";
for(Textvalue:values){
valueString=value.toString();
out+=valueString+"|";
}
context.write(key,newText(out));
}
}
publicstaticvoidmain(String[]args)throwsException{
intres=ToolRunner.run(newConfiguration(),newTest_2(),args);
System.exit(res);
}
}
运行方法同上,可以指定输入文件
查看输出结果:
10000 13953312345|13765431234|18953354321|
110 13153365432|15953345678|
13853398765 15153354321|13906431223|
程序的打包,同java程序
Pig
Hadoop客户端
使类似于sql的面向数据流的语言pigLatin
PigLatin可以完成排序,过滤,求和,聚组,关联等操作,可以支持自定义函数
Pig自动把piglatin映射为map-reduce作业上传到集群运行,减少java代码
三种运行方式:gruntshell脚本方式嵌入式
4Zookeeper操作hadoop集群搭建,sqoop
Googlechubby的开源实现
用于协调分布式系统上的各种服务,例如消息是否到达,单点失效,负载均衡
应用场景:hbase实现nameNode的自动切换
工作原理:领导者,跟随者以及选举过程
Sqoop
用于在hadoop和关型数据库这间的数据交换
通过jdbc接口连入关系型数据库
Avro
数据序列化工具
用于支持大批量数据交换的应用
动态语言友好
Thrift接口
Chukwa
架构在hadoop之上的数据采集和分析框架
主要进行日志采集和分析
通过安装在收集节点的”代理”采集原始日志数据
代理将数据发给收集器
收集器定时将数据写入hadoop集群
指定定时启动的map-reduce作业对数据进行加工处理和分析
Hadoop基础管理中心(hicc)最终展示数据
Cassandra
noSQL,分布式的key-value型数据
与hbase类似
只有顺序写,没有随机写