我是靠谱客的博主 调皮红酒,最近开发中收集的这篇文章主要介绍MR生成HFile文件,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、MR生成HFile文件

[java]  view plain  copy
  1. package insert.tools.hfile;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import org.apache.hadoop.conf.Configuration;  
  6. import org.apache.hadoop.fs.Path;  
  7. import org.apache.hadoop.hbase.HBaseConfiguration;  
  8. import org.apache.hadoop.hbase.KeyValue;  
  9. import org.apache.hadoop.hbase.io.ImmutableBytesWritable;  
  10. import org.apache.hadoop.hbase.mapreduce.KeyValueSortReducer;  
  11. import org.apache.hadoop.hbase.util.Bytes;  
  12. import org.apache.hadoop.io.LongWritable;  
  13. import org.apache.hadoop.io.Text;  
  14. import org.apache.hadoop.mapreduce.Job;  
  15. import org.apache.hadoop.mapreduce.Mapper;  
  16. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
  17. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
  18.   
  19. public class TestHFileToHBase {  
  20.   
  21.     public static class TestHFileToHBaseMapper extends Mapper {  
  22.   
  23.         @Override  
  24.         protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {  
  25.             String[] values = value.toString().split("/t"2);  
  26.             byte[] row = Bytes.toBytes(values[0]);  
  27.             ImmutableBytesWritable k = new ImmutableBytesWritable(row);  
  28.             KeyValue kvProtocol = new KeyValue(row, "PROTOCOLID".getBytes(), "PROTOCOLID".getBytes(), values[1]  
  29.                     .getBytes());  
  30.             context.write(k, kvProtocol);  
  31.   
  32.             // KeyValue kvSrcip = new KeyValue(row, "SRCIP".getBytes(),  
  33.             // "SRCIP".getBytes(), values[1].getBytes());  
  34.             // context.write(k, kvSrcip);  
  35. //           HFileOutputFormat.getRecordWriter   
  36.         }  
  37.   
  38.     }  
  39.   
  40.     public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {  
  41.         Configuration conf = HBaseConfiguration.create();  
  42.         Job job = new Job(conf, "TestHFileToHBase");  
  43.         job.setJarByClass(TestHFileToHBase.class);  
  44.   
  45.         job.setOutputKeyClass(ImmutableBytesWritable.class);  
  46.         job.setOutputValueClass(KeyValue.class);  
  47.   
  48.         job.setMapperClass(TestHFileToHBaseMapper.class);  
  49.         job.setReducerClass(KeyValueSortReducer.class);  
  50. //      job.setOutputFormatClass(org.apache.hadoop.hbase.mapreduce.HFileOutputFormat.class);  
  51.         job.setOutputFormatClass(HFileOutputFormat.class);  
  52.         // job.setNumReduceTasks(4);  
  53.         // job.setPartitionerClass(org.apache.hadoop.hbase.mapreduce.SimpleTotalOrderPartitioner.class);  
  54.   
  55.         // HBaseAdmin admin = new HBaseAdmin(conf);  
  56. //      HTable table = new HTable(conf, "hua");  
  57.   
  58.          HFileOutputFormat.configureIncrementalLoad(job, table);  
  59.   
  60.         FileInputFormat.addInputPath(job, new Path(args[0]));  
  61.         FileOutputFormat.setOutputPath(job, new Path(args[1]));  
  62.   
  63.         System.exit(job.waitForCompletion(true) ? 0 : 1);  
  64.     }  
  65.   
  66. }  


二、改进后的HFileOutputFormat

源码中的HFileOutputFormat只适合一次生成一个列族的HFile,改进后的HFileOutputFormat适合同时多列族生成HFile文件。有add标签的是在源码上添加代码,有revise标签的是在源码上增加代码。参考:https://review.cloudera.org/r/1272/diff/1/?file=17977#file17977line93

[java]  view plain  copy
  1. /** 
  2.  * Copyright 2009 The Apache Software Foundation 
  3.  * 
  4.  * Licensed to the Apache Software Foundation (ASF) under one 
  5.  * or more contributor license agreements.  See the NOTICE file 
  6.  * distributed with this work for additional information 
  7.  * regarding copyright ownership.  The ASF licenses this file 
  8.  * to you under the Apache License, Version 2.0 (the 
  9.  * "License"); you may not use this file except in compliance 
  10.  * with the License.  You may obtain a copy of the License at 
  11.  * 
  12.  *     http://www.apache.org/licenses/LICENSE-2.0 
  13.  * 
  14.  * Unless required by applicable law or agreed to in writing, software 
  15.  * distributed under the License is distributed on an "AS IS" BASIS, 
  16.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  17.  * See the License for the specific language governing permissions and 
  18.  * limitations under the License. 
  19.  */  
  20. package insert.tools.hfile;  
  21.   
  22. import java.io.IOException;  
  23. import java.net.URI;  
  24. import java.net.URISyntaxException;  
  25. import java.util.ArrayList;  
  26. import java.util.List;  
  27. import java.util.Map;  
  28. import java.util.TreeMap;  
  29. import java.util.TreeSet;  
  30.   
  31. import org.apache.hadoop.conf.Configuration;  
  32. import org.apache.hadoop.filecache.DistributedCache;  
  33. import org.apache.hadoop.fs.FileSystem;  
  34. import org.apache.hadoop.fs.Path;  
  35. import org.apache.hadoop.hbase.HConstants;  
  36. import org.apache.hadoop.hbase.KeyValue;  
  37. import org.apache.hadoop.hbase.client.HTable;  
  38. import org.apache.hadoop.hbase.client.Put;  
  39. import org.apache.hadoop.hbase.io.ImmutableBytesWritable;  
  40. import org.apache.hadoop.hbase.io.hfile.Compression;  
  41. import org.apache.hadoop.hbase.io.hfile.HFile;  
  42. import org.apache.hadoop.hbase.mapreduce.KeyValueSortReducer;  
  43. import org.apache.hadoop.hbase.mapreduce.hadoopbackport.TotalOrderPartitioner;  
  44. import org.apache.hadoop.hbase.regionserver.StoreFile;  
  45. import org.apache.hadoop.hbase.util.Bytes;  
  46. import org.apache.hadoop.io.NullWritable;  
  47. import org.apache.hadoop.io.SequenceFile;  
  48. import org.apache.hadoop.mapreduce.Job;  
  49. import org.apache.hadoop.mapreduce.RecordWriter;  
  50. import org.apache.hadoop.mapreduce.TaskAttemptContext;  
  51. import org.apache.hadoop.mapreduce.lib.output.FileOutputCommitter;  
  52. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
  53.   
  54. import org.apache.commons.logging.Log;  
  55. import org.apache.commons.logging.LogFactory;  
  56.   
  57. import com.google.common.base.Preconditions;  
  58.   
  59. /** 
  60.  * Writes HFiles. Passed KeyValues must arrive in order. Currently, can only 
  61.  * write files to a single column family at a time. Multiple column families 
  62.  * requires coordinating keys cross family. Writes current time as the sequence 
  63.  * id for the file. Sets the major compacted attribute on created hfiles. 
  64.  *  
  65.  * @see KeyValueSortReducer 
  66.  */  
  67. public class HFileOutputFormat extends  
  68.         FileOutputFormat {  
  69.     static Log LOG = LogFactory.getLog(HFileOutputFormat.class);  
  70.   
  71.     public RecordWriter getRecordWriter(  
  72.             final TaskAttemptContext context) throws IOException,  
  73.             InterruptedException {  
  74.         // Get the path of the temporary output file  
  75.         final Path outputPath = FileOutputFormat.getOutputPath(context);  
  76.         final Path outputdir = new FileOutputCommitter(outputPath, context)  
  77.                 .getWorkPath();  
  78.         Configuration conf = context.getConfiguration();  
  79.         final FileSystem fs = outputdir.getFileSystem(conf);  
  80.         // These configs. are from hbase-*.xml  
  81.         // revise  
  82.         // final long maxsize = conf.getLong("hbase.hregion.max.filesize",  
  83.         // 268435456);  
  84.         // final int blocksize = conf.getInt("hfile.min.blocksize.size", 65536);  
  85.         final long maxsize = conf.getLong("hbase.hregion.max.filesize",  
  86.                 HConstants.DEFAULT_MAX_FILE_SIZE);  
  87.         final int blocksize = conf.getInt("hfile.min.blocksize.size",  
  88.                 HFile.DEFAULT_BLOCKSIZE);  
  89.         // -revise  
  90.   
  91.         // Invented config. Add to hbase-*.xml if other than default  
  92.         // compression.  
  93.         final String compression = conf.get("hfile.compression",  
  94.                 Compression.Algorithm.NONE.getName());  
  95.   
  96.         return new RecordWriter() {  
  97.             // Map of families to writers and how much has been output on the  
  98.             // writer.  
  99.             private final Map<byte[], WriterLength> writers = new TreeMap<byte[], WriterLength>(  
  100.                     Bytes.BYTES_COMPARATOR);  
  101.             private byte[] previousRow = HConstants.EMPTY_BYTE_ARRAY;  
  102.             private final byte[] now = Bytes  
  103.                     .toBytes(System.currentTimeMillis());  
  104.             // add  
  105.             private boolean rollRequested = false;  
  106.   
  107.             // -add  
  108.   
  109.             public void write(ImmutableBytesWritable row, KeyValue kv)  
  110.                     throws IOException {  
  111.                 // add  
  112.                 // null input == user explicitly wants to flush  
  113.                 if (row == null && kv == null) {  
  114.                     rollWriters();  
  115.                     return;  
  116.                 }  
  117.                 byte[] rowKey = kv.getRow();  
  118.                 // -add  
  119.   
  120.                 long length = kv.getLength();  
  121.                 byte[] family = kv.getFamily();  
  122.                 WriterLength wl = this.writers.get(family);  
  123.                 // revise  
  124.                 // if (wl == null  
  125.                 // || ((length + wl.written) >= maxsize)  
  126.                 // && Bytes.compareTo(this.previousRow, 0,  
  127.                 // this.previousRow.length, kv.getBuffer(), kv  
  128.                 // .getRowOffset(), kv.getRowLength()) != 0) {  
  129.                 // // Get a new writer.  
  130.                 // Path basedir = new Path(outputdir, Bytes.toString(family));  
  131.                 // if (wl == null) {  
  132.                 // wl = new WriterLength();  
  133.                 // this.writers.put(family, wl);  
  134.                 // if (this.writers.size() > 1)  
  135.                 // throw new IOException("One family only");  
  136.                 // // If wl == null, first file in family. Ensure family  
  137.                 // // dir exits.  
  138.                 // if (!fs.exists(basedir))  
  139.                 // fs.mkdirs(basedir);  
  140.                 // }  
  141.                 // wl.writer = getNewWriter(wl.writer, basedir);  
  142.                 // LOG  
  143.                 // .info("Writer="  
  144.                 // + wl.writer.getPath()  
  145.                 // + ((wl.written == 0) ? "" : ", wrote="  
  146.                 // + wl.written));  
  147.                 // wl.written = 0;  
  148.                 // }  
  149.   
  150.                 // If this is a new column family, verify that the directory  
  151.                 // exists  
  152.                 if (wl == null) {  
  153.                     fs.mkdirs(new Path(outputdir, Bytes.toString(family)));  
  154.                 }  
  155.                 // If any of the HFiles for the column families has reached  
  156.                 // maxsize, we need to roll all the writers  
  157.                 if (wl != null && wl.written + length >= maxsize) {  
  158.                     this.rollRequested = true;  
  159.                 }  
  160.                 // This can only happen once a row is finished though  
  161.                 if (rollRequested  
  162.                         && Bytes.compareTo(this.previousRow, rowKey) != 0) {  
  163.                     rollWriters();  
  164.                 }  
  165.                 // create a new HLog writer, if necessary  
  166.                 if (wl == null || wl.writer == null) {  
  167.                     wl = getNewWriter(family);  
  168.                 }  
  169.                 // we now have the proper HLog writer. full steam ahead  
  170.   
  171.                 // -revise  
  172.   
  173.                 kv.updateLatestStamp(this.now);  
  174.                 wl.writer.append(kv);  
  175.                 wl.written += length;  
  176.                 // Copy the row so we know when a row transition.  
  177.                 // revise  
  178.                 // this.previousRow = kv.getRow();  
  179.                 this.previousRow = rowKey;  
  180.                 // -revise  
  181.             }  
  182.   
  183.             // revise  
  184.             // /*  
  185.             // * Create a new HFile.Writer. Close current if there is one.  
  186.             // *  
  187.             // * @param writer  
  188.             // *  
  189.             // * @param familydir  
  190.             // *  
  191.             // * @return A new HFile.Writer.  
  192.             // *  
  193.             // * @throws IOException  
  194.             // */  
  195.             // private HFile.Writer getNewWriter(final HFile.Writer writer,  
  196.             // final Path familydir) throws IOException {  
  197.             // close(writer);  
  198.             // return new HFile.Writer(fs, StoreFile.getUniqueFile(fs,  
  199.             // familydir), blocksize, compression,  
  200.             // KeyValue.KEY_COMPARATOR);  
  201.             // }  
  202.             private void rollWriters() throws IOException {  
  203.                 for (WriterLength wl : this.writers.values()) {  
  204.                     if (wl.writer != null) {  
  205.                         LOG.info("Writer="  
  206.                                 + wl.writer.getPath()  
  207.                                 + ((wl.written == 0) ? "" : ", wrote="  
  208.                                         + wl.written));  
  209.                         close(wl.writer);  
  210.                     }  
  211.                     wl.writer = null;  
  212.                     wl.written = 0;  
  213.                 }  
  214.                 this.rollRequested = false;  
  215.             }  
  216.   
  217.             /* 
  218.              * Create a new HFile.Writer. 
  219.              *  
  220.              * @param family 
  221.              *  
  222.              * @return A WriterLength, containing a new HFile.Writer. 
  223.              *  
  224.              * @throws IOException 
  225.              */  
  226.             private WriterLength getNewWriter(byte[] family) throws IOException {  
  227.                 WriterLength wl = new WriterLength();  
  228.                 Path familydir = new Path(outputdir, Bytes.toString(family));  
  229.                 wl.writer = new HFile.Writer(fs, StoreFile.getUniqueFile(fs,  
  230.                         familydir), blocksize, compression,  
  231.                         KeyValue.KEY_COMPARATOR);  
  232.                 this.writers.put(family, wl);  
  233.                 return wl;  
  234.             }  
  235.   
  236.             // -revise  
  237.   
  238.             private void close(final HFile.Writer w) throws IOException {  
  239.                 if (w != null) {  
  240.                     w.appendFileInfo(StoreFile.BULKLOAD_TIME_KEY, Bytes  
  241.                             .toBytes(System.currentTimeMillis()));  
  242.                     w.appendFileInfo(StoreFile.BULKLOAD_TASK_KEY, Bytes  
  243.                             .toBytes(context.getTaskAttemptID().toString()));  
  244.                     w.appendFileInfo(StoreFile.MAJOR_COMPACTION_KEY, Bytes  
  245.                             .toBytes(true));  
  246.                     w.close();  
  247.                 }  
  248.             }  
  249.   
  250.             // revise  
  251.             // public void close(TaskAttemptContext c) throws IOException,  
  252.             // InterruptedException {  
  253.             // for (Map.Entry e : this.writers  
  254.             // .entrySet()) {  
  255.             // close(e.getValue().writer);  
  256.             // }  
  257.             // }  
  258.             public void close(TaskAttemptContext c) throws IOException,  
  259.                     InterruptedException {  
  260.                 for (WriterLength wl : this.writers.values()) {  
  261.                     close(wl.writer);  
  262.                 }  
  263.             }  
  264.             // -revise  
  265.         };  
  266.     }  
  267.   
  268.     /* 
  269.      * Data structure to hold a Writer and amount of data written on it. 
  270.      */  
  271.     static class WriterLength {  
  272.         long written = 0;  
  273.         HFile.Writer writer = null;  
  274.     }  
  275.   
  276.     /** 
  277.      * Return the start keys of all of the regions in this table, as a list of 
  278.      * ImmutableBytesWritable. 
  279.      */  
  280.     private static List getRegionStartKeys(HTable table)  
  281.             throws IOException {  
  282.         byte[][] byteKeys = table.getStartKeys();  
  283.         ArrayList ret = new ArrayList(  
  284.                 byteKeys.length);  
  285.         for (byte[] byteKey : byteKeys) {  
  286.             ret.add(new ImmutableBytesWritable(byteKey));  
  287.         }  
  288.         return ret;  
  289.     }  
  290.   
  291.     /** 
  292.      * Write out a SequenceFile that can be read by TotalOrderPartitioner that 
  293.      * contains the split points in startKeys. 
  294.      *  
  295.      * @param partitionsPath 
  296.      *            output path for SequenceFile 
  297.      * @param startKeys 
  298.      *            the region start keys 
  299.      */  
  300.     private static void writePartitions(Configuration conf,  
  301.             Path partitionsPath, List startKeys)  
  302.             throws IOException {  
  303.         Preconditions.checkArgument(!startKeys.isEmpty(), "No regions passed");  
  304.   
  305.         // We're generating a list of split points, and we don't ever  
  306.         // have keys < the first region (which has an empty start key)  
  307.         // so we need to remove it. Otherwise we would end up with an  
  308.         // empty reducer with index 0  
  309.         TreeSet sorted = new TreeSet(  
  310.                 startKeys);  
  311.   
  312.         ImmutableBytesWritable first = sorted.first();  
  313.         Preconditions  
  314.                 .checkArgument(  
  315.                         first.equals(HConstants.EMPTY_BYTE_ARRAY),  
  316.                         "First region of table should have empty start key. Instead has: %s",  
  317.                         Bytes.toStringBinary(first.get()));  
  318.         sorted.remove(first);  
  319.   
  320.         // Write the actual file  
  321.         FileSystem fs = partitionsPath.getFileSystem(conf);  
  322.         SequenceFile.Writer writer = SequenceFile.createWriter(fs, conf,  
  323.                 partitionsPath, ImmutableBytesWritable.class,  
  324.                 NullWritable.class);  
  325.   
  326.         try {  
  327.             for (ImmutableBytesWritable startKey : sorted) {  
  328.                 writer.append(startKey, NullWritable.get());  
  329.             }  
  330.         } finally {  
  331.             writer.close();  
  332.         }  
  333.     }  
  334.   
  335.     /** 
  336.      * Configure a MapReduce Job to perform an incremental load into the given 
  337.      * table. This 
  338.      *  
  339.  
  340.      *  
  341. Inspects the table to configure a total order partitioner 
  342.      *  
  343. Uploads the partitions file to the cluster and adds it to the 
  344.      * DistributedCache 
  345.      *  
  346. Sets the number of reduce tasks to match the current number of 
  347.      * regions 
  348.      *  
  349. Sets the output key/value class to match HFileOutputFormat's 
  350.      * requirements 
  351.      *  
  352. Sets the reducer up to perform the appropriate sorting (either 
  353.      * KeyValueSortReducer or PutSortReducer) 
  354.      *  
  355.  
  356.      * The user should be sure to set the map output value class to either 
  357.      * KeyValue or Put before running this function. 
  358.      */  
  359.     public static void configureIncrementalLoad(Job job, HTable table)  
  360.             throws IOException {  
  361.         Configuration conf = job.getConfiguration();  
  362.         job.setPartitionerClass(TotalOrderPartitioner.class);  
  363.         job.setOutputKeyClass(ImmutableBytesWritable.class);  
  364.         job.setOutputValueClass(KeyValue.class);  
  365.         job.setOutputFormatClass(HFileOutputFormat.class);  
  366.   
  367.         // Based on the configured map output class, set the correct reducer to  
  368.         // properly  
  369.         // sort the incoming values.  
  370.         // TODO it would be nice to pick one or the other of these formats.  
  371.         if (KeyValue.class.equals(job.getMapOutputValueClass())) {  
  372.             job.setReducerClass(KeyValueSortReducer.class);  
  373.         } else if (Put.class.equals(job.getMapOutputValueClass())) {  
  374.             job.setReducerClass(PutSortReducer.class);  
  375.         } else {  
  376.             LOG.warn("Unknown map output value type:"  
  377.                     + job.getMapOutputValueClass());  
  378.         }  
  379.   
  380.         LOG.info("Looking up current regions for table " + table);  
  381.         List startKeys = getRegionStartKeys(table);  
  382.         LOG.info("Configuring " + startKeys.size() + " reduce partitions "  
  383.                 + "to match current region count");  
  384.         job.setNumReduceTasks(startKeys.size());  
  385.   
  386.         Path partitionsPath = new Path(job.getWorkingDirectory(), "partitions_"  
  387.                 + System.currentTimeMillis());  
  388.         LOG.info("Writing partition information to " + partitionsPath);  
  389.   
  390.         FileSystem fs = partitionsPath.getFileSystem(conf);  
  391.         writePartitions(conf, partitionsPath, startKeys);  
  392.         partitionsPath.makeQualified(fs);  
  393.         URI cacheUri;  
  394.         try {  
  395.             cacheUri = new URI(partitionsPath.toString() + "#"  
  396.                     + TotalOrderPartitioner.DEFAULT_PATH);  
  397.         } catch (URISyntaxException e) {  
  398.             throw new IOException(e);  
  399.         }  
  400.         DistributedCache.addCacheFile(cacheUri, conf);  
  401.         DistributedCache.createSymlink(conf);  
  402.   
  403.         LOG.info("Incremental table output configured.");  
  404.     }  
  405.   
  406. }  


三、MR生成HFile的注意事项

1. 无论是map还是reduce作为最终的输出结果,输出的key和value的类型应该是: 或者< ImmutableBytesWritable, Put>。

2. Map或者reduce的输出类型是KeyValue 或Put对应KeyValueSortReducer或PutSortReducer。

3. MR例子中job.setOutputFormatClass(HFileOutputFormat.class); HFileOutputFormat是改进后的mr,可适用于多列族同时生成HFile文件,源码中只适合一次对单列族组织成HFile文件。

4. MR例子中HFileOutputFormat.configureIncrementalLoad(job, table);自动对job进行配置,SimpleTotalOrderPartitioner是需要先对key进行整体排序,然后划分到每个reduce中,保证每一个reducer中的的key最小最大值区间范围,是不会有交集的。

因为入库到HBase的时候,作为一个整体的Region,key是绝对有序的。

5. MR例子中最后生成HFile存储在HDFS上,输出路径下的子目录是各个列族。如果对HFile进行入库HBase,相当于move HFile到HBase的Region中,HFile子目录的列族内容没有了。

四、HFile入库到HBase

[java]  view plain  copy
  1. import org.apache.hadoop.hbase.client.HTable;  
  2. import org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles;  
  3. import org.apache.hadoop.hbase.util.Bytes;  
  4.   
  5. public class TestLoadIncrementalHFileToHBase {  
  6.   
  7.     // private static final byte[] TABLE = Bytes.toBytes("hua");  
  8.     // private static final byte[] QUALIFIER = Bytes.toBytes("PROTOCOLID");  
  9.     // private static final byte[] FAMILY = Bytes.toBytes("PROTOCOLID");  
  10.   
  11.     public static void main(String[] args) throws IOException {  
  12.         Configuration conf = HBaseConfiguration.create();  
  13. //      byte[] TABLE = Bytes.toBytes("hua");  
  14.         byte[] TABLE = Bytes.toBytes(args[0]);  
  15.         HTable table = new HTable(TABLE);  
  16.         LoadIncrementalHFiles loader = new LoadIncrementalHFiles(conf);  
  17.         loader.doBulkLoad(new Path(args[1]), table);  
  18. //      loader.doBulkLoad(new Path("/hua/testHFileResult/"), table);  
  19.     }  
  20.   
  21. }  


五、HFile入库到HBase注意事项

1. 通过HBase中 LoadIncrementalHFiles的doBulkLoad方法,对生成的HFile文件入库,入库的第一个参数是表名,第二个参数是HFile的路径(以上MR生成HFile的输出路径),也可一个个列族录入到HBase中对应的表列族。

2. 如何入库的相关链接:

http://hbase.apache.org/docs/r0.89.20100726/bulk-loads.html

http://hbase.apache.org/docs/r0.20.6/api/org/apache/hadoop/hbase/mapreduce/package-summary.html#bulk

http://genius-bai.javaeye.com/blog/641927

3. 入库分为代码入库以及脚本入库。代码入库有两种,一种是

hadoop jar hbase-VERSION.jar completebulkload /myoutput mytable;

另外一种是通过以上的TestLoadIncrementalHFileToHBase类。

脚本入库为:jruby  $HBASE_HOME/bin/loadtable.rb  hbase-mytable  hadoop-hbase-hfile-outputdir。

最后

以上就是调皮红酒为你收集整理的MR生成HFile文件的全部内容,希望文章能够帮你解决MR生成HFile文件所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(34)

评论列表共有 0 条评论

立即
投稿
返回
顶部