spark 存入hbase_Spark入门:读写HBase数据

本文详细介绍了如何使用Spark读写HBase数据库,包括创建HBase表,使用HBase shell插入数据,配置Spark以连接HBase,以及编写Scala程序从Spark读取和写入HBase数据的步骤。通过实例展示了如何使用put命令插入数据,以及如何通过SparkContext的newAPIHadoopRDD API操作HBase数据。
摘要由CSDN通过智能技术生成

【版权声明】博客内容由厦门大学数据库实验室拥有版权,未经允许,请勿转载!

[返回Spark教程首页]

Spark处理的数据有很多是存放在HBase数据库中的,所以,我们需要学会如何读写HBase数据库。HBase是针对谷歌BigTable的开源实现,是一个高可靠、高性能、面向列、可伸缩的分布式数据库,主要用来存储非结构化和半结构化的松散数据。HBase可以支持超大规模数据存储,它可以通过水平扩展的方式,利用廉价计算机集群处理由超过10亿行数据和数百万列元素组成的数据表。如果要了解HBase的技术原理和使用方法,可以参考厦门大学数据库实验室的在线课程《HBase数据库》。

准备工作一:创建一个HBase表

这里依然是以student表为例进行演示。这里假设你已经成功安装了HBase数据库,如果你还没有安装,可以参考厦门大学数据库实验室HBase安装和使用教程,进行安装,安装好以后,不要创建数据库和表,只要跟着本节后面的内容操作即可。HBase安装时有三种模式:单机模式、伪分布式模式和分布式模式。本教程采用伪分布式安装。

安装好了伪分布式模式的HBase以后,我们可以在里面创建一个student表。

请登录Linux系统,打开一个终端(可以使用快捷方式Ctrl+Alt+T组合键打开终端),因为HBase是伪分布式模式,需要调用HDFS,所以,请首先在终端中输入下面命令启动Hadoop:

cd /usr/local/hadoop

./sbin/start-all.sh

启动完成以后,一定要输入jps命令查看是否启动成功:

jps

运行jps命令以后,应该可以看到以下几个进程:

2375 SecondaryNameNode

2169 DataNode

2667 NodeManager

2972 Jps

2045 NameNode

2541 ResourceManager

如果少了其中一个进程,说明启动失败。

下面就可以启动HBase,命令如下:

cd /usr/local/hbase

./bin/start-hbase.sh //启动HBase

./bin/hbase shell //启动hbase shell

这样就可以进入hbase shell命令提示符状态。下面我们在HBase数据库中创建student表(注意:在关系型数据库MySQL中,需要首先创建数据库,然后再创建表,但是,在HBase数据库中,不需要创建数据库,只要直接创建表就可以):

hbase> list

用list命令可以显示当前HBase数据库中有哪些已经创建好的表,如果里面已经有一个名称为student的表,请使用如下命令删除(如果不存在student表,就不用执行下面的删除命令了):

hbase> disable 'student'

hbase> drop 'student'

下面让我们一起来创建一个student表,我们要在这个表中录入如下数据:

+------+----------+--------+------+

| id | name | gender | age |

+------+----------+--------+------+

| 1 | Xueqian | F | 23 |

| 2 | Weiliang | M | 24 |

+------+----------+--------+------+

我们可以在hbase shell中使用下面命令创建:

hbase> create 'student','info'

你可以发现,我们在创建student表的create命令中,命令后面首先跟上表名称’student’,然后,再跟上列族名称’info’,这个列族’info’中包含三个列’name’,’gender’,’age’。你会发现,好像没有’id’字段,这是因为HBase的表中会有一个系统默认的属性作为行键,无需自行创建,默认把put命令操作中跟在表名后的第一个字段作为行健。

创建完“student”表后,可通过describe命令查看“student”表的基本信息:

hbase> describe 'student'

下面,我们要把student表的两个样例记录输入到student表中。但是,HBase是列族数据库,原理和关系数据库不同,操作方法也不同。如果要了解HBase的技术原理和使用方法,可以参考厦门大学数据库实验室的在线课程《HBase数据库》。

如果没有时间学习HBase数据库细节知识,也可以直接按照下面的内容跟着操作就可以了。

HBase中用put命令添加数据,注意:一次只能为一个表的一行数据的一个列(也就是一个单元格,单元格是HBase中的概念)添加一个数据,所以直接用shell命令插入数据效率很低,在实际应用中,一般都是利用编程操作数据。因为这里只要插入两条学生记录,所以,我们可以用shell命令手工插入。

//首先录入student表的第一个学生记录

hbase> put 'student','1','info:name','Xueqian'

hbase> put 'student','1','info:gender','F'

hbase> put 'student','1','info:age','23'

//然后录入student表的第二个学生记录

hbase> put 'student','2','info:name','Weiliang'

hbase> put 'student','2','info:gender','M'

hbase> put 'student','2','info:age','24'

数据录入结束后,可以用下面命令查看刚才已经录入的数据:

//如果每次只查看一行,就用下面命令

hbase> get 'student','1'

//如果每次查看全部数据,就用下面命令

hbase> scan 'student'

可以得到如下结果:

ROW COLUMN+CELL

1 column=info:age, timestamp=1479640712163, value=23

1 column=info:gender, timestamp=1479640704522, value=F

1 column=info:name, timestamp=1479640696132, value=Xueqian

2 column=info:age, timestamp=1479640752474, value=24

2 column=info:gender, timestamp=1479640745276, value=M

2 column=info:name, timestamp=1479640732763, value=Weiliang

2 row(s) in 0.1610 seconds

准备工作二:配置Spark

在开始编程操作HBase数据库之前,需要对做一些准备工作。

(1)请新建一个终端,执行下面命令,把HBase的lib目录下的一些jar文件拷贝到Spark中,这些都是编程时需要引入的jar包,需要拷贝的jar文件包括:所有hbase开头的jar文件、guava-12.0.1.jar、htrace-core-3.1.0-incubating.jar和protobuf-java-2.5.0.jar,可以打开一个终端按照以下命令来操作:

cd /usr/local/spark/lib

mkdir hbase

cd hbase

cp /usr/local/hbase/lib/hbase*.jar ./

cp /usr/local/hbase/lib/guava-12.0.1.jar ./

cp /usr/local/hbase/lib/htrace-core-3.1.0-incubating.jar ./

cp /usr/local/hbase/lib/protobuf-java-2.5.0.jar ./

然后,设置Spark的spark-env.sh文件,告诉Spark可以在哪个路径下找到HBase相关的jar文件,如下:

cd /usr/local/spark/conf

vim spark-env.sh

使用vim编辑器打开spark-env.sh文件以后,可以在文件最前面增加下面一行内容:

export SPARK_CLASSPATH=$SPARK_CLASSPATH:/usr/local/spark/lib/hbase/*:/usr/local/hbase/conf

只有这样,后面编译过程才不会出错。

编写程序读取HBase数据

如果要让Spark读取HBase,就需要使用SparkContext提供的newAPIHadoopRDD API将表的内容以RDD的形式加载到Spark中。

请在Linux系统中打开一个终端,然后执行以下命令:

cd /usr/local/spark/mycode

mkdir hbase

cd hbase

mkdir -p src/main/scala

cd src/main/scala

vim SparkOperateHBase.scala

然后,在SparkOperateHBase.scala文件中输入以下代码:

import org.apache.hadoop.conf.Configuration

import org.apache.hadoop.hbase._

import org.apache.hadoop.hbase.client._

import org.apache.hadoop.hbase.mapreduce.TableInputFormat

import org.apache.hadoop.hbase.util.Bytes

import org.apache.spark.SparkContext

import org.apache.spark.SparkContext._

import org.apache.spark.SparkConf

object SparkOperateHBase {

def main(args: Array[String]) {

val conf = HBaseConfiguration.create()

val sc = new SparkContext(new SparkConf())

//设置查询的表名

conf.set(TableInputFormat.INPUT_TABLE, "student")

val stuRDD = sc.newAPIHadoopRDD(conf, classOf[TableInputFormat],

classOf[org.apache.hadoop.hbase.io.ImmutableBytesWritable],

classOf[org.apache.hadoop.hbase.client.Result])

val count = stuRDD.count()

println("Students RDD Count:" + count)

stuRDD.cache()

//遍历输出

stuRDD.foreach({ case (_,result) =>

val key = Bytes.toString(result.getRow)

val name = Bytes.toString(result.getValue("info".getBytes,"name".getBytes))

val gender = Bytes.toString(result.getValue("info".getBytes,"gender".getBytes))

val age = Bytes.toString(result.getValue("info".getBytes,"age".getBytes))

println("Row key:"+key+" Name:"+name+" Gender:"+gender+" Age:"+age)

})

}

}

然后就可以用sbt打包编译。不过,在编译之前,需要新建一个simple.sbt文件,在simple.sbt配置文件中,需要知道scalaVersion、spark-core、hbase-client、hbase-common、hbase-server的版本号。在前面章节《Spark的安装和使用》的“编写Scala独立应用程序”部分,我们已经介绍了如何寻找scalaVersion和spark-core的版本号,这里不再赘述。现在介绍如何找到你自己电脑上安装的HBase的hbase-client、hbase-common、hbase-server的版本号。

请在Linux系统中打开一个终端,输入下面命令:

cd /usr/local/hbase //这是笔者电脑的hbase安装目录

cd lib

ls

ls命令会把“/usr/local/hbase/lib”目录下的所有jar文件全部列出来,其中,就可以看到下面三个文件:

hbase-client-1.1.5.jar //可以看出版本号是1.1.5

hbase-common-1.1.5.jar //可以看出版本号是1.1.5

hbase-server-1.1.5.jar //可以看出版本号是1.1.5

根据上面三个文件,我们就可以得知hbase-client、hbase-common、hbase-server的版本号是1.1.5(当然,你的电脑上可能不是这个版本号,请以你自己的版本号为准)。

有了这些版本号信息,我们就可以新建一个simple.sbt文件:

cd /usr/local/spark/mycode/hbase

vim simple.sbt

然后在simple.sbt中录入下面内容:

name := "Simple Project"

version := "1.0"

scalaVersion := "2.10.5"

libraryDependencies += "org.apache.spark" %% "spark-core" % "1.6.2"

libraryDependencies += "org.apache.hbase" % "hbase-client" % "1.1.5"

libraryDependencies += "org.apache.hbase" % "hbase-common" % "1.1.5"

libraryDependencies += "org.apache.hbase" % "hbase-server" % "1.1.5"

保存该文件,退出vim编辑器。

然后,输入下面命令:

find .

应该可以看到类似下面的文件结构:

.

./src

./src/main

./src/main/scala

./src/main/scala/SparkOperateHBase.scala

./simple.sbt

下面就可以运行sbt打包命令:

cd /usr/local/spark/mycode/hbase //一定把这个设置为当前目录

/usr/local/sbt/sbt package

打包成功以后,生成的 jar 包的位置为 /usr/local/spark/mycode/hbase/target/scala-2.10/simple-project_2.10-1.0.jar。

最后,通过 spark-submit 运行程序。我们就可以将生成的 jar 包通过 spark-submit 提交到 Spark 中运行了,命令如下:

/usr/local/spark/bin/spark-submit --class "SparkOperateHBase" /usr/local/spark/mycode/hbase/target/scala-2.10/simple-project_2.10-1.0.jar

执行后得到如下结果:

Students RDD Count:2

Row key:1 Name:Xueqian Gender:F Age:23

Row key:2 Name:Weiliang Gender:M Age:24

编写程序向HBase写入数据

下面编写程序向HBase中写入两行数据。

请打开一个Linux终端,输入如下命令:

cd /usr/local/spark/mycode/hbase

vim src/main/scala/SparkWriteHBase.scala

上面命令用vim编辑器新建了一个文件SparkWriteHBase.scala,然后,在SparkWriteHBase.scala文件中输入下面代码:

import org.apache.hadoop.hbase.HBaseConfiguration

import org.apache.hadoop.hbase.mapreduce.TableOutputFormat

import org.apache.spark._

import org.apache.hadoop.mapreduce.Job

import org.apache.hadoop.hbase.io.ImmutableBytesWritable

import org.apache.hadoop.hbase.client.Result

import org.apache.hadoop.hbase.client.Put

import org.apache.hadoop.hbase.util.Bytes

object SparkWriteHBase {

def main(args: Array[String]): Unit = {

val sparkConf = new SparkConf().setAppName("SparkWriteHBase").setMaster("local")

val sc = new SparkContext(sparkConf)

val tablename = "student"

sc.hadoopConfiguration.set(TableOutputFormat.OUTPUT_TABLE, tablename)

val job = new Job(sc.hadoopConfiguration)

job.setOutputKeyClass(classOf[ImmutableBytesWritable])

job.setOutputValueClass(classOf[Result])

job.setOutputFormatClass(classOf[TableOutputFormat[ImmutableBytesWritable]])

val indataRDD = sc.makeRDD(Array("3,Rongcheng,M,26","4,Guanhua,M,27")) //构建两行记录

val rdd = indataRDD.map(_.split(',')).map{arr=>{

val put = new Put(Bytes.toBytes(arr(0))) //行健的值

put.add(Bytes.toBytes("info"),Bytes.toBytes("name"),Bytes.toBytes(arr(1))) //info:name列的值

put.add(Bytes.toBytes("info"),Bytes.toBytes("gender"),Bytes.toBytes(arr(2))) //info:gender列的值

put.add(Bytes.toBytes("info"),Bytes.toBytes("age"),Bytes.toBytes(arr(3).toInt)) //info:age列的值

(new ImmutableBytesWritable, put)

}}

rdd.saveAsNewAPIHadoopDataset(job.getConfiguration())

}

}

保存该文件退出vim编辑器,然后,使用sbt打包编译,命令如下:

cd /usr/local/spark/mycode/hbase

/usr/local/sbt/sbt package

打包成功以后,生成的 jar 包的位置为 /usr/local/spark/mycode/hbase/target/scala-2.10/simple-project_2.10-1.0.jar。实际上,由于之前我们已经编写了另外一个代码文件SparkOperateHBase.scala,所以,simple-project_2.10-1.0.jar中实际包含了SparkOperateHBase.scala和SparkWriteHBase.scala两个代码文件的编译结果(class文件),在运行命令时,可以通过–class后面的名称参数来决定运行哪个程序。

最后,通过 spark-submit 运行程序。我们就可以将生成的 jar 包通过 spark-submit 提交到 Spark 中运行了,命令如下:

/usr/local/spark/bin/spark-submit --class "SparkWriteHBase" /usr/local/spark/mycode/hbase/target/scala-2.10/simple-project_2.10-1.0.jar

执行后,我们可以切换到刚才的HBase终端窗口,在HBase shell中输入如下命令查看结果:

hbase> scan 'student'

得到如下结果:

ROW COLUMN+CELL

1 column=info:age, timestamp=1479640712163, value=23

1 column=info:gender, timestamp=1479640704522, value=F

1 column=info:name, timestamp=1479640696132, value=Xueqian

2 column=info:age, timestamp=1479640752474, value=24

2 column=info:gender, timestamp=1479640745276, value=M

2 column=info:name, timestamp=1479640732763, value=Weiliang

3 column=info:age, timestamp=1479643273142, value=\x00\x00\x00\x1A

3 column=info:gender, timestamp=1479643273142, value=M

3 column=info:name, timestamp=1479643273142, value=Rongcheng

4 column=info:age, timestamp=1479643273142, value=\x00\x00\x00\x1B

4 column=info:gender, timestamp=1479643273142, value=M

4 column=info:name, timestamp=1479643273142, value=Guanhua

4 row(s) in 0.3240 seconds

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值