Spark如何读取Hbase特定查询的数据

最近工作需要使用到Spark操作Hbase,上篇文章已经写了如何使用Spark读写Hbase全量表的数据做处理,但这次有所不同,这次的需求是Scan特定的Hbase的数据然后转换成RDD做后续处理,简单的使用Google查询了一下,发现实现方式还是比较简单的,用的还是Hbase的TableInputFormat相关的API。 

基础软件版本如下: 
Java代码   收藏代码
  1. Hadoop2.7.2  
  2. Hbase1.2.0  
  3. Spark2.1.0  
  4. Scala2.11.8  



直接上代码如下: 
Java代码   收藏代码
  1. `           val startRowkey="row1"   
  2.             val endRowkey="row1"  
  3.             //开始rowkey和结束一样代表精确查询某条数据  
  4.   
  5.             //组装scan语句  
  6.             val scan=new Scan(Bytes.toBytes(startRowkey),Bytes.toBytes(endRowkey))  
  7.             scan.setCacheBlocks(false)  
  8.             scan.addFamily(Bytes.toBytes("ks"));  
  9.             scan.addColumn(Bytes.toBytes("ks"), Bytes.toBytes("data"))  
  10.               
  11.             //将scan类转化成string类型  
  12.             val scan_str= TableMapReduceUtil.convertScanToString(scan)  
  13.             conf.set(TableInputFormat.SCAN,scan_str)  
  14.   
  15.             //使用new hadoop api,读取数据,并转成rdd  
  16.             val rdd = sc.newAPIHadoopRDD(conf, classOf[TableInputFormat], classOf[ImmutableBytesWritable], classOf[Result])  
  17.   
  18.              //打印扫描的数据总量  
  19.              println("count:"+rdd.count)  




上面的少量代码,已经完整实现了使用spark查询hbase特定的数据,然后统计出数量最后输出,当然上面只是一个简单的例子,重要的是能把hbase数据转换成RDD,只要转成RDD我们后面就能进行非常多的过滤操作。 


注意上面的hbase版本比较新,如果是比较旧的hbase,如果自定义下面的方法将scan对象给转成字符串,代码如下: 

Java代码   收藏代码
  1. import java.io.{DataOutputStream, ByteArrayOutputStream}  
  2. import java.lang.String  
  3. import org.apache.hadoop.hbase.client.Scan  
  4. import org.apache.hadoop.hbase.HBaseConfiguration  
  5. import org.apache.hadoop.hbase.io.ImmutableBytesWritable  
  6. import org.apache.hadoop.hbase.client.Result  
  7. import org.apache.hadoop.hbase.mapreduce.TableInputFormat  
  8. import org.apache.hadoop.hbase.util.Base64  
  9.   
  10. def convertScanToString(scan: Scan): String = {  
  11.   val out: ByteArrayOutputStream = new ByteArrayOutputStream  
  12.   val dos: DataOutputStream = new DataOutputStream(out)  
  13.   scan.write(dos)  
  14.   Base64.encodeBytes(out.toByteArray)  
  15. }  



最后,还有一点,上面的代码是直接自己new了一个scan对象进行组装,当然我们还可以不自己new对象,全部使用TableInputFormat下面的相关的常量,并赋值,最后执行的时候TableInputFormat会自动帮我们组装scan对象这一点通过看http://www.fhadmin.org/的源码就能明白: 
Java代码   收藏代码
  1. private static final Log LOG = LogFactory.getLog(TableInputFormat.class);  
  2. public static final String INPUT_TABLE = "hbase.mapreduce.inputtable";  
  3. private static final String SPLIT_TABLE = "hbase.mapreduce.splittable";  
  4. public static final String SCAN = "hbase.mapreduce.scan";  
  5. public static final String SCAN_ROW_START = "hbase.mapreduce.scan.row.start";  
  6. public static final String SCAN_ROW_STOP = "hbase.mapreduce.scan.row.stop";  
  7. public static final String SCAN_COLUMN_FAMILY = "hbase.mapreduce.scan.column.family";  
  8. public static final String SCAN_COLUMNS = "hbase.mapreduce.scan.columns";  
  9. public static final String SCAN_TIMESTAMP = "hbase.mapreduce.scan.timestamp";  
  10. public static final String SCAN_TIMERANGE_START = "hbase.mapreduce.scan.timerange.start";  
  11. public static final String SCAN_TIMERANGE_END = "hbase.mapreduce.scan.timerange.end";  
  12. public static final String SCAN_MAXVERSIONS = "hbase.mapreduce.scan.maxversions";  
  13. public static final String SCAN_CACHEBLOCKS = "hbase.mapreduce.scan.cacheblocks";  
  14. public static final String SCAN_CACHEDROWS = "hbase.mapreduce.scan.cachedrows";  
  15. public static final String SCAN_BATCHSIZE = "hbase.mapreduce.scan.batchsize";  
  16. public static final String SHUFFLE_MAPS = "hbase.mapreduce.inputtable.shufflemaps";  



上面代码中的常量,都可以conf.set的时候进行赋值,最后任务运行的时候会自动转换成scan,有兴趣的朋友可以自己尝试。 

你可能感兴趣的:(Spark如何读取Hbase特定查询的数据)