高可用Hadoop平台-启航
1.概述
在上篇博客中,我们搭建了《配置高可用Hadoop平台》,接下来我们就可以驾着Hadoop这艘巨轮在大数据的海洋中遨游了。工欲善其事,必先利其器。是的,没错;我们开发需要有开发工具(IDE);本篇文章,我打算讲解如何搭建和使用开发环境,以及编写和讲解WordCount这个例子,给即将在Hadoop的海洋驰骋的童鞋入个门。上次,我在《网站日志统计案例分析与实现》中说会将源码放到Github,后来,我考虑了下,决定将《高可用的Hadoop平台》做一个系列,后面基于这个平台,我会单独写一篇来赘述具体的实现过程,和在实现过程中遇到的一些问题,以及解决这些问题的方案。下面我们开始今天的启航。
2.启航
IDE:JBoss Developer Studio 8.0.0.GA (Eclipse的升级版,Redhat公司出的)
JDK:1.7(或1.8)
Hadoop2x-eclipse-plugin:这个插件,本地单元测试或自己做学术研究比较好用
插件下载地址:https://github.com/smartdengjie/hadoop2x-eclipse-plugin
由于JBoss Developer Studio 8基本适合于Retina屏,所以,我们这里直接使用JBoss Developer Studio 8,JBoss Developer Studio 7对Retina屏的支持不是很完美,这里就不赘述了。
附上一张IDE的截图:

2.1安装插件
下面我们开始安装插件,首先展示首次打开的界面,如下图所示:

然后,我们到上面给的Github的地址,clone整个工程,里面有编译好的jar和源码,可自行选择(使用已存在的和自己编译对应的版本),这里我直接使用编译好的版本。我们将jar放到IDE的plugins目录下,如下图所示:

接着,我们重启IDE,界面出现如下图所示的,即表示插件添加成功,若没有,查看IDE的启动日志,根据异常日志定位出原因。


2.2设置Hadoop插件
配置信息如下所示(已在图中说明):


添加本地的hadoop源码目录:

到这里,IDE和插件的搭建就完成了,下面我们进入一段简单的开发,hadoop的源码中提供了许多example让我学习,这里我以WordCount为例子来说明:
3.WordCount
首先我们看下hadoop的源码文件目录,如下图所示:


3.1源码解读
package cn.hdfs.mr.example; import java.io.IOException;
import java.util.Random;
import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import cn.hdfs.utils.ConfigUtils; /**
*
* @author dengjie
* @date 2015年03月13日
* @description Wordcount的例子是一个比较经典的mapreduce例子,可以叫做Hadoop版的hello world。
* 它将文件中的单词分割取出,然后shuffle,sort(map过程),接着进入到汇总统计
* (reduce过程),最后写道hdfs中。基本流程就是这样。
*/
public class WordCount { private static Logger log = LoggerFactory.getLogger(WordCount.class); public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1);
private Text word = new Text(); /*
* 源文件:a b b
*
* map之后:
*
* a 1
*
* b 1
*
* b 1
*/
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());// 整行读取
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());// 按空格分割单词
context.write(word, one);// 每次统计出来的单词+1
}
}
} /*
* reduce之前:
*
* a 1
*
* b 1
*
* b 1
*
* reduce之后:
*
* a 1
*
* b 2
*/
public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable(); public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
} @SuppressWarnings("deprecation")
public static void main(String[] args) throws Exception {
Configuration conf1 = new Configuration();
Configuration conf2 = new Configuration();
long random1 = new Random().nextLong();// 重定下输出目录1
long random2 = new Random().nextLong();// 重定下输出目录2
log.info("random1 -> " + random1 + ",random2 -> " + random2);
Job job1 = new Job(conf1, "word count1");
job1.setJarByClass(WordCount.class);
job1.setMapperClass(TokenizerMapper.class);// 指定Map计算的类
job1.setCombinerClass(IntSumReducer.class);// 合并的类
job1.setReducerClass(IntSumReducer.class);// Reduce的类
job1.setOutputKeyClass(Text.class);// 输出Key类型
job1.setOutputValueClass(IntWritable.class);// 输出值类型 Job job2 = new Job(conf2, "word count2");
job2.setJarByClass(WordCount.class);
job2.setMapperClass(TokenizerMapper.class);
job2.setCombinerClass(IntSumReducer.class);
job2.setReducerClass(IntSumReducer.class);
job2.setOutputKeyClass(Text.class);
job2.setOutputValueClass(IntWritable.class);
// FileInputFormat.addInputPath(job, new
// Path(String.format(ConfigUtils.HDFS.WORDCOUNT_IN, "test.txt")));
// 指定输入路径
FileInputFormat.addInputPath(job1, new Path(String.format(ConfigUtils.HDFS.WORDCOUNT_IN, "word")));
// 指定输出路径
FileOutputFormat.setOutputPath(job1, new Path(String.format(ConfigUtils.HDFS.WORDCOUNT_OUT, random1)));
FileInputFormat.addInputPath(job2, new Path(String.format(ConfigUtils.HDFS.WORDCOUNT_IN, "word")));
FileOutputFormat.setOutputPath(job2, new Path(String.format(ConfigUtils.HDFS.WORDCOUNT_OUT, random2))); boolean flag1 = job1.waitForCompletion(true);// 执行完MR任务后退出应用
boolean flag2 = job1.waitForCompletion(true);
if (flag1 && flag2) {
System.exit(0);
} else {
System.exit(1);
} }
}
4.总结
这篇文章就和大家分享到这里,如果在研究的过程有什么问题,可以加群讨论或发送邮件给我,我会尽我所能为您解答,与君共勉!
高可用Hadoop平台-启航的更多相关文章
- 高可用Hadoop平台-探索
1.概述 上篇<高可用Hadoop平台-启航>博客已经让我们初步了解了Hadoop平台:接下来,我们对Hadoop做进一步的探索,一步一步的揭开Hadoop的神秘面纱.下面,我们开始赘述今 ...
- 高可用Hadoop平台-Oozie工作流之Hadoop调度
1.概述 在<高可用Hadoop平台-Oozie工作流>一篇中,给大家分享了如何去单一的集成Oozie这样一个插件.今天为大家介绍如何去使用Oozie创建相关工作流运行与Hadoop上,已 ...
- 高可用Hadoop平台-Hue In Hadoop
1.概述 前面一篇博客<高可用Hadoop平台-Ganglia安装部署>,为大家介绍了Ganglia在Hadoop中的集成,今天为大家介绍另一款工具——Hue,该工具功能比较丰富,下面是今 ...
- 高可用Hadoop平台-实战尾声篇
1.概述 今天这篇博客就是<高可用Hadoop平台>的尾声篇了,从搭建安装到入门运行 Hadoop 版的 HelloWorld(WordCount 可以称的上是 Hadoop 版的 Hel ...
- 高可用Hadoop平台-实战
1.概述 今天继续<高可用的Hadoop平台>系列,今天开始进行小规模的实战下,前面的准备工作完成后,基本用于统计数据的平台都拥有了,关于导出统计结果的文章留到后面赘述.今天要和大家分享的 ...
- 高可用Hadoop平台-集成Hive HAProxy
1.概述 这篇博客是接着<高可用Hadoop平台>系列讲,本篇博客是为后面用 Hive 来做数据统计做准备的,介绍如何在 Hadoop HA 平台下集成高可用的 Hive 工具,下面我打算 ...
- 高可用Hadoop平台-Flume NG实战图解篇
1.概述 今天补充一篇关于Flume的博客,前面在讲解高可用的Hadoop平台的时候遗漏了这篇,本篇博客为大家讲述以下内容: Flume NG简述 单点Flume NG搭建.运行 高可用Flume N ...
- 高可用Hadoop平台-Ganglia安装部署
1.概述 最近,有朋友私密我,Hadoop有什么好的监控工具,其实,Hadoop的监控工具还是蛮多的.今天给大家分享一个老牌监控工具Ganglia,这个在企业用的也算是比较多的,Hadoop对它的兼容 ...
- 高可用Hadoop平台-HBase集群搭建
1.概述 今天补充一篇HBase集群的搭建,这个是高可用系列遗漏的一篇博客,今天抽时间补上,今天给大家介绍的主要内容目录如下所示: 基础软件的准备 HBase介绍 HBase集群搭建 单点问题验证 截 ...
随机推荐
- redis.conf之save配置项解读
配置示例: save 900 1 save 300 10 save 60 3600 配置解读: 1) “save 900 1”表示如果900秒内至少1个key发生变化(新增.修改和删除),则重写rdb ...
- POJ3258--River Hopscotch(Binary Search similar to POJ2456)
Every year the cows hold an event featuring a peculiar version of hopscotch that involves carefully ...
- java中JDK环境变量的配置
JDK的配置在 window中的配置,我的电脑-->属性-->高级系统设置-->高级-->环境变量中配置,具体下图
- Python自动化开发 - 内置函数总结
Python解释器提供了很多内置函数 参考链接:https://docs.python.org/3.6/library/functions.html 一.数学相关 1.绝对值:abs(-1) 2.最大 ...
- Android-Java-单例模式优化&多线程并发
上一篇博客,Android-Java单例模式,介绍了在真实开发过程中,普遍使用的几种单例模式,而今天这篇博客,将要对单利模式进行优化 并且 通过多线程并发来分析 单利模式的优化: 对于为什么会出现安全 ...
- MariaDB安装、初始化及常用操作
1.Linux下安装与初始化 #安装 yum install mariadb-server #设置编码 vim /etc/my.cnf [mysqld]character-set-server=utf ...
- EF查询某个时间段内的数据遇到坑!
第一个问题 var res = pwDb.Set<WorkInfo>().Where(t => t.WorkTime > startTime && t.Work ...
- 《PHP, MySQL, Javascript和CSS》读书随手记----MySQL篇
一 基础 要求结尾分号 如果在命令输入期间想要终止其运行,不要Ctrl-C. 要输入\c,并按回车键. sql命令和关键字不区分大小写. 表名在windows中不区分大小写,但是在linux和os x ...
- JQuery Mobile - 解决页面点击时候,页眉和页脚消失问题!
当点击页面时候,页眉和页脚会消失!解决方法,在页面和页脚中加入: data-quicklinks="true" 实际使用代码: <div data-role="pa ...
- Mysql 经典案例总结(学习之前需要有Mysql基础)01
Sql 经典案例 gb 4.2 ** 1 检索记录 (1) 主要介绍 Sql的基本SELECT查询语句 使用 SELECT * from 表 查询数据 查询该表的每一列数据 * 代表所有的意思 也可以 ...