本文将分两部分介绍,第一部分讲解使用 HBase 新版 API 进行 CRUD 基本操作;第二部分讲解如何将 Spark 内的 RDDs 写入 HBase 的表中,反之,HBase 中的表又是如何以 RDDs 形式加载进 Spark 内的。

环境配置

为了避免版本不一致带来不必要的麻烦,API 和 HBase环境都是 1.0.0 版本。HBase 为单机模式,分布式模式的使用方法类似,只需要修改HBaseConfiguration的配置即可。

开发环境中使用 SBT 加载依赖项

  1. name := "SparkLearn"
  2.  
  3. version := "1.0"
  4.  
  5. scalaVersion := "2.10.4"
  6.  
  7. libraryDependencies += "org.apache.spark" %% "spark-core" % "1.3.0"
  8.  
  9. libraryDependencies += "org.apache.hbase" % "hbase-client" % "1.0.0"
  10.  
  11. libraryDependencies += "org.apache.hbase" % "hbase-common" % "1.0.0"
  12.  
  13. libraryDependencies += "org.apache.hbase" % "hbase-server" % "1.0.0"

HBase 的 CRUD 操作

新版 API 中加入了 ConnectionHAdmin成了AdminHTable成了Table,而AdminTable只能通过Connection获得。Connection的创建是个重量级的操作,由于Connection是线程安全的,所以推荐使用单例,其工厂方法需要一个HBaseConfiguration

  1. val conf = HBaseConfiguration.create()
  2. conf.set("hbase.zookeeper.property.clientPort", "2181")
  3. conf.set("hbase.zookeeper.quorum", "master")
  4.  
  5. //Connection 的创建是个重量级的工作,线程安全,是操作hbase的入口
  6. val conn = ConnectionFactory.createConnection(conf)

创建表

使用Admin创建和删除表

  1. val userTable = TableName.valueOf("user")
  2.  
  3. //创建 user 表
  4. val tableDescr = new HTableDescriptor(userTable)
  5. tableDescr.addFamily(new HColumnDescriptor("basic".getBytes))
  6. println("Creating table `user`. ")
  7. if (admin.tableExists(userTable)) {
  8. admin.disableTable(userTable)
  9. admin.deleteTable(userTable)
  10. }
  11. admin.createTable(tableDescr)
  12. println("Done!")

插入、查询、扫描、删除操作

HBase 上的操作都需要先创建一个操作对象Put,Get,Delete等,然后调用Table上的相对应的方法

  1. try{
  2. //获取 user 表
  3. val table = conn.getTable(userTable)
  4.  
  5. try{
  6. //准备插入一条 key 为 id001 的数据
  7. val p = new Put("id001".getBytes)
  8. //为put操作指定 column 和 value (以前的 put.add 方法被弃用了)
  9. p.addColumn("basic".getBytes,"name".getBytes, "wuchong".getBytes)
  10. //提交
  11. table.put(p)
  12.  
  13. //查询某条数据
  14. val g = new Get("id001".getBytes)
  15. val result = table.get(g)
  16. val value = Bytes.toString(result.getValue("basic".getBytes,"name".getBytes))
  17. println("GET id001 :"+value)
  18.  
  19. //扫描数据
  20. val s = new Scan()
  21. s.addColumn("basic".getBytes,"name".getBytes)
  22. val scanner = table.getScanner(s)
  23.  
  24. try{
  25. for(r <- scanner){
  26. println("Found row: "+r)
  27. println("Found value: "+Bytes.toString(
  28. r.getValue("basic".getBytes,"name".getBytes)))
  29. }
  30. }finally {
  31. //确保scanner关闭
  32. scanner.close()
  33. }
  34.  
  35. //删除某条数据,操作方式与 Put 类似
  36. val d = new Delete("id001".getBytes)
  37. d.addColumn("basic".getBytes,"name".getBytes)
  38. table.delete(d)
  39.  
  40. }finally {
  41. if(table != null) table.close()
  42. }
  43.  
  44. }finally {
  45. conn.close()
  46. }

Spark 操作 HBase

写入 HBase

首先要向 HBase 写入数据,我们需要用到PairRDDFunctions.saveAsHadoopDataset。因为 HBase 不是一个文件系统,所以saveAsHadoopFile方法没用。

def saveAsHadoopDataset(conf: JobConf): Unit
Output the RDD to any Hadoop-supported storage system, using a Hadoop JobConf object for that storage system

这个方法需要一个 JobConf 作为参数,类似于一个配置项,主要需要指定输出的格式和输出的表名。

Step 1:我们需要先创建一个 JobConf。

  1. //定义 HBase 的配置
  2. val conf = HBaseConfiguration.create()
  3. conf.set("hbase.zookeeper.property.clientPort", "2181")
  4. conf.set("hbase.zookeeper.quorum", "master")
  5.  
  6. //指定输出格式和输出表名
  7. val jobConf = new JobConf(conf,this.getClass)
  8. jobConf.setOutputFormat(classOf[TableOutputFormat])
  9. jobConf.set(TableOutputFormat.OUTPUT_TABLE,"user")

Step 2: RDD 到表模式的映射
在 HBase 中的表 schema 一般是这样的:

  1. row cf:col_1 cf:col_2

而在Spark中,我们操作的是RDD元组,比如(1,"lilei",14)(2,"hanmei",18)。我们需要将 RDD[(uid:Int, name:String, age:Int)] 转换成 RDD[(ImmutableBytesWritable, Put)]。所以,我们定义一个 convert 函数做这个转换工作

  1. def convert(triple: (Int, String, Int)) = {
  2. val p = new Put(Bytes.toBytes(triple._1))
  3. p.addColumn(Bytes.toBytes("basic"),Bytes.toBytes("name"),Bytes.toBytes(triple._2))
  4. p.addColumn(Bytes.toBytes("basic"),Bytes.toBytes("age"),Bytes.toBytes(triple._3))
  5. (new ImmutableBytesWritable, p)
  6. }

Step 3: 读取RDD并转换

  1. //read RDD data from somewhere and convert
  2. val rawData = List((1,"lilei",14), (2,"hanmei",18), (3,"someone",38))
  3. val localData = sc.parallelize(rawData).map(convert)

Step 4: 使用saveAsHadoopDataset方法写入HBase

  1. localData.saveAsHadoopDataset(jobConf)

读取 HBase

Spark读取HBase,我们主要使用SparkContext 提供的newAPIHadoopRDDAPI将表的内容以 RDDs 的形式加载到 Spark 中。

  1. val conf = HBaseConfiguration.create()
    conf.set("hbase.zookeeper.property.clientPort", "2181")
    conf.set("hbase.zookeeper.quorum", "master")
  2.  
  3. //设置查询的表名
    conf.set(TableInputFormat.INPUT_TABLE, "user")
  4.  
  5. val usersRDD = sc.newAPIHadoopRDD(conf, classOf[TableInputFormat],
    classOf[org.apache.hadoop.hbase.io.ImmutableBytesWritable],
    classOf[org.apache.hadoop.hbase.client.Result])
  6.  
  7. val count = usersRDD.count()
    println("Users RDD Count:" + count)
    usersRDD.cache()
  8.  
  9. //遍历输出
    usersRDD.foreach{ case (_,result) =>
    val key = Bytes.toInt(result.getRow)
    val name = Bytes.toString(result.getValue("basic".getBytes,"name".getBytes))
    val age = Bytes.toInt(result.getValue("basic".getBytes,"age".getBytes))
    println("Row key:"+key+" Name:"+name+" Age:"+age)
    }

spark 对hbase 操作的更多相关文章

  1. Spark-读写HBase,SparkStreaming操作,Spark的HBase相关操作

    Spark-读写HBase,SparkStreaming操作,Spark的HBase相关操作 1.sparkstreaming实时写入Hbase(saveAsNewAPIHadoopDataset方法 ...

  2. Spark读Hbase优化 --手动划分region提高并行数

    一. Hbase的region 我们先简单介绍下Hbase的架构和Hbase的region: 从物理集群的角度看,Hbase集群中,由一个Hmaster管理多个HRegionServer,其中每个HR ...

  3. [Spark] 04 - HBase

    BHase基本知识 基本概念 自我介绍 HBase是一个分布式的.面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”. ...

  4. HBase调优案例(三)——Spark访问HBase慢

    负载信息:RegionServer:3个 Region:5400多个 现象:在使用Spark对HBase进行scan操作时发现有些task执行比较慢 原因分析:查看Spark应用的executor日志 ...

  5. Spark Dataset DataFrame 操作

    Spark Dataset DataFrame 操作 相关博文参考 sparksql中dataframe的用法 一.Spark2 Dataset DataFrame空值null,NaN判断和处理 1. ...

  6. MapReduce和Spark写入Hbase多表总结

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 大家都知道用mapreduce或者spark写入已知的hbase中的表时,直接在mapreduc ...

  7. 大数据学习系列之九---- Hive整合Spark和HBase以及相关测试

    前言 在之前的大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 中介绍了集群的环境搭建,但是在使用hive进行数据查询的时候会非常的慢,因为h ...

  8. spark读写hbase性能对比

    一.spark写入hbase hbase client以put方式封装数据,并支持逐条或批量插入.spark中内置saveAsHadoopDataset和saveAsNewAPIHadoopDatas ...

  9. Spark读写HBase

    Spark读写HBase示例 1.HBase shell查看表结构 hbase(main)::> desc 'SDAS_Person' Table SDAS_Person is ENABLED ...

随机推荐

  1. js对secure的支持是没问题的,httponly是为限制js而产生的,当然httponly的cookie也不会被js创建

    function setCookie4(c_name,value,expiredays){ var cookieStr = ""; var exdate=new Date(); e ...

  2. Day5 CSS基本样式和C3选择器

    Day5 CSS基本样式和C3选择器 一.背景属性 1.背景颜色            background-color:transparent(默认值,透明); 颜色的取值:            ...

  3. Linux系统 Centos7/Centos6.8 yum命令在线安装 MySQL5.6

    Linux系统 Centos7 yum命令在线安装 MySQL5.6 标签: centosmysqlyum 2015-11-18 17:21 707人阅读 评论(0) 收藏 举报  分类: Linux ...

  4. 从零开始的全栈工程师——js篇2.14(表单与计时器)

    一.表单 Form input select textarea type=”radio/checkbox/password/button/text/submit/reset/” 表单的事件 oncha ...

  5. RING3到RING0

    当我在说跳转时,说的什么? CPU有很多指令,不是所有的指令都能够随时用,比如 ltr指令就不是随便什么时候能用,在保护模式下,如果你不安规则来执行指令,CPU就会抛出异常,比如你在INTEL手册上就 ...

  6. ArcGIS for Server新建站点异常,Failed to create the site.Failed to configure the server machine'XXXX',Server machine'XXXX' is not a local server machine.

      系统环境:操作系统Win7 64位,装在虚拟机VM中,ArcGIS for Server 10.2.1 问题描述:ArcGIS for Server 10.2.1安装并授权完成后,站点初始化时显示 ...

  7. linux 下 `dirname $0`(转)

    在命令行状态下单纯执行 $ cd `dirname $0` 是毫无意义的.因为他返回当前路径的".".这个命令写在脚本文件里才有作用,他返回这个脚本文件放置的目录,并可以根据这个目 ...

  8. tomcat jvm参数优化

    根据gc(垃圾回收器)的选择,进行参数优化 JVM给了三种选择:串行收集器.并行收集器.并发收集器,但是串行收集器只适用于小数据量的情况,所以这里的选择主要针对并行收集器和并发收集器. -XX:+Us ...

  9. 详细讲解:通过phpstudy 设置站点域名、站点域名管理

    我们在本地编程的时候,会遇到路径特别长的情况,这样子我们在url中的输入就会变得不方便而且容易报错,那么在phpstudy这个环境中,有一个很好的功能,就是“站点域名管理”,他能让我们的url网址大大 ...

  10. ffmpeg 命令2

    ffmpeg常用基本命令(转) [FFmpeg]FFmpeg常用基本命令 1.分离视频音频流 ffmpeg -i input_file -vcodec copy -an output_file_vid ...