- 2015-03-26 11:29
論文需要用到這一部分技術,但苦於一直沒有深入的學習,所以還請您賜教,謝謝!!!qq:945856510,為了交流方便。
- 阿笨貓 2015-03-26 11:40
hadoop 我也只是業餘用用,不是很精通.
關於 你的問題 "細談如何Hadoop重寫分塊函數,改變分塊規則"
是否而已詳細說一下你的需求,看看我是否能幫上忙吧
- 2015-03-26 11:42
恩恩,
- 2015-03-26 11:45
我的檔案是一個按一行一行儲存的檔案,而且只有完整的一行才是有效資料,而實際上當我把檔案上傳到HDFS上的時候,它只是非常機械的按64M(預設的大小)一Block Storage的,這就破壞了我資料的有效性,所以我想是否能重寫這個分塊函數,在裡面加一些規則。。。這是我目前能想到的方法
- 2015-03-26 11:47
資料一般格式:keyword deweys
book 0.1.1.2_0.2.2.1_0.2.3.1
title 1.2.1.3_7.5.3
...
這樣的形式
- 阿笨貓 2015-03-26 11:51
我明白你的問題了,這個問題的解決,從來都不是修改block的劃分哦.而是修改你的reader的代碼哦.
雖然資料是按照block劃分,但是實際你在tt上讀取的資料,可不是只能讀取到一個block哦,資料讀取是可以跨越block界限的.block只是hadoop自己儲存的資料分塊組織,跟你的使用沒關係
這個hadoop的內建的reader裡面就有這樣的代碼,我待會給你找一下是那個代碼,待會去吃飯,你可能得多等一會
- 2015-03-26 11:52
好的,我也去吃飯哈…40後能會實驗室,謝謝你呀
- 2015-03-26 11:53
40分鐘後,。。。有點小激動啦
- 阿笨貓 2015-03-26 12:04
http://blog.csdn.net/skywalker_only/article/details/42678659
你閱讀下這個博文,
重點閱讀下"FileInputFormat的主要子類有..."後面這段
對於你的需求,TextInputFormat是可以滿足的.
對於你的疑問,閱讀"上述分割InputSplit的邏輯完全是針對大小進行的,那麼是否存在將一行記錄劃分到兩個InputSplit中的可能性?" 後面這一段.
如果還不明白的話,請閱讀TextInputFormat,LineRecordReader代碼.
在不明白,就Google,看別人怎麼解釋的.
我只能幫你到這裡了,剩下的靠你啦
- 阿笨貓 2015-03-26 13:58
是否解決了你的疑惑? 你看過那個 hadoop權威指南 沒有,可以網上下載一個看看
- 2015-03-26 14:40
恩恩,疑惑是解開了,但是就是不知道怎麼用KeyValueTextInputFormat或者TextInputFormat(剛剛一直在調試)。裡面對這兩個類的描述是這樣的:
1、KeyValueTextInputFormat:用於純文字檔案的InputFormat,每行使用分隔位元組劃分為鍵和值,該分隔字元由參數mapreduce.input.keyvaluelinerecordreader.key.value.separator指定,預設使用\t。如果該分隔字元不存在則整行將做為鍵,值為空白。RecordReader為KeyValueLineRecordReader。
2、TextInputFormat:用於純文字檔案的InputFormat,也是預設的InputFormat。輸入檔案被分解為行,斷行符號或者換行做為行結束的標記,鍵為行在檔案中的位置,值為行內容。該InputFormat使用LineRecordReader讀取InputSplit的內容。
現在問題就是MapReducer本身是內部調用TextInputFormat的,換句話說就是比如:我現在想用KeyValueTextInputFormat,但是該如何設定(配置)參數呢,讓MapReducer知道去調用KeyValueTextInputFormat呢?那本書我沒有看過,但是有。我現在就是想知道怎麼調用KeyValueTextInputFormat。。。
- 2015-03-26 14:45
你忙吧,我要是先弄弄,出來了就告訴你哈,謝謝你啊!!
- 2015-03-26 18:03
那個問題已經解決了,主要是在引用包的時候要注意hadoop版本的區別,謝謝你啊
- 2015-04-13 17:18
您好!這兩天我一直糾結於一個非常奇怪的問題,憋了兩天了,實在沒有辦法,只好來求助於你了.....希望能從你這裡獲得解決問題的思路。I am really looking forward to your reply,thank you!
- 阿笨貓 2015-04-13 17:20
有問題就直接留言啊,你這樣多浪費時間?
- 2015-04-13 17:37
輸入資料格式(給map的資料):
John-0.0.0_0.1.0.0.0_0.1.1.1.0_0.1.2.0.0_0.2.0.0.0
Projects-0.2
我想得到的輸出資料格式:
Projects-0.2
John-0.0.0_0.1.0.0.0_0.1.1.1.0_0.1.2.0.0_0.2.0.0.0
換句話說就是按照單詞後面的dewey碼的個數從小到大排序,而不是單詞的順序,我的排序程式核心程式如下:
public static class Map extends Mapper{
public void map(Text key,Text value,Context context)throws IOException,InterruptedException{
String[] s=value.toString().trim().split("_");
context.write(new Text(s.length+""), new Text(key.toString()+"-"+value)); //key與values之間是用"="符號隔開,這在main函數中進行了設定
}
}
public static class Reduce extends Reducer<Text,Text,Text,Text>{public void reduce(Text key,Iterable<Text> values,Context context)throws IOException,InterruptedException{Iterator<Text> itr = values.iterator();Text t=itr.next();StringTokenizer st = new StringTokenizer(t.toString(),"-");System.out.println("st的大小為:"+st.countTokens());}}
控制台輸出的結果為:
15/04/13 17:34:16 INFO mapred.MapTask: data buffer = 79691776/99614720
15/04/13 17:34:16 INFO mapred.MapTask: record buffer = 262144/327680
15/04/13 17:34:16 INFO mapred.MapTask: Starting flush of map output
st的大小為:2
st的大小為:2
15/04/13 17:34:17 INFO mapred.MapTask: Finished spill 0
15/04/13 17:34:17 INFO mapred.TaskRunner: Task:attempt_local_0001_m_000000_0 is done. And is in the process of commiting
15/04/13 17:34:17 INFO mapred.LocalJobRunner:
15/04/13 17:34:17 INFO mapred.TaskRunner: Task ‘attempt_local_0001_m_000000_0‘ done.
15/04/13 17:34:17 INFO mapred.LocalJobRunner:
15/04/13 17:34:17 INFO mapred.Merger: Merging 1 sorted segments
15/04/13 17:34:17 INFO mapred.Merger: Down to the last merge-pass, with 1 segments left of total size: 10 bytes
15/04/13 17:34:17 INFO mapred.LocalJobRunner:
st的大小為:0
這讓我非常苦惱,真實搞不明白,為什麼會出現-----st的大小為:0----這樣一個輸出,我也不知道到底是那個環節出了問題,還望您指點
- 阿笨貓 2015-04-13 20:36
我建議你把map裡面的key,value都System.out輸出下看看,是不是和你想象的一樣?
- 阿笨貓 2015-04-13 20:37
再給你一個建議,把上次推薦的 hadoop權威指南 看完,下次書上可以找到答案的,就不回複你了
- 阿笨貓 2015-04-13 20:39
最後一個建議,建議你嘗試下streaming,針對你之前提的問題,我建議試試streaming.
http://www.cnblogs.com/luchen927/archive/2012/01/16/2323448.html
- 2015-04-13 20:45
恩,好的。我在map裡面都輸出看了,是有資料的,但是就是不知道reduce為什麼最後還蹦出一條資料,那條資料在reduce裡面,用System.out怎麼都顯示不出來,而且更奇怪的是單只是在reduce裡面System.out能看到和map裡面一樣的資料,一加上context.write寫的時候,就報越界,而如果我進行if控制之後,context.write正常歸約輸出的資料也不能寫入HDFS中了,。。。。。非常奇怪
- 阿笨貓 2015-04-13 20:47
把完整代碼貼出來吧,這裡放不下,就發你部落格裡吧.資料檔案cat幾行出來,全部要正式的情況,我運行下試試
- 2015-04-13 20:57
實在不好意思,還沒有開通部落格,代碼只能現將就一下了,
- 2015-04-13 20:57
package ile.mapreduce.hqs.www.school;
import java.io.IOException;
import java.util.Iterator;
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.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
/**
- @author hzd
- @version 2015-4-12 14:34
- 1.功能:對XML的關鍵字,根據dewey碼進行排序
- 2.現在可以確定的是,‘-‘號作為分割符(其實在解析大檔案出現的各種問題,實在是有點讓人難於理解)
- 3.使用了自訂的AW_KeyValueTextInputFormat類進行讀取Hadoop上的檔案,其實hadoop
-
本身就有KeyValueTextInputFormat,但是由於版本更新的問題使得介面有所變更,導致函數參數無法正確的對上
*/
public class AW3_Sort_Deweys implements Tool{
public static class Map extends Mapper{
public void map(Text key,Text value,Context context)throws IOException,InterruptedException{
StringTokenizer st = new StringTokenizer(value.toString(),"\n");
while(st.hasMoreTokens()){
String[] s=st.nextToken().split("_");
context.write(new Text(s.length+""), new Text(key.toString()+"-"+value));
}
}
}
public static class Reduce extends Reducer{
public void reduce(Text key,Iterable values,Context context)throws IOException,InterruptedException{
Iterator<Text> itr = values.iterator();Text t=itr.next();StringTokenizer st = new StringTokenizer(t.toString(),"-");int i=0;Text k=null,v=null;while(st.hasMoreTokens()){System.out.println(st.nextToken());if(0==i){k = new Text(st.nextToken());}else{v = new Text(st.nextToken());}}context.write(k,v);}
}
@Override
public int run(String[] arg0) throws Exception {
// TODO Auto-generated method stub
String input = "hdfs://localhost:9000/user/hzd/output-selected/";
String output = "hdfs://localhost:9000/user/hzd/output-sorted/";
Path inputDir = new Path(input); Path outputDir = new Path(output); Configuration conf=new Configuration();conf.set("mapred.textoutputformat.separator","-");//輸出的時候也按"-"符號作為分隔字元Job job=new Job(conf,"Sort_Deweys");job.setInputFormatClass(AW_KeyValueTextInputFormat.class);//我也是人才啊,這個Hadoop幹了這種調包的事情都不說一聲job.setJarByClass(AW3_Sort_Deweys.class);job.setMapperClass(Map.class);job.setCombinerClass(Reduce.class);job.setReducerClass(Reduce.class);job.setOutputKeyClass(Text.class);job.setOutputValueClass(Text.class);FileInputFormat.addInputPath(job, inputDir);FileOutputFormat.setOutputPath(job, outputDir);job.waitForCompletion(true);return job.isSuccessful()?0:1;
}
public static void main(String[] args) throws Exception {
AW3_Sort_Deweys sort_dewey = new AW3_Sort_Deweys();
int exit = ToolRunner.run(sort_dewey, args);
System.exit(exit);
}
@Override
public Configuration getConf() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setConf(Configuration arg0) {
// TODO Auto-generated method stub
}
}
- 2015-04-13 21:04
http://pan.baidu.com/s/1c0B6efY
- 2015-04-13 21:04
用到的兩個Java類我放到雲端硬碟上了,你看看
- 阿笨貓 2015-04-13 21:06
part-r-00000 是輸入是嗎?
- 2015-04-13 21:05
對的
- 阿笨貓 2015-04-13 21:06
弱弱的問一句,你註冊了部落格園,難道沒有給你開通部落格?
- 2015-04-13 21:09
其實我這樣就是為了達到下面這種效果
輸入資料格式(給map的資料):
John-0.0.0_0.1.0.0.0_0.1.1.1.0_0.1.2.0.0_0.2.0.0.0
Projects-0.2
我想得到的輸出資料格式:
Projects-0.2
John-0.0.0_0.1.0.0.0_0.1.1.1.0_0.1.2.0.0_0.2.0.0.0
換句話說就是按照單詞後面的dewey碼的個數從小到大排序,而不是單詞的順序
- 2015-04-13 21:11
純屬失誤,給你帶來不便,還請諒解,我今晚就申請開通
- 阿笨貓 2015-04-13 21:31
AW_KeyValueTextInputFormat 你這個類做了啥改動?為啥要做這樣的改動?預設的textinputformat為什麼不符合你的功能?
- 2015-04-13 21:36
是的,因為我要,按"—"符號進行分割
- 阿笨貓 2015-04-13 21:37
我囧,你使用預設的textinputformat,然後在map裡面你得到的是key(offset),和value(Projects-0.2),你在map函數裡自己split好了,這樣不行嗎?
- 2015-04-13 21:43
主要是我要藉助rreduce對Dewey碼進行排序
- 阿笨貓 2015-04-13 21:46
John-0.0.0_0.1.0.0.0_0.1.1.1.0_0.1.2.0.0_0.2.0.0.0
這個資料,Dewey碼是指0.0.0_0.1.0.0.0_0.1.1.1.0_0.1.2.0.0_0.2.0.0.0 嗎?
按照這個進行字典序排序?
- 2015-04-13 21:43
如果資料量很大的話,自己寫程式進行排序,後果很嚴重……而如果能用其他方法實現我說的那種順序,當然是也可以,但是,我就一直苦於為什麼在reduce裡面會報那種錯誤
- 2015-04-13 21:43
如果資料量很大的話,自己寫程式進行排序,後果很嚴重……而如果能用其他方法實現我說的那種順序,當然是也可以,但是,我就一直苦於為什麼在reduce裡面會報那種錯誤
- 2015-04-13 21:46
如果資料量很大的話,自己寫程式進行排序,後果很嚴重……而如果能用其他方法實現我說的那種順序,當然是也可以,但是,我就一直苦於為什麼在reduce裡面會報那種錯誤
- 2015-04-13 21:45
後面的是dewey碼,但是是按Dewey碼的個數的多少進行排序,而不是字典序
- 2015-04-13 21:49
忘了說明了,一個關鍵字,如果有多個Dewey碼,那麼Dewey之間用"_"隔開
- 阿笨貓 2015-04-13 21:51
"按Dewey碼的個數的多少進行排序" 這個邏輯你在代碼裡面那部分做的?
- 2015-04-13 21:54
藉助map裡面算出來的Dewey碼的個數,進行排序
- 阿笨貓 2015-04-13 22:00
先拋開你說的那個reduce的輸出問題.
你想排序,你現在使用的是hadoop預設的reduce會對key進行排序,不過你知道reduce端對key進行排序,是字典序的,也就意味著順序可能是,1,11,2,3... ,11個Dewey碼的要排在2個Dewey碼的前面
- 2015-04-13 22:03
恩,這個我知道,我會控制在沒9個一組的基礎上進行處理
- 2015-04-13 22:03
這是我目前的思路
- 阿笨貓 2015-04-13 22:03
原來如此,那就好
今天時間有點晚了,我先下了,建議你先不糾結為啥有哪個輸出,先搞定你要的功能吧.我明天給你一個可啟動並執行版本吧
- 2015-04-13 22:04
好的,非常感謝,晚安!
- 阿笨貓 2015-04-13 22:44
package test;
import java.io.IOException;
import java.util.Iterator;
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.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.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class AW3_Sort_Deweys implements Tool{
public static class Map extends Mapper<LongWritable,Text,LongWritable,Text>{public void map(LongWritable key,Text value,Context context)throws IOException,InterruptedException{ String[] kv = value.toString().split("-"); if (kv.length<2) return; String[] ss = kv[1].split("_"); context.write(new LongWritable(ss.length), value);}}public static class Reduce extends Reducer<LongWritable,Text,Text,Text>{public void reduce(LongWritable key,Iterable<Text> values,Context context)throws IOException,InterruptedException{for(Text v :values) context.write(new Text(),v);}}@Overridepublic int run(String[] arg0) throws Exception {String input = "/wireless_ha3_xuxm/in1/"; String output = "/wireless_ha3_xuxm/out1/"; Path inputDir = new Path(input); Path outputDir = new Path(output); Configuration conf=new Configuration();Job job=new Job(conf,"Sort_Deweys");job.setJarByClass(AW3_Sort_Deweys.class);job.setMapperClass(Map.class);job.setReducerClass(Reduce.class);FileInputFormat.addInputPath(job, inputDir);FileOutputFormat.setOutputPath(job, outputDir);job.waitForCompletion(true);return job.isSuccessful()?0:1;}public static void main(String[] args) throws Exception {AW3_Sort_Deweys sort_dewey = new AW3_Sort_Deweys();int exit = ToolRunner.run(sort_dewey, args);System.exit(exit);}@Overridepublic Configuration getConf() {return null;}@Overridepublic void setConf(Configuration arg0) {}
}
- 阿笨貓 2015-04-13 22:42
[admin at inc-search-dev-offer3 doc-count]$ hadoop fs -cat /wireless_ha3_xuxm/in1/*
Ben-0.1.1.2.0_0.1.2.1.0_0.2.0.0.1_0.3.0.0.0_0.3.1.0.0
John-0.0.0_0.1.0.0.0_0.1.1.1.0_0.1.2.0.0
Projects-0.2
[admin at inc-search-dev-offer3 doc-count]$ hadoop fs -cat /wireless_ha3_xuxm/out1/part-r-00000
Projects-0.2
John-0.0.0_0.1.0.0.0_0.1.1.1.0_0.1.2.0.0
Ben-0.1.1.2.0_0.1.2.1.0_0.2.0.0.1_0.3.0.0.0_0.3.1.0.0
- 阿笨貓 2015-04-13 22:43
啟動並執行效果是這樣的,我也只能幫到你這裡了,後面靠你自己了