Why I am here--細談如何Hadoop重寫分塊函數,改變分塊規則

來源:互聯網
上載者:User

標籤:

    • 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

      啟動並執行效果是這樣的,我也只能幫到你這裡了,後面靠你自己了

Why I am here--細談如何Hadoop重寫分塊函數,改變分塊規則

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.