Hbase数据导出与批量写入
Hbase数据导入导出
我们都知道Hbase数据进容易,到想大批量导出有点难,这和hbase特性有关,它不支持大范围数据scan。下面介绍两种Hbase数据导出方式。
一、通过建hive外部表方式,把hbase数据导到hive外部表,然后再把外部表数据写入hive内部表(为什么要多这一步?是因为后续我们还实时去访问外部表查询统计数据对hbase压了很大,存入内部表后,后续都只对内部表操作不影响hbase)。
hive建hbase内部表方式
CREATE EXTERNAL TABLE hive_hbase_ex_test(
id string comment "hbase rowkey",
name string comment "姓名",
code string comment "编号",
phone string comment "电话号码"
)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,user:NAME,user:CODE,user:PHONE")
TBLPROPERTIES("hbase.table.name" = "test:info");
hbase 表名:test:info
user为列族
备注:"hbase.columns.mapping" 下的hbase中的字段要在一行,中间以,分割不能空格或换行
二、通过快照方式快速把hbase数据迁移到另一个hbase集群
在源Hbase对表打快照,然后把快照拷贝到目标Hbase集群,最后恢复快照。
注意,该方案用phoenix建的表需提前在目标集群建好
要保证两个集群建表语句一致,特别是加盐值。若有二级索引需要把二级索引表一起迁移,要不然二级索引不生效
步骤:
1、对表创建快照
登录源hbase集群机器用hbase shell连接hbase ,创建快照
snapshot ‘table_name’,‘snapshot_name’
例:snapshot ‘MY.TEST’,‘SNAPSHOT_MY_TEST’
list_snapshots //查看已建快照
delete_snapshot ‘SNAPSHOT_MY_TEST_TEST’ 删除快照
2、迁移快照
退出hbase shell
hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot –snapshot 快照名 -copy-from 源Hbase集群active namenode存放快照路径 -copy-to 目标Hbase集群active namenode存放快照路径
例:
hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot SNAPSHOT_MY_TEST -copy-from hdfs://192.168.12.1:9000/hbase -copy-to hdfs://192.168.10.2:9000/hbase
3、disable新集群表
登录目标hbase集群机器,使用hbase shell 连接hbase, disable表
disable ‘MY.TEST’
4、恢复快照
登录目标hbase集群机器,使用hbase shell 连接hbase,恢复快照
restore_snapshot ‘SNAPSHOT_MY_TEST’
5、恢复表
登录目标hbase集群机器,使用hbase shell 连接hbase,恢复表
enable ‘MY.TEST’
6、验证是否迁移成功
对两个集群表数据查看对比,数量量和数据值。
三、通过spark批量导出数据
使用phoenix访问hbase为前提
使用spark2
引入jar包
phoenix-spark2
使用phoenix-spark会有各种问题
import org.apache.phoenix.spark._
val sparkSession = SparkSession.builder()
.master("local[*]")
.getOrCreate()
//to DataFrame
val df = sparkSession.sqlContext.phoenixTableAsDataFrame(
"tableName",
Seq("ID","NAME","CODE"),
Option("id='test'"),
zkUrl = Some("zk1,zk2,zk3:2181:/hbase")
)
//to RDD
val rdd = sparkSession.sparkContext.phoenixTableAsRDD(
"tableName",
Seq("ID","NAME","CODE"),
Option("id='test'"),
zkUrl = Some("zk1,zk2,zk3:2181:/hbase")
)
可以把phoenix表数据转为spark的df和rdd两种方式,其中Option(“id=‘test’”)为筛选条件可以没有,及全量导。
四、导出csv文件
从源Hbase集群导出csv文件,然后远程拷贝到目标Hbase集群,再导入数据。
前期工作:在两个集群准备好一个目录可存放导出的csv文件
步骤:
1、 用phoenix连接源Hbase集群
a)设置输出格式为csv
!outputformat csv
b)设置查询记录存放路径
!record /data/info.csv
c)执行查询sql
select * from TEST.INFO;
2、 进入存放csv文件目录
替换文件中单引号’为空,导出记录都加了单引号,但导入不能用单引号
sed -i “s/’//g” info.csv
3、 把导出的csv文件scp到目标Hbase集群
4、 在目标Hbase集群导入csv文件
进入phoenix安装的bin目录
./psql.py -d 分隔符 –t 表名 hbase地址 csv文件路径
./psql.py -d ‘,’ -t ‘TEST.INFO’ 192.168.12.1,192.168.12.2:2181:/hbase /data/info.csv
常见问题:
1、 对于大表查询语句要走索引,分批次查,要不然会报查询超时。
Hbase数据批量写入
一、还是通过hive建外部表的方式,往hive外部表写入数据,就会自动写入hbase。
二、通过spark
使用phoenix访问hbase为前提
引入jar包
phoenix-spark
或者phoenix-spark2
import org.apache.phoenix.spark._
df.write
.format("org.apache.phoenix.spark")
.mode(SaveMode.Overwrite)
.option("table", "tableName")
.option("zkUrl", "zk1,zk2,zk3:2181:/hbase")
.save()
//或者
rdd.saveToPhoenix(
"tableName",
Seq("ID","NAME","CODE"),
zkUrl = Some("zk1,zk2,zk3:2181:/hbase")
)