全排序 --(按字典顺序)BinaryComparable

6-1、全排序 --(按字典顺序)BinaryComparable


类SamplerInputFormat:

  1. package mapreduce.baozi;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.ArrayList;  
  5.   
  6. import org.apache.hadoop.conf.Configuration;  
  7. import org.apache.hadoop.fs.FileSystem;  
  8. import org.apache.hadoop.fs.Path;  
  9. import org.apache.hadoop.io.LongWritable;  
  10. import org.apache.hadoop.io.NullWritable;  
  11. import org.apache.hadoop.io.SequenceFile;  
  12. import org.apache.hadoop.io.Text;  
  13. import org.apache.hadoop.mapred.FileInputFormat;  
  14. import org.apache.hadoop.mapred.FileSplit;  
  15. import org.apache.hadoop.mapred.InputSplit;  
  16. import org.apache.hadoop.mapred.JobConf;  
  17. import org.apache.hadoop.mapred.LineRecordReader;  
  18. import org.apache.hadoop.mapred.RecordReader;  
  19. import org.apache.hadoop.mapred.Reporter;  
  20. import org.apache.hadoop.util.IndexedSortable;  
  21. import org.apache.hadoop.util.QuickSort;  
  22.   
  23. public class SamplerInputFormat extends FileInputFormat<Text, Text> {  
  24.   
  25.     static final String PARTITION_FILENAME = "_partition.lst";  
  26.     static final String SAMPLE_SIZE = "terasort.partitions.sample";  
  27.     private static JobConf lastConf = null;  
  28.     private static InputSplit[] lastResult = null;  
  29.   
  30.     static class TextSampler implements IndexedSortable {  
  31.   
  32.         public ArrayList<Text> records = new ArrayList<Text>();  
  33.   
  34.         @Override  
  35.         public int compare(int arg0, int arg1) {  
  36.             Text right = records.get(arg0);  
  37.             Text left = records.get(arg1);  
  38.   
  39.             return right.compareTo(left);  
  40.         }  
  41.   
  42.         @Override  
  43.         public void swap(int arg0, int arg1) {  
  44.             Text right = records.get(arg0);  
  45.             Text left = records.get(arg1);  
  46.   
  47.             records.set(arg0, left);  
  48.             records.set(arg1, right);  
  49.         }  
  50.   
  51.         public void addKey(Text key) {  
  52.             records.add(new Text(key));  
  53.         }  
  54.   
  55.         public Text[] createPartitions(int numPartitions) {  
  56.             int numRecords = records.size();  
  57.             if (numPartitions > numRecords) {  
  58.                 throw new IllegalArgumentException("Requested more partitions than input keys (" + numPartitions +  
  59.                         " > " + numRecords + ")");  
  60.             }  
  61.             new QuickSort().sort(this0, records.size());  
  62.             float stepSize = numRecords / (float) numPartitions;  
  63.             Text[] result = new Text[numPartitions - 1];  
  64.             for (int i = 1; i < numPartitions; ++i) {  
  65.                 result[i - 1] = records.get(Math.round(stepSize * i));  
  66.             }  
  67.             return result;  
  68.         }  
  69.   
  70.     }  
  71.   
  72.     public static void writePartitionFile(JobConf conf, Path partFile) throws IOException {  
  73.         SamplerInputFormat inputFormat = new SamplerInputFormat();  
  74.         TextSampler sampler = new TextSampler();  
  75.         Text key = new Text();  
  76.         Text value = new Text();  
  77.   
  78.         int partitions = conf.getNumReduceTasks(); // Reducer任务的个数  
  79.         long sampleSize = conf.getLong(SAMPLE_SIZE, 100); // 采集数据-键值对的个数  
  80.         InputSplit[] splits = inputFormat.getSplits(conf, conf.getNumMapTasks());// 获得数据分片  
  81.         int samples = Math.min(10, splits.length);// 采集分片的个数  
  82.         long recordsPerSample = sampleSize / samples;// 每个分片采集的键值对个数  
  83.         int sampleStep = splits.length / samples; // 采集分片的步长  
  84.         long records = 0;  
  85.   
  86.         for (int i = 0; i < samples; i++) {  
  87.             RecordReader<Text, Text> reader = inputFormat.getRecordReader(splits[sampleStep * i], conf, null);  
  88.             while (reader.next(key, value)) {  
  89.                 sampler.addKey(key);  
  90.                 records += 1;  
  91.                 if ((i + 1) * recordsPerSample <= records) {  
  92.                     break;  
  93.                 }  
  94.             }  
  95.         }  
  96.         FileSystem outFs = partFile.getFileSystem(conf);  
  97.         if (outFs.exists(partFile)) {  
  98.             outFs.delete(partFile, false);  
  99.         }  
  100.         SequenceFile.Writer writer = SequenceFile.createWriter(outFs, conf, partFile, Text.class, NullWritable.class);  
  101.         NullWritable nullValue = NullWritable.get();  
  102.         for (Text split : sampler.createPartitions(partitions)) {  
  103.             writer.append(split, nullValue);  
  104.         }  
  105.         writer.close();  
  106.   
  107.     }  
  108.   
  109.     static class TeraRecordReader implements RecordReader<Text, Text> {  
  110.   
  111.         private LineRecordReader in;  
  112.         private LongWritable junk = new LongWritable();  
  113.         private Text line = new Text();  
  114.         private static int KEY_LENGTH = 10;  
  115.   
  116.         public TeraRecordReader(Configuration job, FileSplit split) throws IOException {  
  117.             in = new LineRecordReader(job, split);  
  118.         }  
  119.   
  120.         @Override  
  121.         public void close() throws IOException {  
  122.             in.close();  
  123.         }  
  124.   
  125.         @Override  
  126.         public Text createKey() {  
  127.             // TODO Auto-generated method stub  
  128.             return new Text();  
  129.         }  
  130.   
  131.         @Override  
  132.         public Text createValue() {  
  133.             return new Text();  
  134.         }  
  135.   
  136.         @Override  
  137.         public long getPos() throws IOException {  
  138.             // TODO Auto-generated method stub  
  139.             return in.getPos();  
  140.         }  
  141.   
  142.         @Override  
  143.         public float getProgress() throws IOException {  
  144.             // TODO Auto-generated method stub  
  145.             return in.getProgress();  
  146.         }  
  147.   
  148.         @Override  
  149.         public boolean next(Text arg0, Text arg1) throws IOException {  
  150.             if (in.next(junk, line)) {  
  151.                // if (line.getLength() < KEY_LENGTH) {  
  152.                     arg0.set(line);  
  153.                     arg1.clear();  
  154. //                } else {  
  155. //                    byte[] bytes = line.getBytes(); // 默认知道读取要比较值的前10个字节 作为key  
  156. //                                                    // 后面的字节作为value;  
  157. //                    arg0.set(bytes, 0, KEY_LENGTH);  
  158. //                    arg1.set(bytes, KEY_LENGTH, line.getLength() - KEY_LENGTH);  
  159. //                }  
  160.                 return true;  
  161.             } else {  
  162.                 return false;  
  163.             }  
  164.         }  
  165.   
  166.     }  
  167.   
  168.     @Override  
  169.     public InputSplit[] getSplits(JobConf conf, int splits) throws IOException {  
  170.         if (conf == lastConf) {  
  171.             return lastResult;  
  172.         }  
  173.         lastConf = conf;  
  174.         lastResult = super.getSplits(lastConf, splits);  
  175.         return lastResult;  
  176.   
  177.     }  
  178.   
  179.     public org.apache.hadoop.mapred.RecordReader<Text, Text> getRecordReader(InputSplit arg0, JobConf arg1,  
  180.             Reporter arg2) throws IOException {  
  181.         return new TeraRecordReader(arg1, (FileSplit) arg0);  
  182.     }  
  183.   
  184. }  



类SamplerSort:

  1. package mapreduce.baozi;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.URI;  
  5. import java.util.ArrayList;  
  6. import java.util.List;  
  7.   
  8. import org.apache.hadoop.conf.Configured;  
  9. import org.apache.hadoop.filecache.DistributedCache;  
  10. import org.apache.hadoop.fs.FileSystem;  
  11. import org.apache.hadoop.fs.Path;  
  12. import org.apache.hadoop.io.NullWritable;  
  13. import org.apache.hadoop.io.SequenceFile;  
  14. import org.apache.hadoop.io.Text;  
  15. import org.apache.hadoop.mapred.FileOutputFormat;  
  16. import org.apache.hadoop.mapred.JobClient;  
  17. import org.apache.hadoop.mapred.JobConf;  
  18. import org.apache.hadoop.mapred.Partitioner;  
  19. import org.apache.hadoop.mapred.TextOutputFormat;  
  20. import org.apache.hadoop.util.Tool;  
  21. import org.apache.hadoop.util.ToolRunner;  
  22.   
  23. public class SamplerSort extends Configured implements Tool {  
  24.   
  25.     // 自定义的Partitioner  
  26.     public static class TotalOrderPartitioner implements Partitioner<Text, Text> {  
  27.   
  28.         private Text[] splitPoints;  
  29.   
  30.         public TotalOrderPartitioner() {  
  31.         }  
  32.   
  33.         @Override  
  34.         public int getPartition(Text arg0, Text arg1, int arg2) {  
  35.             // TODO Auto-generated method stub  
  36.             return findPartition(arg0);  
  37.         }  
  38.   
  39.         public void configure(JobConf arg0) {  
  40.             try {  
  41.                 FileSystem fs = FileSystem.getLocal(arg0);  
  42.                 Path partFile = new Path(SamplerInputFormat.PARTITION_FILENAME);  
  43.                 splitPoints = readPartitions(fs, partFile, arg0); // 读取采集文件  
  44.             } catch (IOException ie) {  
  45.                 throw new IllegalArgumentException("can't read paritions file", ie);  
  46.             }  
  47.   
  48.         }  
  49.   
  50.         public int findPartition(Text key) // 分配可以到多个reduce  
  51.         {  
  52.             int len = splitPoints.length;  
  53.             for (int i = 0; i < len; i++) {  
  54.                 int res = key.compareTo(splitPoints[i]);  
  55.                 if (res > 0 && i < len - 1) {  
  56.                     continue;  
  57.                 } else if (res == 0) {  
  58.                     return i;  
  59.                 } else if (res < 0) {  
  60.                     return i;  
  61.                 } else if (res > 0 && i == len - 1) {  
  62.                     return i + 1;  
  63.                 }  
  64.             }  
  65.             return 0;  
  66.         }  
  67.   
  68.         private static Text[] readPartitions(FileSystem fs, Path p, JobConf job) throws IOException {  
  69.             SequenceFile.Reader reader = new SequenceFile.Reader(fs, p, job);  
  70.             List<Text> parts = new ArrayList<Text>();  
  71.             Text key = new Text();  
  72.             NullWritable value = NullWritable.get();  
  73.             while (reader.next(key, value)) {  
  74.                 parts.add(key);  
  75.             }  
  76.             reader.close();  
  77.             return parts.toArray(new Text[parts.size()]);  
  78.         }  
  79.   
  80.     }  
  81.   
  82.     @Override  
  83.     public int run(String[] args) throws Exception {  
  84.         JobConf job = (JobConf) getConf();  
  85.        // job.set(name, value);  
  86.         Path inputDir = new Path(args[0]);  
  87.         inputDir = inputDir.makeQualified(inputDir.getFileSystem(job));  
  88.         Path partitionFile = new Path(inputDir, SamplerInputFormat.PARTITION_FILENAME);  
  89.   
  90.         URI partitionUri = new URI(partitionFile.toString() +  
  91.                 "#" + SamplerInputFormat.PARTITION_FILENAME);  
  92.   
  93.         SamplerInputFormat.setInputPaths(job, new Path(args[0]));  
  94.         FileOutputFormat.setOutputPath(job, new Path(args[1]));  
  95.   
  96.         job.setJobName("SamplerTotalSort");  
  97.         job.setJarByClass(SamplerSort.class);  
  98.         job.setOutputKeyClass(Text.class);  
  99.         job.setOutputValueClass(Text.class);  
  100.         job.setInputFormat(SamplerInputFormat.class);  
  101.         job.setOutputFormat(TextOutputFormat.class);  
  102.         job.setPartitionerClass(TotalOrderPartitioner.class);  
  103.         job.setNumReduceTasks(4);  
  104.   
  105.         SamplerInputFormat.writePartitionFile(job, partitionFile); // 数据采集并写入文件  
  106.   
  107.         DistributedCache.addCacheFile(partitionUri, job);  
  108.         DistributedCache.createSymlink(job);  
  109.         // SamplerInputFormat.setFinalSync(job, true);  
  110.         JobClient.runJob(job);  
  111.         return 0;  
  112.     }  
  113.   
  114.     public static void main(String[] args) throws Exception {  
  115.         int res = ToolRunner.run(new JobConf(), new SamplerSort(), args);  
  116.         System.exit(res);  
  117.     }  
  118.   
  119. }  



输入数据:

  1. hadoop@hadoop:/home/hadoop/blb$ hdfs dfs -text libin/input/*  
  2. dfgdfg  
  3. sdfg  
  4. try  
  5. hjk  
  6. nvb  
  7. ghjk  
  8. uiy  
  9. dfdsf  
  10. xcvx  
  11. asda  
  12. wqe  
  13. zxc  
  14. vbnvb  
  15. fghfghd  
  16. iop  
  17. ery  
  18. mnbgj  
  19. asd  
  20. bdfb  
  21. cfh  
  22. awr  
  23. abgf  
  24. bdfgh  
  25. bnj  
  26. boi  
  27. boiut  
  28. hadoop@hadoop:/home/hadoop/blb$   


输出目录及数据:

  1. hadoop@hadoop:/home/hadoop/blb$ hdfs dfs -ls libin/output/totalorderoutzidian  
  2. Found 5 items  
  3. -rw-r--r--   2 hadoop hadoop          0 2015-10-08 16:13 libin/output/totalorderoutzidian/_SUCCESS  
  4. -rw-r--r--   2 hadoop hadoop        125 2015-10-08 16:13 libin/output/totalorderoutzidian/part-00000  
  5. -rw-r--r--   2 hadoop hadoop          0 2015-10-08 16:13 libin/output/totalorderoutzidian/part-00001  
  6. -rw-r--r--   2 hadoop hadoop          0 2015-10-08 16:13 libin/output/totalorderoutzidian/part-00002  
  7. -rw-r--r--   2 hadoop hadoop         28 2015-10-08 16:13 libin/output/totalorderoutzidian/part-00003  
  8. hadoop@hadoop:/home/hadoop/blb$ hdfs dfs -text libin/output/totalorderoutzidian/*  
  9. abgf  
  10. asd  
  11. asda  
  12. awr  
  13. bdfb  
  14. bdfgh  
  15. bnj  
  16. boi  
  17. boiut  
  18. cfh  
  19. dfdsf  
  20. dfgdfg  
  21. ery  
  22. fghfghd  
  23. ghjk  
  24. hjk  
  25. iop  
  26. mnbgj  
  27. nvb  
  28. sdfg  
  29. try  
  30. uiy  
  31. vbnvb  
  32. wqe  
  33. xcvx  
  34. zxc 

原文地址:http://blog.csdn.net/baolibin528/article/details/48974233

参考资料:http://blog.csdn.net/yeruby/article/details/21233661

http://my.oschina.net/dfsj66011/blog/342633

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值