本文已参加「新人创作礼」活动,一起开启掘金创作之路。
这次带来的是 对Hadoop、Hbase、Zookeeper 的简单理解,来帮助刚接触的新手们更简洁的理解其优缺点。除此之外,还有对上次发布的 Mapreduce 代码的简单解析。
对 Hadoop、Hbase、Zookeeper 的简单理解
Hadoop
一个大数据的框架,主要能解决海量数据的存储和海量数据的分析计算问题。Hadoop 的框架最核心的设计就是 HDFS 和 MapReduce,HDFS 为海量的数据提供了存储,则 MapReduce 为海量的数据提供了计算。
Hbase
Hbase 是一个构建在 HDFS 上面的分布式数据库,HDFS 的缺点是除了能够存储海量的数据之外,不支持小文件,不支持并发写,不支持文件随机修改,查询效率低,而 Hbase 是一个支持百万级别高并发写入,支持实时查询,适合存储稀疏数据的分布式数据库系统,补足了 HDFS 不能满足实施需求的缺点。
Zookeeper
一个集中式服务,用于维护配置信息,命名,提供分布式同步和提供组服务,可以协调 hadoop 以及其它的分布式系统。且可以提供组服务,即集群管理,就像 dubbo+zookeeer,服务器上的服务注册,或者获取服务,都是在 zookeeper 上操作的,比如创建组、加入组成员、列出组成员和删除组成员,而对于这些服务,主要通过 zookeeper 心跳机制,它会去检测与其连接的一些服务器的数量,以及信息。什么时候连上 zookeeper,或什么时候断开都有其心跳机制完成。相当于一个管理员的身份,加强了集群的稳定性。
上一节中提到的 Mapreduce 字符计数代码解析
/*
Mapper中四个参数
前面两个Text、IntWritable 指的是map 函数输入的参数key、value 的类型;
后面两个Text、IntWritable 指的是map 函数输出的key、value 的类型
*/
public class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {
IntWritable one = new IntWritable(1);
Text word = new Text();
/*
Object key 键
Text value 文本值
Context context 上下文
*/
//map方法,一次处理一行数据,然后以键值对的方式输出
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);
}
}
}
/*
Reducer中四个参数
表示每一行中的每个单词
表示每一行中的每个单词的出现次数,固定值为1
表示每一行中的每个单词
表示每一行中的每个单词的出现次数之和
*/
public class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
IntWritable result = new IntWritable();
/*
Text key 文本key
Iterable<IntWritable> values 次数
Context context 上下文
*/
//reduce方法 仅是将每个key出现的次数求和。
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);
}
}
public class WordCount {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
/*GenericOptionsParser是hadoop框架中解析命令行参数的基本类。
conf 需要修改的配置
args 执行jar包代码时传入的命令行参数
getRemainingArgs() 对命令行的输入参数进行处理
*/
String[] otherArgs = new GenericOptionsParser(conf,args).getRemainingArgs();
if(otherArgs.length != 2) {
System.err.println("Usage: wordcount <in> <out>");
System.exit(2);
}
Job job = new Job(conf, "wordcount");
job.setJarByClass(WordCount.class);//设置jar
job.setMapperClass(TokenizerMapper.class);//设置job的Mapper类
job.setCombinerClass(IntSumReducer.class);//设置Combiner预聚合类
job.setReducerClass(IntSumReducer.class);//设置job的Reducer类
//设置job的Mapper端输出的Key-Value类
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
//设置job的输入路径,路径为命令行的第一个参数
FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
//设置job的输出路径,路径为命令行的第二个参数
FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
//Job运行是通过job.waitForCompletion(true),true表示将运行进度等信息及时输出给用户,false的话只是等待作业结束判断返回值是0还是1,0为正常
System.exit(job.waitForCompletion(true)?0:1);
}
}