分享

hbase使用需要注意什么问题及hbase如何使用mapreduce插入导出数据

nettman 发表于 2014-3-6 00:50:20 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 9695
本帖最后由 pig2 于 2014-3-6 01:36 编辑
我们是否产生如下问题:hbase使用需要注意什么问题,mapReduce如何操作habse。具体如下
1.HBase如果加了列限定,如果该列不存在时返回的结果为什么?
2.HBase在scan时指定的StartRow里面能否加-?
3.MapReduce如何导出hbase数据?
4.mapReduce如何插入数据到HBase?

加微信w3aboutyun,可拉入技术爱好者群

没找到任何评论,期待你打破沉寂

nettman 发表于 2014-3-6 00:53:00
本帖最后由 pig2 于 2014-3-6 01:36 编辑
1.HBase如果加了列限定,如果该列不存在时返回的结果为empty.

   看下面的代码:
  1.   Get get = new Get(Bytes.toBytes("100"));
  2.     get.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"));
复制代码
这里加入了列限定,也就是只返回列族info下面的name字段。但是如果name字段根本不存在,返回的Result在调用result.isEmpty()时则返回为true,也就是说就算其他字段存在,也什么都没返回来,包括rowkey也没有返回来。当然,如果是限定多个列,只要一个列存在就可以正常返回。所以需要注意。

2.HBase在scan时指定的StartRow里面不能加-

看下面的代码:
  1. Scan scan = new Scan();
  2. scan.setStartRow(Bytes.toBytes("3136947-"));
  3. scan.setStopRow(Bytes.toBytes("3136947-" + 1));
复制代码
我的本意是查询rowkey以 3136947- 开头的行,但是因为我的里面有一个-(“杠”),所以什么都没返回,去掉-后正常。这说明这里是不能使用-,-也并不是转义字符,转义后也还是scan不出来的。不知道其他字符是不是也不行,没有测试。 所以需要注意。

3.HBase在scan时过滤掉指定列不存在的记录

如果想返回某个字段必须存在的行,不存在该字段的记录过滤掉不返回,方法如下:
  1. Scan scan = new Scan();
  2.         scan.setStartRow(Bytes.toBytes("3136947"));
  3.         scan.setStopRow(Bytes.toBytes("3136947" + 1));
  4.         scan.addColumn(Bytes.toBytes("info"),
  5.                 Bytes.toBytes("name"));
  6.         SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("info"),
  7.                 Bytes.toBytes("name"),
  8.                 CompareFilter.CompareOp.NOT_EQUAL, Bytes.toBytes("0"));
  9.         filter.setFilterIfMissing(true);
  10.         scan.setFilter(filter);
复制代码
注意:如果是判断某个列是否存在,必须在addColumn里面加上该列,也就是必须返回的字段里面必须包含该列,否则也不会返回,因为在处理的时候是调用addColumn然后才会调用过滤器。
这里的过滤器里面指定该列的字段值必须不等于0(当然,如果你的name里有等于0的当然不能使用0),并且设置setFilterIfMissing为true,也就是设置为如果该列不存在就过滤掉这条数据,默认为false。


4.利用MapReduce导出hbase数据

如果hbase作为数据的输出,job设置如下:
  1. Configuration conf = HBaseConfiguration.create();
  2.         Scan scan = new Scan();
  3.         scan.setStartRow(Bytes.toBytes("3136947"));
  4.         scan.setStopRow(Bytes.toBytes("3136947" + 1));
  5.         scan.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"));
  6.         scan.addFamily(UserStoreHelper.FAMILY_INFO);
  7.         scan.addColumn(UserStoreHelper.FAMILY_INFO, UserStoreHelper.USER_ID);
  8.         scan.addColumn(UserStoreHelper.FAMILY_INFO, UserStoreHelper.FRIENDS);
  9.         scan.addColumn(UserStoreHelper.FAMILY_INFO, UserStoreHelper.LEVEL_CODE);
  10.         final Job job = new Job(conf, "exportHBaseUser");
  11.         job.setJarByClass(TestJobCreator.class);
  12.         job.setOutputFormatClass(TextOutputFormat.class);
  13.         FileOutputFormat.setOutputPath(job, new Path("test1"));
  14.        // job.setReducerClass(HbaseExportReduce.class);
  15.        // job.setPartitionerClass(UserPartitioner.class);
  16.        // job.setNumReduceTasks(14);
  17.         TableMapReduceUtil.initTableMapperJob(Bytes.toBytes("usertable"),
  18.                 scan,
  19.                 TestMapper.class,
  20.                 Text.class,
  21.                 NullWritable.class,
  22.                 job);
复制代码
在initTableMapperJob里面设置的map必须继承org.apache.hadoop.hbase.mapreduce.TableMapper,并且最后两个设置的参数是自己定义的map的输出时的key和value的类型。

5.利用mapReduce插入数据到HBase

如果hbase作为数据的输入。代码如下:
  1. final Configuration conf = HBaseConfiguration.create();
  2. final Job job = new Job(conf, "Sync-To-HBase");
  3. job.setJarByClass(PostStoreExportHBaseJobCreator.class);
  4.    //我这里是以mongodb为输入     
  5.   job.setInputFormatClass(MongoInputFormat.class);
  6.    TableMapReduceUtil.initTableReducerJob("usertable", null, job);
  7.     //把数据转换为hbase表格式的map
  8.    job.setMapperClass(TestMapper.class);
  9.     //直接入hbase库不需要reduce   
  10.     job.setNumReduceTasks(0);
复制代码
这里map的输出必须是key为ImmutableBytesWritable,value为 Put
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条