hadoop實現自動打包并提交到集群(完全自動)
話不多說,直接上效果圖。
可以看到代碼是在集群上運行的而不是在本地。
而且我所說的自動不是其他博客說的那樣還要自己手動打jar包然后在eclipse中通過代碼傳到集群上,而是在eclipse上運行這段代碼會自動把jar包打好然后自動上傳到集群上
完全不用手!
完全不用手!
完全不用手!
非常方便!!!
示例
鏈接:https://pan.baidu.com/s/1KVvwsHLEI0CHdhiwcfIgww
提取碼:ahzp
這是一個倒排索引的例子,data是數據,InvertIndex是mapreduce代碼,EJob是自動打包工具。
代碼中的一些關鍵點我已經備注了,按照提示設置路徑就沒問題。
首先在eclipse中連接hadoop,可以參照我的博客,但是按照這樣運行是默認在本地運行的,運行時會顯示在localhost上運行,要想在集群上運行,需要把在搭建hadoop中的配置的那些文件復制到本項目的bin目錄下,像這樣,然后就可以提交到集群了。可以直接拿我這個代碼改一下路徑嘗試一下完全自動打包提交的快感。
代碼展示
InvertIndex的代碼(用來實現倒排索引的,很基礎,所以不過多說):
package test;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
//import org.apache.hadoop.io.LongWritable;
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.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapred.JobConf;
public class InvertIndex {
public static class Map extends Mapper<LongWritable,Text,Text,Text>
{
@Override
public void map(LongWritable key,Text value,Context context) throws IOException,InterruptedException
{
FileSplit fileSplit = (FileSplit)context.getInputSplit();
String fileName = fileSplit.getPath().getName();
Text word = new Text();
// System.out.println(fileName.toString());
Text fileName_lineOffset = new Text(fileName);
StringTokenizer itr = new StringTokenizer(value.toString());
for(;itr.hasMoreTokens();){
word.set(itr.nextToken());
context.write(word, fileName_lineOffset);
}
}
}
public static class Reduce extends Reducer<Text,Text,Text,Text>
{
@Override
public void reduce(Text key,Iterable<Text> values,Context context) throws IOException,InterruptedException
{
Iterator<Text> it = values.iterator();
StringBuilder all = new StringBuilder();
if (it.hasNext()){
all.append(it.next().toString());
for(;it.hasNext();){
all.append(";");
// System.out.println(it.next());
all.append(it.next().toString());
}
context.write(key, new Text(all.toString()));
}
}
}
public static void main(String[] args ) throws Exception
{
// 重點
// 這部分就是自動打jar包的代碼,將需要打包的項目的bin目錄輸入,然后jar包會輸出到EJob中設置的輸出目錄中
File jarFile = EJob.createTempJar("/root/workspace/Myproject/bin");
System.out.println(jarFile);
ClassLoader classLoader = EJob.getClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
// 重點
Configuration conf = new Configuration(true);
String[] ars=new String[]{"hdfs://192.168.75.128:9000/data/","hdfs://192.168.75.128:9000/output/test"};
String[] otherArgs=new GenericOptionsParser(conf,ars).getRemainingArgs();
@SuppressWarnings("deprecation")
Job job= Job.getInstance(conf,"invert index");
// 將打成的jar包上傳到集群
((JobConf) job.getConfiguration()).setJar(jarFile.toString());
job.setMapperClass(Map.class);
job.setReducerClass(Reduce.class);
job.setInputFormatClass(TextInputFormat.class);
FileInputFormat.addInputPath(job,new Path(otherArgs[0]));
// job.setOutputFormatClass(TextOutputFormat.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
String time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
FileOutputFormat.setOutputPath(job,new Path(otherArgs[1]+ time));
System.out.println("Job Start!");
if (job.waitForCompletion(true)) {
System.out.println("ok!");
System.exit(0);
} else {
System.out.println("error!");
System.exit(-1);
}
}
}
EJob的代碼(這是個大佬寫的,真的非常好用,大體思路就是創建一個jar包,然后讀取bin目錄下文件將其寫入jar包中,然后直接將該jar包提交到集群上,實現完全自動打包提交。代碼中具體要改的我已經備注上去了,按照備注改就可以正常運行了):
package test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
public class EJob {
private static List<URL> classPath = new ArrayList<URL>();
// 這里的輸入root是你要打jar包項目的bin目錄
public static File createTempJar(String root) throws IOException {
// System.out.println("bbbb");
if (!new File(root).exists()) {
return null;
}
// System.out.println("aaaa");
Manifest manifest = new Manifest();
manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
//final File jarFile = File.createTempFile("EJob-", ".jar", new File(System.getProperty("java.io.tmpdir")));
// 這個是你打成的jar包輸出的目錄
final File jarFile = File.createTempFile("EJob-", ".jar",new File("/root/workspace/Myproject/bin/zf/"));
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
jarFile.delete();
}
});
JarOutputStream out = new JarOutputStream(new FileOutputStream(jarFile), manifest);
createTempJarInner(out, new File(root), "");
out.flush();
out.close();
return jarFile;
}
private static void createTempJarInner(JarOutputStream out, File f,String base) throws IOException{
if (f.isDirectory()) {
File[] fl = f.listFiles();
if (base.length() > 0) {
base = base + "/";
}
for (int i = 0; i < fl.length; i++) {
createTempJarInner(out, fl[i], base + fl[i].getName());
}
} else {
out.putNextEntry(new JarEntry(base));
FileInputStream in = new FileInputStream(f);
byte[] buffer = new byte[1024];
int n = in.read(buffer);
while (n != -1) {
out.write(buffer, 0, n);
n = in.read(buffer);
}
in.close();
}
}
public static ClassLoader getClassLoader() {
ClassLoader parent = Thread.currentThread().getContextClassLoader();
if (parent == null){
parent = EJob.class.getClassLoader();
}
if (parent == null) {
parent = ClassLoader.getSystemClassLoader();
}
return new URLClassLoader(classPath.toArray(new URL[0]), parent);
}
public static void addClasspath(String component) {
if ((component != null) && (component.length() > 0)) {
try {
File f = new File(component);
if (f.exists()) {
//URL key = f.getCanonicalFile().toURL();
URL key = f.getCanonicalFile().toURI().toURL();
if (!classPath.contains(key)) {
classPath.add(key);
}
}
}catch (IOException e) {
}
}
}
}
智能推薦
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
猜你喜歡
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...
styled-components —— React 中的 CSS 最佳實踐
https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...
19.vue中封裝echarts組件
19.vue中封裝echarts組件 1.效果圖 2.echarts組件 3.使用組件 按照組件格式整理好數據格式 傳入組件 home.vue 4.接口返回數據格式...