HBase学习笔记 (二)

二、 HBase深入使用


HBase学习笔记 (二)



1.HBase数据检索流程讲解

HBase学习笔记 (二)

图中有瑕疵,实际上一个regionserver一个Hlog。

一个列簇一个store。

HFilehdfs file。


hbase表的检索流程:

HBase学习笔记 (二)

通过regionserver找到region。

 

命名空间(数据库):

HBase学习笔记 (二)

HBase学习笔记 (二)

user表时自己创建的用户表。

 

每个表的region信息存在meta表中:

HBase学习笔记 (二)

HBase学习笔记 (二)

HBase学习笔记 (二) 

meta表也需要存储在region中,被某个regionserver管理。可在zookeeper中查看:

HBase学习笔记 (二) 

其他reginserver的位置:

HBase学习笔记 (二)

一个regionserver一个目录,后面的数字是启动的时间。



2.  深入HBase数据存储讲解

 HBase学习笔记 (二)

HBase学习笔记 (二)

(一个列簇一个store)

HBase学习笔记 (二)

(这个文件是二进制字节数组)


HBase数据存储:

HBase学习笔记 (二)


HregionServer

HBase学习笔记 (二)


StoreFile合并:

HBase学习笔记 (二)

小文件合并,如果文件超过设定的大小就分割。

 

用户写入数据的流程:

HBase学习笔记 (二)


Hlog文件结构:

HBase学习笔记 (二) 


3.  HBase Java API使用讲解


将配置文件拷贝到resources

HBase学习笔记 (二) 


HbaseTest.java(HBase表的创建、删除;对表中数据的添加、获取)

publicclass HbaseTest {

 

    public Connection connection;

    // hbaseconfiguration初始化配置信息时会自动加载当前应用classpath下的core-site.xmlhdfs-site.xmlhbase-site.xml

    // 其实创建connection时,查看源码可发现已加载了上述配置文件,所以这一步可省略

    publicstatic Configuration configuration = HBaseConfiguration.create();

    public Table table;

    public Admin admin;

 

    public HbaseTest() throws IOException {

       // 手动设置加载的配置信息

       // configuration.addResource("hbaseaaa.xml");

       // connection初始化

       connection = ConnectionFactory.createConnection();

       admin = connection.getAdmin();

    }

 

    publicvoid createTable(String tablename, String... cf1) throws IOException {

       // 创建HTableDescriptor对象,描述表信息

       // 创建tablename对象描述表的名称

       TableName tname = TableName.valueOf(tablename);

       HTableDescriptor tDescriptor = new HTableDescriptor(tname);

       // 判断是否表已存在

       if (admin.tableExists(tname)) {

           System.out.println("" + tablename + "已存在");

           return;

       }

       // 添加表列簇信息

       for (String cf : cf1) {

           HColumnDescriptor family = new HColumnDescriptor(cf);

           tDescriptor.addFamily(family);

       }

 

       // 调用admincreateTable方法创建表

       admin.createTable(tDescriptor);

       System.out.println("" + tablename + "创建成功");

    }

 

    publicvoid deleteTable(String tablename) throws IOException {

       Admin admin = connection.getAdmin();

       TableName tname = TableName.valueOf(tablename);

       if (!admin.tableExists(tname)) {

           System.out.println("" + tablename + "不存在");

           return;

       }

       // 停止使用该表

       admin.disableTable(tname);

       admin.deleteTable(tname);

       System.out.println("" + tablename + "删除成功");

    }

 

    // 新增数据到表里面 put

    publicvoid putData() throws IOException {

       TableName tableName = TableName.valueOf("bd18:fromjava");

       Table table = connection.getTable(tableName);

       Random random = new Random();

       List<Put> batPut = new ArrayList();

       for (inti = 0; i < 10; i++) {

           // 构建put的参数是rowkey rowkey_i(Bytes是工具类,各种java基础数据类型和字节数组之间的转换)

           Put put = new Put(Bytes.toBytes("rowkey_" + i));

           put.addColumn(Bytes.toBytes("i"), Bytes.toBytes("username"), Bytes.toBytes("un_" + i));

           put.addColumn(Bytes.toBytes("i"), Bytes.toBytes("age"), Bytes.toBytes(random.nextInt(50) + 1));

           put.addColumn(Bytes.toBytes("i"), Bytes.toBytes("birthday"), Bytes.toBytes("20170" + i + "01"));

           put.addColumn(Bytes.toBytes("i"), Bytes.toBytes("phone"), Bytes.toBytes("电话_" + i));

           put.addColumn(Bytes.toBytes("i"), Bytes.toBytes("email"), Bytes.toBytes("email_" + i));

           // 单记录

           // table.put(put);

           batPut.add(put);

       }

       table.put(batPut);

       System.out.println("表插入数据成功");

 

    }

 

    //get数据

    publicvoid getData() throws Exception{

       TableName tableName = TableName.valueOf("bd18:fromjava");

       table = connection.getTable(tableName);

       //构建get对象

       List<Get> gets = new ArrayList<Get>();

       for(inti=0;i<5;i++){

           Get get = new Get(Bytes.toBytes("rowkey_"+i));

           gets.add(get);

       }

       Result[] results = table.get(gets);

       for (Result result : results) {

           //一行一行读取数据     第一种方法

           /*NavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> maps = result.getMap();

           for(byte[] cf : maps.keySet()){

              NavigableMap<byte[], NavigableMap<Long,byte[]>> valueWritableColumnQualify = maps.get(cf);

              for (byte[] ColumnQualify : valueWritableColumnQualify.keySet()) {

                  NavigableMap<Long, byte[]> valueWritableTimeStamp = valueWritableColumnQualify.get(ColumnQualify);

                  for (long ts : valueWritableTimeStamp.keySet()) {

                     byte[] value = valueWritableTimeStamp.get(ts);

                     System.out.println("rowkey: "+Bytes.toString(result.getRow())+",columnFamliy: "+

                     Bytes.toString(cf)+",columnQualify: "+Bytes.toString(ColumnQualify)+",timestamp: "+

                            new Date(ts)+",value: "+Bytes.toString(value));

                  }

              }

           }*/

       /* 

           //使用字段名和列簇名来获取value    第二种方法

           System.out.println("rowkey: "+Bytes.toString(result.getRow())+",columfamliy:i,columnqualify:username,value: "+

           Bytes.toString(result.getValue(Bytes.toBytes("i"), Bytes.toBytes("username"))));

          

           System.out.println("rowkey: "+Bytes.toString(result.getRow())+",columfamliy:i,columnqualify:username,value: "+

                  Bytes.toInt(result.getValue(Bytes.toBytes("i"), Bytes.toBytes("age"))));*/

 

           // 使用cell获取result里面的数据

           CellScanner cellScanner = result.cellScanner();

           while (cellScanner.advance()) {

              Cell cell = cellScanner.current();

              // 从单元格cell中把数据获取并输出

              // 实用CellUtil工具类,从cell中把数据或群出来

              String famliy = Bytes.toString(CellUtil.cloneFamily(cell));

              String qualify = Bytes.toString(CellUtil.cloneQualifier(cell));

              String rowkey = Bytes.toString(CellUtil.cloneRow(cell));

              String value = Bytes.toString(CellUtil.cloneValue(cell));

              System.out.println(

                     "rowkey: " + rowkey + ",columnqualify:" + famliy + ",qualify: " + qualify + ",value: " + value);

           }

       }

    }

 

    // 关闭连接

    publicvoid cleanUp() throws IOException {

       connection.close();

    }

 

    publicstaticvoid main(String[] args) throws Exception {

       HbaseTest hbaseTest = new HbaseTest();

       //hbaseTest.createTable("bd18:fromjava", "i", "j");

       //hbaseTest.deleteTable("bd18:fromjava");

       //hbaseTest.putData();

       hbaseTest.getData();

       hbaseTest.cleanUp();

    }

}


HBaseScanTest.java(hbase表中读取数据)


publicclass HBaseScanTest {

 

    publicstatic Configuration configuration=HBaseConfiguration.create();

    private Connection connection;

    private Table bd18Test;

   

    public HBaseScanTest() throws IOException {

       connection=ConnectionFactory.createConnection(configuration);

        bd18Test=connection.getTable(TableName.valueOf("bd18:fromjava"));

    }

   

    publicvoid scanData() throws IOException {

      

       Scan scan=new Scan();

       //添加扫描列簇约束,减少扫描列簇数据文件

       scan.addFamily(Bytes.toBytes("i"));

       //[start,stop),如何使stop变成闭区间:转换成二进制,+1

       scan.setStartRow(Bytes.toBytes("rowkey_6"));

       scan.setStopRow(Bytes.toBytes("rowkey_8"));

       scan.addColumn(Bytes.toBytes("i"), Bytes.toBytes("username"));

       //scan.setTimeRange(minStamp, maxStamp);

       ResultScanner rs=bd18Test.getScanner(scan);

       showResult(rs);

    }

   

    //专有过滤器,行健前缀过滤器:PrefixFilter

    //取出

    publicvoid getByPrefixFilter() throws IOException {

       Filter prefixFilter=new PrefixFilter(Bytes.toBytes("Row"));

       Scan scan=new Scan();

       scan.setFilter(prefixFilter);

       ResultScanner rs=bd18Test.getScanner(scan);

       showResult(rs);

    }

   

    //ColumnPrefixFilter,列前缀过滤器,用法同上

    //MultipleColumnPrefixFilter,多子列前缀过滤器

    //DependentColumnFilter,列过滤器,既指定列簇又指定列名称的过滤器

   

   

    //按照姓名查找用户信息

    publicvoid getBySEeachValue() throws IOException {

       Filter valueFilter=new ValueFilter(CompareFilter.CompareOp.EQUAL, new RegexStringComparator("_"));

       Scan scan=new Scan();

       scan.setFilter(valueFilter);

       ResultScanner rs=bd18Test.getScanner(scan);

       showResult(rs);

    }

   

    publicvoid getByColumRangeFilter() throws IOException {

       Filter cRangeFilter=new ColumnRangeFilter(Bytes.toBytes("o_name1"), true, Bytes.toBytes("o_name2"), true);

       Scan scan=new Scan();

       //只扫描j列簇

       scan.addFamily(Bytes.toBytes("j"));

       scan.setFilter(cRangeFilter);

       ResultScanner rs=bd18Test.getScanner(scan);

       showResult(rs);

    }

   

    //qualifyFilter 列名过滤器,只返回能匹配的列名称的单元格数据

    publicvoid getByQualifyFilter() throws IOException {

       Filter qualifyFilter=new QualifierFilter(CompareFilter.CompareOp.EQUAL,new BinaryPrefixComparator(Bytes.toBytes("phone_")));

       Scan scan=new Scan();

       scan.setFilter(qualifyFilter);

       ResultScanner rs=bd18Test.getScanner(scan);

       showResult(rs);

    }

   

    //familyfilter 返回的是设置列簇下面的数据,这个不常用,因为列簇通常只有1-2个。列簇可以

    //设置多个除非HBase优化,在缓冲区将数据刷新到HFile时,不连带其他HStore的缓冲区

    publicvoid getByFamilyFilter() throws Exception{

       FamilyFilter familyFilter = new FamilyFilter(CompareFilter.CompareOp.LESS, new BinaryComparator(Bytes.toBytes("j")));

        Scan scan = new Scan();

        scan.setFilter(familyFilter);

        ResultScanner rs = bd18Test.getScanner(scan);

        showResult(rs);

    }

   

   

    //rowfilter

    //获取rowkey中包含rowkey中包含"row"的数据

    publicvoid getByRowFilter() throws IOException {

       Scan scan=new Scan();

//     //rowkey中包含row这个字符串的的都会获取到

//     RowFilter rowFilter=new RowFilter(CompareFilter.CompareOp.EQUAL,new RegexStringComparator("row"));

//     //把过滤器加到scan

//     scan.setFilter(rowFilter);

//     //scan加入到table上进行扫描获取resultscanner结果

//     ResultScanner rs=bd18Test.getScanner(scan);

//     showResult(rs);

      

       //获取rowKey<=rowkey_5并包含rowkey_5

       RowFilter ItRowFilter=new RowFilter(CompareFilter.CompareOp.LESS_OR_EQUAL,new BinaryComparator(Bytes.toBytes("rowkey_5")));

       scan.setFilter(ItRowFilter);

       ResultScanner rs=bd18Test.getScanner(scan);

       showResult(rs);

    }

   

    //FilterList,组合过滤器

    //查询rowkey包含n_6,且电话是以135开头的数据

    publicvoid getByFilterList() throws IOException {

       List<Filter> flist=new ArrayList();

       //第一个条件:rowkey包含n_6

       Filter filter1=new RowFilter(CompareOp.EQUAL,new RegexStringComparator("_6"));

       flist.add(filter1);

       //第二个条件:电话是以155开头

       Filter filter2=new ColumnPrefixFilter(Bytes.toBytes("phone_155"));

       flist.add(filter2);

       //组装两个filter,关系为''

       Filter filter=new FilterList(Operator.MUST_PASS_ONE,flist);

       Scan scan=new Scan();

       scan.setFilter(filter);

       ResultScanner rs=bd18Test.getScanner(scan);

       showResult(rs);

    }  

   

    publicvoid showResult(ResultScanner rs) throws IOException {

       Result result=rs.next();

       while(result!=null) {

           //result中的数据进行展示

           CellScanner cs=result.cellScanner();

           System.out.println("rowkey:"+Bytes.toString(result.getRow()));

           while(cs.advance()) {

              Cell cell=cs.current();

              String family=Bytes.toString(CellUtil.cloneFamily(cell));

              String qualify=Bytes.toString(CellUtil.cloneQualifier(cell));

              String value=Bytes.toString(CellUtil.cloneValue(cell));

              System.out.println("     cf:"+family+",qualify:"+qualify+",value:"+value);

             

           }

           result=rs.next();

       }

    }

   

    publicstaticvoid main(String[] args) throws Exception {

       HBaseScanTest hBaseScanTest=new HBaseScanTest();

       //hBaseScanTest.scanData();

       //hBaseScanTest.getByRowFilter();

       //hBaseScanTest.getByFamilyFilter();

       //hBaseScanTest.getByQualifyFilter();

       //hBaseScanTest.getByColumRangeFilter();

       //hBaseScanTest.getBySEeachValue();

       //hBaseScanTest.getByPrefixFilter();

       hBaseScanTest.getByFilterList();

    }

} 


配置文件的加载:

HBase学习笔记 (二)

HBase学习笔记 (二)


将内存中的数据flushstorefile中:

HBase学习笔记 (二)

这时候数据还在内存中,即memstore中,还没溢写到stroefile中,这时候可以手动将内存中的数据写到storefile中:

HBase学习笔记 (二)

HBase学习笔记 (二)

HBase学习笔记 (二)

HBase学习笔记 (二)


删除操作:

  publicvoid deleteData(String tableName) throws IOException {

       Table table = getHTableByTableName(tableName);

 

       // hBaseOperation.getData(tableName);

      

       Delete delete=new Delete(Bytes.toBytes("10004"));

      

       // delete.addColumns删除该列的所有版本

       // 删除该列的最新版本

       delete.addColumn(

              Bytes.toBytes("info"),

              Bytes.toBytes("address")

       );

        // delete.addFamily(Bytes.toBytes("info")); //删除一个rowkey的一个列簇

        table.delete(delete);

        table.close();

    }

删除,其实并未删除,只是打上标签,在storefile合并时才会删除。

合并前:

HBase学习笔记 (二) 合并后:

HBase学习笔记 (二)

HBase学习笔记 (二)

HBase学习笔记 (二)

compact文件的选择首先要判断是major还是minor,如果是major,则整个HStore的所有HFile都被选中,否则就选择部分文件进行minor compact。考虑到compact操作都会耗费大量的IO,因此minorcompact操作的目标就是以最少的IO代价换取最大的读性能提高。目前在新版本里,HStorecompact文件选择策略能够充分考虑了整体情况去选择最佳的方案。


查看所有的Filter

HBase学习笔记 (二)

比较重要的就是prefixFilterPageFilter。

MRHbaseScan使用技巧:
HadoopMR运算中,Hbase可以作为输入数据源参与运算,其中作为HTable的迭代器Scan有几个使用技巧。

涉及的方法如下:
public void setBatch(int batch)
public void setCaching(int caching)
public void setCacheBlocks(boolean cacheBlocks)

public void setBatch(int batch)

为设置获取记录的列个数,默认无限制,也就是返回所有的列

public void setCaching(int caching)

每次从服务器端读取的行数,默认为配置文件中设置的值

public void setCacheBlocks(boolean cacheBlocks)

为是否缓存块,默认缓存,我们分内存,缓存和磁盘,三种方式,一般数据的读取为内存->缓存->磁盘,当MR的时候为非热点数据,因此不需要缓存。

因此在MR的时候最好设置如下:
scan.setCacheBlocks(false);
scan.setCaching(200);//
大了占内存,但是rpc
scan.setBatch(6);//
你需要的列



4.  HBase 架构深入剖析讲解


HBase学习笔记 (二)

HBase学习笔记 (二) hadoop底层就是rpc协议。


HBase学习笔记 (二)

没有单节点故障,就是因为zookeeper。

hbase表的元数据可在zkCli.sh中查看。

ROOT表是老版本的概念,新版本的是meta表。

HBase学习笔记 (二)


启动多个master

HBase学习笔记 (二)

查看hbase-daemons.sh脚本:

HBase学习笔记 (二)

HBase学习笔记 (二)

查看master-backup.sh脚本:

HBase学习笔记 (二)

HBase学习笔记 (二)

创建backup-masters文件:

HBase学习笔记 (二)

执行脚本:

[[email protected]]# bin/hbase-daemons.sh start master-backup

HBase学习笔记 (二)


管理HregionServer的负载均衡等:

tools工作组都是Hmaster的工作

HBase学习笔记 (二)

HBase学习笔记 (二)

HBase学习笔记 (二)

图中HMasterHDFS的箭头:

HBase学习笔记 (二)

这些region信息都是Hmaster写到HDFS上的。

 

默认情况下,HBase管理Zookeeper实例,实际生产环境不让他管理,通过以下配置:

hbase-env.sh

HBase学习笔记 (二)

设置为false,并在hbase-site.xml中添加自己安装的zookeeper的信息。

 

谷歌的三篇论文(三驾马车):

GFSMapReduceBigTable

java开源出来的:

HDFSMapReduceHBase

其中BigTable中有个协作框架,开源出来就是Zookeeper

 


5. HBase集成MapReduce时, 运行的classpath以及自带mr程序的功能讲解


hbasemapreduce的集成:

1. 输入表是hbase

2. 输出表是hbase

3. 输入输出都是hbase

HBase学习笔记 (二) 

java代码打成jar包是不打包依赖的,如下图:

HBase学习笔记 (二)

HBase学习笔记 (二)

但是bin/yarn jar这个命令会自动帮我们加载依赖。


运行hbase代码打成的jar包时,需要加载hbase的依赖:

查看jar包的相关命令:

HBase学习笔记 (二)

HBase学习笔记 (二)

······

HBase学习笔记 (二)


执行hbase jar包中的rowcounter程序:

HBase学习笔记 (二)

(这个jar包中封装了很多工具类)

 

[[email protected] hbase-1.2.0-cdh5.13.0]#/opt/cdh5.13.0/hadoop-2.6.0-cdh5.13.0/bin/hadoop jarlib/hbase-server-1.2.0-cdh5.13.0.jar

HBase学习笔记 (二)

(提示找不到类,所以要加载hbase jar包)


加载hbase所需的依赖,并查看jar包包含的工具类:

HBase学习笔记 (二)

export HBASE_HOME=/opt/cdh5.13.0/hbase-1.2.0-cdh5.13.0

export HADOOP_HOME=/opt/cdh5.13.0/hadoop-2.6.0-cdh5.13.0

HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`

$HADOOP_HOME/bin/yarn jar $HBASE_HOME/lib/hbase-server-1.2.0-cdh5.13.0.jar


如果运行失败,将后两句放在一起执行:HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`  $HADOOP_HOME/bin/yarn jar$HBASE_HOME/lib/hbase-server-1.2.0-cdh5.13.0.jar


completebulkload

默认的方式:每条数据要经过:预写日志,memstoreflush storeFilecompactregion。最终形成hfile

采用completebulkload

HBase学习笔记 (二)

  

TSVCSV的区别:

HBase学习笔记 (二)

 

查看工具类的可加参数:

HBase学习笔记 (二)

 

使用rowcounter计算user表的行数:

HBase学习笔记 (二)

HBase学习笔记 (二)

HBase学习笔记 (二)

HBase学习笔记 (二)



6. 依据实际需求编写MapReduce程序, 集成HBase对表进行读取和写入数据


参考:

HBase学习笔记 (二)


user表中的nameage列导入到basic表中:

HBase学习笔记 (二) 

User2BasicMapReduce.java

准备工作:

HBase学习笔记 (二)


publicclass User2BasicMapReduce extends Configured implements Tool{

 

    // Mapper Class

    publicstaticclass ReadUserMapper extends TableMapper<Text, Put>{

      

       private Text mapOutPutKey=new Text();

      

       @Override

       publicvoid map(ImmutableBytesWritable key, Result value,

              Mapper<ImmutableBytesWritable, Result, Text, Put>.Context context)

              throws IOException, InterruptedException {

           // get rowkey

           String rowkey=Bytes.toString(key.get());

           // set

           mapOutPutKey.set(rowkey);

           //---------------------------------------------------------

           Put put = new Put(key.get());

           // iterator

           for(Cell cell : value.rawCells()) {

              // add family : info

               if("info".equals(Bytes.toString(CellUtil.cloneFamily(cell)))){

                  // add column : name

                  if("name".equals(Bytes.toString(CellUtil.cloneQualifier(cell)))) {

                     put.add(cell);

                  }

              }

              // add family : info

               if("info".equals(Bytes.toString(CellUtil.cloneFamily(cell)))){

                  // add column : age

                  if("age".equals(Bytes.toString(CellUtil.cloneQualifier(cell)))) {

                     put.add(cell);

                  }

              }

           }

           context.write(mapOutPutKeyput);

       }

      

    }

   

    // Rudecer class

    publicstaticclass writeBasicReducer extends TableReducer<Text, Put, NullWritable>{

 

       @Override

       publicvoid reduce(Text key, Iterable<Put> values,

              Reducer<Text, Put, NullWritable, Mutation>.Context context)

              throws IOException, InterruptedException {

           for(Put put : values) {

              context.write(NullWritable.get(), put);

           }

          

       }

      

    }

   

    // Driver

    publicint run(String[] argsthrows Exception {

       // create job

       // Job.getInstance(conf, jobName);

       Job job=Job.getInstance(this.getConf(),this.getClass().getName());

      

       // set run job class

       job.setJarByClass(this.getClass());

      

       // set job

       Scan scan = new Scan();

       // 版本太低的话,执行以下操作会出现没有该方法的异常

       //scan.setCaching(500);        // 1 is the default in Scan, which will be bad for MapReduce jobs

       //scan.setCacheBlocks(false);  // don't set to true for MR jobs

       // set other scan attrs

      

       // set input and set mapper

       TableMapReduceUtil.initTableMapperJob(

         "user",        // input table

         scan,               // Scan instance to control CF and attribute selection

         ReadUserMapper.class,     // mapper class

         Text.class,         // mapper output key

         Put.class,  // mapper output value

         job

       );

      

       // set output and reducer

       TableMapReduceUtil.initTableReducerJob(

         "basic",        // output table

         writeBasicReducer.class,    // reducer class

         job

       );

       job.setNumReduceTasks(1);   // at least one, adjust as required

 

       // submit job

       booleanisSuccess = job.waitForCompletion(true);

      

       returnisSuccess ? 0:1;

    }

 

   

    publicstaticvoid main(String[] argsthrows Exception {

       // get configuration

       Configuration configuration=HBaseConfiguration.create();

 

       // submit job

       intstatus = ToolRunner.run(configurationnew User2BasicMapReduce(), args);

      

       // exit program

       System.out.println(status);

      

    }

}


把配置文件然后打成jar包,上传到linux上,执行:

export HBASE_HOME=/opt/cdh5.13.0/hbase-1.2.0-cdh5.13.0

export HADOOP_HOME=/opt/cdh5.13.0/hadoop-2.6.0-cdh5.13.0

HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`

 

$HADOOP_HOME/bin/yarn jar  /opt/datas/hbase-mr-user2basic.jar


查看basic表:

HBase学习笔记 (二)


查看ToolRunner.run(configuration, new User2BasicMapReduce(), args) 源码:

HBase学习笔记 (二)


细节补充:

HBase学习笔记 (二)

HBase学习笔记 (二)

HBase学习笔记 (二)

HBase学习笔记 (二)


 

7.  HBase 的数据迁移常见方式及importTsv功能演示讲解


HBase学习笔记 (二)

 

数据迁移的三种方式:

HBase学习笔记 (二)

hbase bulk load tool把要加载到hbase表中的数据变成hbase底层的hfile文件,然后把它加载到hbase

HBase学习笔记 (二)

通用:通过jdbc从关系型数据库抽数据,然后puthbase中插入数据。

HBase学习笔记 (二)

HBase学习笔记 (二)


创建样本数据:

student.tsv

10001 zhangsan 35 male   beijing     0108978342

10002 lisi 22 male   shanghai  0108213342

10003 wangwu   28 female     guangzhou    0111178342

10004 zhaoliu    32 male   zhengzhou    0108972222

10005 zengqi     26 female     shijiazhuang 0103538342

10006 gouba 35 male   hangzhou 0109889842

上传到hdfs

HBase学习笔记 (二)


hbase中创建student表:

HBase学习笔记 (二)


执行数据迁移:

export HBASE_HOME=/opt/cdh5.13.0/hbase-1.2.0-cdh5.13.0

export HADOOP_HOME=/opt/cdh5.13.0/hadoop-2.6.0-cdh5.13.0

HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`

 

${HADOOP_HOME}/bin/yarn jar ${HBASE_HOME}/lib/hbase-server-1.2.0-cdh5.13.0.jar importtsv \

-Dimporttsv.columns=HBASE_ROW_KEY,\

info:name,info:age,info:sex,info:address,info:phone \

student \

hdfs://hadoop-senior:8020/user/zhuyu/hbase/importtsv

-Dimporttsv.columns字段之间不能有空格

HBase学习笔记 (二)

HBase学习笔记 (二)

(数据还在memStore中,没有溢写到storeFile)

HBase学习笔记 (二)


命令使用过程:

HBase学习笔记 (二)

HBase学习笔记 (二)

HBase学习笔记 (二)

 

 

8.  如何使用BulkLoad加载数据到HBase表及剖析原理


使用默认的importtsv加载缺点:

HBase学习笔记 (二)

数据还在内存中。

如果我们处理的数据量很大非常耗资源。

 

引出使用BulkLoad加载数据:

HBase学习笔记 (二)

HBase学习笔记 (二)

GC:垃圾回收机制

HBase学习笔记 (二)

HBase学习笔记 (二)

 HBase学习笔记 (二)


实例:

创建hbasestudent2

HBase学习笔记 (二)


执行BulkLoad加载数据成HFile

HBase学习笔记 (二)

export HBASE_HOME=/opt/cdh5.13.0/hbase-1.2.0-cdh5.13.0

export HADOOP_HOME=/opt/cdh5.13.0/hadoop-2.6.0-cdh5.13.0

HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`

{HADOOP_HOME}/bin/yarn jar ${HBASE_HOME}/lib/hbase-server-1.2.0-cdh5.13.0.jar importtsv \

-Dimporttsv.columns=HBASE_ROW_KEY,\

info:name,info:age,info:sex,info:address,info:phone \

-Dimporttsv.bulk.output=/user/zhuyu/hbase/hfileoutput \

student2 \

hdfs://hadoop-senior:8020/user/zhuyu/hbase/importtsv

HBase学习笔记 (二)

HBase学习笔记 (二)

 

HFile加载到hbase表:

export HBASE_HOME=/opt/cdh5.13.0/hbase-1.2.0-cdh5.13.0

export HADOOP_HOME=/opt/cdh5.13.0/hadoop-2.6.0-cdh5.13.0

HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`

${HADOOP_HOME}/bin/yarn jar ${HBASE_HOME}/lib/hbase-server-1.2.0-cdh5.13.0.jar \

completebulkload \

hdfs://hadoop-senior:8020/user/zhuyu/hbase/hfileoutput \

user2

HBase学习笔记 (二)


查看:

HBase学习笔记 (二)

再看生成hfile的文件夹:

HBase学习笔记 (二)

文件已经move到了student2表目录下:

HBase学习笔记 (二)


查看LoadIncrementalHFiles如何使用:

HBase学习笔记 (二)


查看源码:

查看ImportTsv源码:

ctrl+shift+T

HBase学习笔记 (二)

HBase学习笔记 (二)

(是mapreduce)


查看LoadIncrementalHFiles源码:

HBase学习笔记 (二)

(不是mapreduce)

 

使用mapreduce生成HFile

HBase学习笔记 (二)

HBase学习笔记 (二)


作业:

HBase学习笔记 (二)

(csv)