一、scala
scala版本:
val t1=list1.flatMap(_.split(" ")).map((_,1))
.groupBy(_._1) //不可以替换为groupByKey(),scala没有这个算子
.mapValues(_.size)
.toList
.sortWith(_._2>_._2) //可以替换为sortBy(_._2),但是没有设置第二个参数
二、Spark版本 写法二:
val conf:SparkConf=new SparkConf()
conf.setAppName("myWC")
conf.setMaster("local[*]")
val sc = new SparkContext(conf)
val r1: RDD[String] = sc.textFile("hdfs://mini1:9000/data/wcount")
val r2 = r1.flatMap(_.split(" ")).map(x=>(x,1))
.reduceByKey(_+_) //scala中没有这个算子
.sortBy(_._2,false)
println(r2.collect().toBuffer)
r2.saveAsTextFile("hdfs://mini1:9000/out/wcount_2_11") //一个目录
三、MR写法
mapper
package wordcount;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import java.io.IOException;
/**
* @Description
* @Author cqh <caoqingghai@1000phone.com>
* @Version V1.0
* @Since 1.0
* @Date 2019/4/12 17:23
*/
public class WordCountMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
Text k = new Text();
IntWritable v = new IntWritable(1);
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
FileSplit fileSplit = (FileSplit) context.getInputSplit();
String fileName = fileSplit.getPath().getName();
String line = value.toString();
String[]fileds = line.split(" ");
for (String word : fileds){
k.set(word);
context.write(k,v);
}
}
}
reducer
package wordcount;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
/**
* @Description
* @Author cqh <caoqingghai@1000phone.com>
* @Version V1.0
* @Since 1.0
* @Date 2019/4/12 17:23
*/
public class WordCountReduce extends Reducer<Text, IntWritable,Text,IntWritable> {
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int count =0;
for (IntWritable value :values){
count += value.get();
}
context.write(key,new IntWritable(count));
}
}
runner
package wordcount;
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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
/**
* @Description
* @Author cqh <caoqingghai@1000phone.com>
* @Version V1.0
* @Since 1.0
* @Date 2019/4/12 17:23
*/
public class WordCountRunner {
public static void main(String[] args) {
try {
Configuration conf = new Configuration();
//设置行分隔符,可能 读取多行数据比如我们的配置文件</property>
//conf.set("textinputformat.record.delimiter","</doc>");
//获取job并携带参数
Job job = Job.getInstance(conf,"wordCount");
//可以用job对象封装一些信息
//首先程序是一个jar包,就要指定jar包的位置
//将jar包放在root目录下
//可以将这个程序打包为pv.jar,上传到linux机器上
//使用命令运行
//hadoop jar /root/pv.jar pvcount.PvCountRunner /data/pvcount /out/pvcount
//hadoop jar /zgm2/wc.jar z1wc.MyRunner /data/wcount /out/zwcount
job.setJar("/root/word.jar");
/**
* 一个jar包中可能有多个job,所以我们要指明job使用的是哪儿一个map类
* 哪儿一个reduce类
*/
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReduce.class);
/**
* map端输出的数据要进行序列化,所以我们要告诉框架map端输出的数据类型
*/
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
/**
* reduce端要输出,所有也要指定数据类型
*/
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
/**
* 告诉框架用什么组件去读数据,普通的文本文件,就用TextInputFormat
* 导入长包
*/
job.setInputFormatClass(TextInputFormat.class);
/**
* 告诉这个组件去哪儿读数据
* TextInputFormat有个父类FileInputFormat
* 用父类去指定到哪儿去读数据
* 输入路径是一个目录,该目录下如果有子目录需要进行设置递归遍历,否则会报错
*/
FileInputFormat.addInputPath(job,new Path(args[0]));
/**
* 干预分片的大小
*/
//FileInputFormat.setMinInputSplitSize(job,1000);
//FileInputFormat.setMaxInputSplitSize(job,1000000);
//设置写出的组件
job.setOutputFormatClass(TextOutputFormat.class);
//设置写出的路径
FileOutputFormat.setOutputPath(job,new Path(args[1]));
// FileOutputFormat.
job.setNumReduceTasks(2);
//执行
/**
* 信息设置完成,可以调用方法向yarn去提交job
* waitForCompletion方法就会将jar包提交给RM
* 然后rm可以将jar包分发,其他机器就执行
*/
//传入一个boolean类型的参数,如果是true,程序执行会返回true/flase
//如果参数传入true,集群在运行时会有进度,这个进度会在客户端打印
boolean res = job.waitForCompletion(true);
/**
* 客户端退出后会返回一个状态码,这个状态码我们可以写shell脚本的时候使用
* 根据返回的状态码的不同区执行不同的逻辑
*/
System.exit(res? 0:1);
} catch (Exception e) {
e.printStackTrace();
}
}
}