Python 3 使用HBase 总结

HBase 简介和安装

请参考文章:HBase 一文读懂

Python3 HBase API

HBase 前期准备

1 安装happybase库操作hbase
安装该库 pip install happybase2 确保 Hadoop 和 Zookeeper 可用并开启
确保Hadoop 正常运行
确保Zookeeper 正常运行3 开启HBase thrift服务
使用命令开启
$HBASE_HOME/bin/hbase-daemon.sh start thrift4、使用jps 命令查看thrift 服务 是否正常启动
[root@Hadoop3-master bin]# jps
69760 Worker
120160 ResourceManager
81811 QuorumPeerMain
119541 DataNode
93143 Jps
56695 Worker
119387 NameNode
119802 SecondaryNameNode
92890 ThriftServer
69549 Master
69759 Worker
[root@Hadoop3-master bin]#

HappyBase 简介

Happybase是Python通过Thrift访问HBase的库,实现起来方便、快捷。

HappyBase 核心类

Centos 操作指令 


[root@Hadoop3-master bin]# ./zkServer.sh start #启动 ZooKeeper
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@Hadoop3-master bin]# hbase-daemon.sh start thrift #开启守护hbase 线程并开启thrift 服务
running thrift, logging to /usr/local/hbase/logs/hbase-root-thrift-Hadoop3-master.out
[root@Hadoop3-master bin]# jps #hadoop 3 服务/Hbase 服务
69760 Worker
120160 ResourceManager
81811 QuorumPeerMain
119541 DataNode
93143 Jps
56695 Worker
119387 NameNode
119802 SecondaryNameNode
92890 ThriftServer
69549 Master
69759 Worker
[root@Hadoop3-master bin]# 

 HBase 伪集群/单机版本遇到问题总结

 ERROR: KeeperErrorCode = NoNode for /hbase/master

造成此类问题的原因是:使用HBase 自带ZooKeeper 分布式调度框架造成,由于我的环境是单机版本,我的大致设置是使用独立ZooKeeper 服务。如下是我hbase-site.xml 和hbase-env.sh 相关配置

hbase-env.sh:

export HBASE_MANAGES_ZK=false # 推荐不使用HBash 自带zookeeper

hbase-site.xml:配置Hadoop 3 存储地址、ZooKeeper 服务地址和端口

  <property><name>hbase.rootdir</name><value>hdfs://Hadoop3-master:9000/hbase</value></property><!--必须设置为True,否则无法连接ZooKeeper--><property><name>hbase.cluster.distributed</name><value>true</value></property><!-- zk 端口 --><property><name>hbase.zookeeper.property.clientPort</name><value>2181</value></property><!-- hbase 依赖 zk的地址 --><property><name>hbase.zookeeper.quorum</name><value>Hadoop3-master</value></property>

Zookeeper:Unable to read additional data from client sessionid 0x00, likely client has closed socket

报错信息:

EndOfStreamException: Unable to read additional data from client sessionid 0x6362257b44e5068d, likely client has closed socket

具体原因:客户端连接Zookeeper时,配置的超时时长过短。

解决办法:调整zoo.cfg 超时参数值

[root@Hadoop3-master conf]# vi /usr/local/zookeeper/conf/zoo.cfg
# The number of milliseconds of each tick
tickTime=10000

 将超时时间由原来的2 秒修改为10 秒

HRegionServer: Failed construction RegionServer

2023-08-16 11:47:22,026 ERROR [main] regionserver.HRegionServer: Failed construction RegionServer
java.lang.StackOverflowErrorat org.apache.zookeeper.ZooKeeper.exists(ZooKeeper.java:2000)

原因:ZooKeeper 存储HBase 信息异常

解决办法:使用zkCli.sh 删除/hbase 节点数据

[root@Hadoop3-master bin]# ./zkCli.sh
Connecting to localhost:2181
******
WatchedEvent state:SyncConnected type:None path:null
[zk: localhost:2181(CONNECTED) 0] ls /
[hbase, zookeeper]
[zk: localhost:2181(CONNECTED) 5] deleteall /hbase
[zk: localhost:2181(CONNECTED) 6] ls /
[zookeeper]
[zk: localhost:2181(CONNECTED) 7] quitWATCHER::WatchedEvent state:Closed type:None path:null
2023-08-16 14:18:58,892 [myid:] - INFO  [main:ZooKeeper@1288] - Session: 0x10002e674ad0027 closed
2023-08-16 14:18:58,893 [myid:] - INFO  [main-EventThread:ClientCnxn$EventThread@568] - EventThread shut down for session: 0x10002e674ad0027
2023-08-16 14:18:58,895 [myid:] - INFO  [main:ServiceUtils@45] - Exiting JVM with code 0

Thriftpy2.transport.base.TTransportException: TTransportException(type=1, message="Could not connect to ('*.*.*.*', 9090)")

原因:HBase 没有启动thrift 守护进程服务。

解决办法:开启HBase thrift 守护进程服务。

[root@Hadoop3-master bin]# ./hbase-daemon.sh start thrift
running thrift, logging to /usr/local/hbase/logs/hbase-root-thrift-Hadoop3-master.out
[root@Hadoop3-master bin]# jps
69760 Worker
128612 QuorumPeerMain
70406 SecondaryNameNode
59081 HRegionServer
69549 Master
70190 DataNode
76078 ThriftServer
56695 Worker
70040 NameNode
70744 ResourceManager
58845 HMaster
69759 Worker
76286 Jps
[root@Hadoop3-master bin]#

通过jsp 指令查看是否包含ThriftServer 标识符 。

HBase Shell 及其常用命令

 hbase shell是一个命令行工具。在linux上,输入命令: . /hbase shell  

HBase Shell

  • version:显示当前hbase的版本号
  • status:显示各主节点的状态,之后可以加入参数
  • whoami:显示当前用户名
  • 退出shell模式:exit或quit.
[test@cs010 bin]$ ./hbase shell
//version显示当前hbase版本号
hbase(main):001:0> version
1.4.12, r6ae4a77408ad35d6a7a4e5cebfd401fc4b72b5ec, Sun Nov 24 13:25:41 CST 2019
//status显示各主节点的状态
hbase(main):002:0> status
1 active master, 0 backup masters, 1 servers, 1 dead, 7.0000 average load
//whoami显示当前用户名
hbase(main):003:0> whoami
test(auth:SIMPLE)groups: test

表和列族操作 

Hbase的表结构(schema)只有表名和列族两项内容.但列族的属性很多,在修改和建立表结构时,可以对列族的数量和属性进行设定.

HBase Shell操作表命令: 

创建表 

//创建表,必须指明两个参数:表名和列族的名字
1.  create 'table1','basic'    //建立表名为table1,含有一个列族basic
2.  create 'table1','basic','advanced' //建立表名为table1,建立了2个列族basic,advanced.
3.  create 'table2','basic',MAX_FILESIZE=>'134217728' //对表中所有列族设定,所有分区单次持久化的最大值为128MB
4.  create 'TABLE1','basic' //hbase区分大小写,与第一个table1是2张不同的表
5.  create 'table1',{NAME => 'basic',VERSION => 5,BLOCKCACHE => true}
//大括号内是对列族basic进行描述,定义了VERSION=>5,表示对于同一个cell,保留最近的5个历史版本,BLOCKCACHE赋值为true,允许读取数据时进行缓存.其他未指定的参数,采用默认值
//大括号中的语法,NAME和VERSION为参数名,不需要用括号引用.//创建命名空间
create_namespace 'bigdata'//命名空间下创建表
create 'bigdata:student','info'//命名空间下删除表,如果有表,需要先删除表drop_namespace 'bigdata'

查看表名列表 

//list命令查看当前所有表名
list//list命令查看当前命名空间
list_space//exists 命令查看此表是否存在 
exists 'table_test1'eg:
hbase(main):010:0> list
TABLE
table_test1
1 row(s) in 0.0060 secondshbase(main):043:0> list_namespace
NAMESPACE
default
1 row(s) in 0.0190 secondshbase(main):011:0> exists 'table_test1'
Table table_test1 does exist
0 row(s) in 0.0070 seconds

描述表结构 

//描述表结构 describe命令查看指定表的列族信息,包括有多少个列族、每个列族的参数信息
describe 'table_test1'//描述命名空间下的表结构describe 'bigdata:table_test1'
eg:
hbase(main):013:0> describe 'table_test1'
Table table_test1 is ENABLED
table_test1
COLUMN FAMILIES DESCRIPTION
{NAME => 'test001', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER',COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE =>'65536', REPLICATION_SCOPE => '0'}
{NAME => 'test002', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER',COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE =>'65536', REPLICATION_SCOPE => '0'}
2 row(s) in 0.0250 seconds

修改表结构 

//修改表结构,alter命令,比如增加列族或修改列族参数.
//eg:表table_test1中新增列族test002
1. alter 'table_test1','test001','test002' //新增列族test002
2. alter 'table_test1','test002' //新增列族test002
3. alter 'table_test1','test001',{NAME=> 'test002',IN_MEMORY =>true} //新增列族test002//修改列族名称,该列族下已存有数据,需要对数据进行修改
4. alter 'table_test1',{NAME=> 'test001',IN_MEMORY =>true}//删除一个列族,以及其中的数据(前提是至少要有一个列族)
5. alter 'table_test1','delete'=>'test001'
6. alter 'table_test1',{NAME=> 'test002',METHOD=>'delete'}eg:
[haishu@cs010 bin]$ . /hbash shell
hbase(main):001:0> list
TABLE
table_test1
1 row(s) in 0.1710 secondshbase(main):002:0> alter 'table_test1','delete'=>'test001'
Updating all regions with the new schema...
1/1 regions updated.
Done.
0 row(s) in 1.9480 secondshbase(main):003:0> alter 'table_test1',{NAME=>'test002',METHOD=>'delete'}
Updating all regions with the new schema...
1/1 regions updated.
Done.
0 row(s) in 1.8710 seconds

删除表 

//先禁用表,再删除表
disable 'table1' //禁用表table1
is_disable 'table1'//查看是否禁用成功
drop 'table1'//删除表//顺序完成禁用、删除表、删除所有数据、重新建立空表,即清空表中所有的数据
truncate 'table1'

数据更新

HBase Shell 增删改查命令:

数据插入 

//数据插入,参数依次显示为:表名、行键名称、列族:列的名称、单元格的值、时间戳或数据版本号,数值越大表示时间或版本越新,如果省略,默认显示当前时间戳
put 'table_test','001','basic:test001','micheal jordan',1
put 'table_test','002','basic:test002','kobe'

数据更新 

//数据更新,put语句行键、列族已存在,但不考虑时间戳。建表时设定VERSIONS=>n,则用户可以查询到同一个cell,最新的n个数据版本
put 'table_test','001','basic:test001','air jordan',2

数据删除

HBase 的删除操作并不会立即将数据从磁盘上删除,删除操作主要是对要被删除的数据打上标记。

当执行删除操作时,HBase 新插入一条相同的 KeyValue 数据,但是使 keytype=Delete,这便意味着数据被删除了,直到发生 Major compaction 操作时,数据才会被真正的从磁盘上删除,删除标记也会从StoreFile删除。

//数据删除,用delete,必须指明表名和列族名称
delete 'table_test','001','basic'
delete 'table_test','002','basic:test002'
delete 'table_test','002','basic:test002',2
//如果指明了版本,默认删除的是所有版本<=2的数据
//delete命令的最小粒度是cell,且不能跨列族删除。//删除表中所有列族在某个行键上的数据,即删除一个逻辑行,则需要使用deleteall命令
deleteall 'table_test','001'
deleteall 'table_test','002',1
//hbase并不能做实时删除数据,当hbase删除数据时,可以看作为这条数据put了新的版本,有一个删除标记(tombstone)

计数器 

//incr命令可以将cell的数值在原值上加入指定数值
incr 'table_test','001','basic:scores',10//get_counter命令可以查看计数器的当前值
get_counter 'table_test','001','basic:scores' 

数据查询 

hbase有2种基本的数据查询方法:

  1.get:按行键获取一条数据

  2.scan:扫描一个表,可以指定行键范围或使用过滤器限制范围。

  3.count:采用count指令计算表的逻辑行数

//get命令的必选参数为表名和行键名
get 'table_test','001'
//可选项,指明列族名称、时间戳的范围、数据版本数、使用过滤器
get 'table_test','001',{COLUMN=>'basic'}
get 'table_test','001',{COLUMN=>'basic',TIMERANGE=>[1,21]}
get 'table_test','001',{COLUMN=>'basic',VERSIONS=>3}
get 'table_test','001',{COLUMN=>'basic',TIMERANG=>[1,2],VERSION=>3}
get 'table_test','001',{FILTER=>"ValueFilter(=,'binary:Michael Jordan 1')"}
//scan数据扫描,不指定行键,hbase只能通过全表扫描的方式查询数据
scan 'table_test'
//指定列族名称
scan 'table_test' ,{COLUMN =>'basic'}
//指定列族和列名
scan 'table_test' ,{COLUMN =>'basic:name'}
//指定输出行数
scan 'table_test' ,{LIMIT => 1}
//指定行键的范围,中间用逗号隔开
scan 'table_test' ,{LIMIT =>'001',LIMIT => '003'}
//指定时间戳或时间范围
scan 'table_test' ,{TIMESTAMP => 1}
scan 'table_test' ,{TIMESTAMP => [1,3]}
//使用过滤器
scan 'table_test' ,FILTER=>"RowFilter(=,substring:0')"
//指定对同一个键值返回的最多历史版本数量
scan 'table_test' ,{version=> 1}
//采用count指令可以计算表的逻辑行数
count 'table_test' 

过滤查询 

无论是在get方法还是scan方法,均可以使用过滤器(filter)来显示扫描或输出的范围。

//过滤器进行过滤查询,配合比较运算符或比较器共同使用:>、<、=、>=、<=、!=
show_filters

比较器:

  • BinaryComparator:完整字节比较器,如:binary:001,表示用字典顺序依次比较数据的所有字节。
  • BinaryPrefixComparator:前缀字节比较器,如:binaryprefix:001,表示用字典顺序依次比较数据的前3个字节。
  • RegexStringComparator:正则表达式比较器,如regexstring:a*c,表示字符串'a'开头,'c'结构的所有字符串。只可以用=或!=两种运算符。
  • SubstringComparator:子字符串比较器,如substring:00.只可以用=或!=两种运算符。
  • BitComparator:比特位比较器。只可以用=或!=两种运算符。
  • NullComparator:空值比较器。
//比较器语法使用,用FILTER=> "过滤器(比较方式)"的方式指明所使用的过滤方法
//在语法格式上,过滤的方法用双引号引用,而比较方式用小括号引用
scan 'table_test',FILTER=>"RowFilter(=,'substring:0')"
scan 'table_test',{FILTER=>"RowFilter(=,'substring:0')"}

 过滤器的用途:

  • 行键过滤器
  • 列族和列过滤器
  • 值过滤器
  • 其他过滤器

行键过滤器:

//行键过滤器,RowFilter:可以配合比较器及运算符,实现行键字符串的比较和过滤。
//需求:显示行键前缀为0开头的键值对,进行子串过滤只能用=或!=两种方式,不支持采用大于或小于
scan 'table_test',FILTER=>"RowFilter(=,'Substring:0')"
scan 'table_test',FILTER=>"RowFilter(>=,'BinaryPrefix:0')"
//行键前缀比较器,PrefixFilter:比较行键前缀(等值比较)的命令
scan 'table_test',FILTER=>"PrefixFilter('0')"
//KeyOnlyFilter:只对cell的键进行过滤和显示,不显示值,扫描效率比RowFilter高
scan 'table_test',{FILTER=>"KeyOnlyFilter()"}//FirstKeyFilter:只扫描相同键的第一个cell,其键值对都会显示出来,如果有重复的行键则跳过。可以用来实现对行键(逻辑行)的计数,和其他计数方式相比。
scan 'table_test',{FILTER=>"FirstKeyFilter()"}//InclusiveStopFilter:使用STARTROW和ENDROW进行设定范围的scan时,结果会包含STARTROW行,但不包括ENDROW,使用该过滤器替代ENDROW条件
scan 'table_test',{STARTROW=>'001',ENDROW=>'002'}
scan 'table_test',{STARTROW=>'001',FILTER=>"InclusiveStopFilter ('binary:002')",ENDROW=>'002'}

 列族和列过滤器:

//列族和列过滤器
//列族过滤器:FamilyFilter
scan 'table_test',FILTER=>"FamilyFilter(=,'substring:test001')"
//列名(列标识符)过滤器:QualifierFilter
scan 'table_test',FILTER=>"QualifierFilter(=,'substring:test001')"
//列名前缀过滤器:ColumnPrefixFilter
scan 'table_test',FILTER=>"ColumnPrefixFilter('f')"
//指定多个前缀的ColumnPrefixFilter:MultipleColumnPrefixFilter
scan 'table_test',FILTER=>"MultipleColumnPrefixFilter('f','l')"
//时间戳过滤器:TimestampsFilter
scan 'table_test',{FILTER=>"TimestampsFilter(1,2)"}
//列名范围过滤器:ColumnRangeFilter
scan 'table_test',{FILTER=>"ColumnRangeFilter('f',false,'lastname',true)"}
//参考列过滤器:DependentColumnFilter,设定一个参考列(即列名),如果某个逻辑行包含该列,则返回该行中和参考列时间戳相同的所有键值对
//过滤器参数中,第一项是需要过滤数据的列族名,第二项是参考列名,第三项是false说明扫描包含"basic:firstname",如果是true则说明在basic列族的其他列中进行扫描。
scan 'table_test',{FILTER=>"DependentColumnFilter('basic','firstname',false)"}

 值过滤器:

/ValueFilter:值过滤器,get或者scan方法找到符合值条件的键值对,变量=值:Michael Jordanget 'table_test','001',{FILTER=>"ValueFilter(=,'binary:Michael Jordan')"} scan 'table_test',{FILTER=>"ValueFilter(=,'binary:Michael Jordan')"} 
//SingleColumnValueFilter:在指定的列族和列中进行比较的值过滤器,使用该过滤器时尽量在前面加上一个独立的列名限定 
scan 'table_test',{ COLUMN => 'basic:palyername' , FILTER => "SingleColumnValueExcludeFilter('basic','playername',=,'binary:Micheal Jordan 3')"}
//SingleColumnValueExcludeFilter:和SingleColumnValueFilter类似,但功能正好相反,即排除匹配成功的值 
scan 'table_test', FILTER => "SingleColumnValueExcludeFilter( 'basic' , 'playername' ,=,'binary:Micheal Jordan 3')" 
SingleColumnValueFilter和SingleColumnValueExcludeFilter区别: Value = "Micheal Jordan "的键值对,或者返回除此之外的其他所有键值对。 
//其他过滤器 
1. ColumnCountGetFilter:限制每个逻辑行最多返回多少个键值对(cell),一般用get,不用scan.
2. PageFilter:对显示结果按行进行分页显示 
3. ColumnPaginationFilter:对显示结果按列进行分页显示 
4. 自定义过滤器:hbase允许采用Java编程的方式开发新的过滤器 
eg: scan 'table_test', FILTER => "ColumnPrefixFilter( 'first' ) AND ValueFilter(=, 'substring:kobe')"eg:
hbase(main):012:0> get 'Test','002',{FILTER=>"ValueFilter(=,'binary:test004')"}
COLUMN CELL
zhangsan:wendy001 timestamp=1587208488702, value=test004
zhangsan:wendy002 timestamp=1587208582262, value=test004
1 row(s) in 0.0100 secondshbase(main):013:0> scan 'Test',{FILTER=>"ValueFilter(=,'binary:test004')"}
ROW COLUMN+CELL
001 column=zhangsan:wendy001, timestamp=1587208452109, value=test004
002 column=zhangsan:wendy001, timestamp=1587208488702, value=test004
002 column=zhangsan:wendy002, timestamp=1587208582262, value=test004
2 row(s) in 0.0100 secondshbase(main):018:0> scan 'Test',{ COLUMN => 'zhangsan:wendy002' , FILTER => "SingleColumnValueExcludeFilter('zhangsan','wendy002',=,'binary:test004')"}
ROW COLUMN+CELL
0 row(s) in 0.0040 secondshbase(main):019:0> scan 'Test',{COLUMN=>'zhangsan:wendy002',FILTER=>"SingleColumnValueFilter('zhangsan','wendy002',=,'binary:test004')"}
ROW COLUMN+CELL
002 column=zhangsan:wendy002, timestamp=1587208582262, value=test004
1 row(s) in 0.0060 seconds

 快照操作

快照:一种不复制数据就能建立表副本的方法,可以用于数据恢复,构建每日、每周或每月的数据报告,并在测试中使用等。

快照前提:Hbase的配置文件hbase-site.xml中配置hbase.snpashot.enabled属性为true。一般情况下,HBase的默认选项即为true。

//建立表的快照p1
snapshot 'test001','p1'
//显示快照列表
List_snapshots
//删除快照
delete_snapshot 'p1'
PS:注意删除快照后,原表的数据仍然存在。删除原表,快照的数据也仍然存在。//通过快照生成新表play_1,注意用此种方法生成新表,不会发生数据复制,只会进行元数据操作
clone_snapshot 'p1','play_1'
//快照恢复原表格,将抛弃快照之后的所有变化
restore_snapshot 'p1'//利用快照实现表改名,方法:制作一个快照,再将快照生成为新表,最后将不需要的旧表和快照删除
snapshot 'player','p1'
clone_snapshot 'p1','play_1'
disable 'player'
drop 'player'
delete_snapshot 'p1'

 批量导入导出

场景:put方法用于逐条采集数据,但如果需要将大量数据一次性写入HBase,则需要进行批量操作。此外,如果需要将数据备份到HDFS等位置,也需要进行批量操作,基于hadoopde的MapReduce方法实现,而数据的导入源头和备份目的,通常是在HDFS之上。

批量导入数据,有两种方式:

  1、第一种是并行化的数据插入,利用MapReduce等方式将数据发给多个RegionServer。

  2、第二种是根据表信息直接将原始数据转换成HFile,并将数据复制到HDFS的相应位置,再将文件中的数据纳入管理。

方法1,利用ImportTsv类方法:将存储在HDFS上的文本文件导入到HBase的指定表,TXT文件当中应当有明确的列分隔符,比如利用'\t'(TAB键)分割的TSV格式,或逗号分割的CSV格式。

  原理:执行机制是扫描整个文件,逐条将数据写入。使用MapReduce方法在多个节点上启动多个进程,同时读取多个HDFS上的文件分块。数据根据所属分区不同,被发向不同的Regionserver,利用分布式并行读写的方式,加快数据导入的速度。

//在linux的命令行通过HBase指令调用ImportTsv类
//player为表名,hdfs://namenode:8020/input/为导入文件所在的目录,这里不需要指定文件名,导入时会遍历目录中的所有文件。
hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.columns= HBASE_ROW_KEY,basic:playername,advance:scores -Dimporttsv.skip.bad.lines =true player hdfs://namenode:8020/input/
//-Dimporttsv.columns=HBASE_ROW_KEY,参数依次为:第一个关键字HBASE_ROW_KEY是指定文本文件中的行键,第二个是写入列族basic下名为playername的列,第三个是写入advance列族下的scores列,这一参数一般为必选项。
//-Dimporttsv.skip.bad.lines=true表示略过无效的行,如果设置为false,则遇到无效行会导入报告失败 //可选参数 
//-Dimporttsv.separator=',',用逗号作为分隔符,也可以指定为其他形式的分隔符,例如'\0',默认情况下分隔符为'\t'。 
//-Dimporttsv.timestamp =1298529542218,导入时使用指定的时间戳,如果不指定则采用当前时间。 

方法二,利用bulk-load方法:直接将原始数据转换成HFile,并将数据复制到HDFS的相应位置,再将文件中的数据纳入管理,分为2个步骤。

//前提:表结构已经建立好,并且在命令中指定了表名,因为要根据表结构和分区状况准备文件
//第一步:利用ImportTsv生成文件
//第二步:复制//第一步:利用ImportTsv生成文件
hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.columns= HBASE_ROW_KEY,basic:playername,advance:scores -Dimporttsv.skip.bad.lines =true -Dimporttsv.bulk.output=hdfs://namenode:8020/bulkload/ player hdfs://namenode:8020/input/
//-Dimporttsv.bulk.output 参数,设定了HDFS路径,准备好HFile文件的存放地址:hdfs://namenode:8020/bulkload/,由于MapReduce的特性,该路径不能提前存在
//第二步:复制,利用MapReduce实现,参数为HFile文件所在路径和表名。
hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles
hdfs://namenode:8020/bulkload player

方法三,从关系型数据库中导入数据到HBase:Hadoop系列组件中,有名为Sqoop的组件可以实现Hadoop、Hive、HBase等大数据工具与关系型数据库(例如MySQL、Oracle)之间的数据导入、导出。

Sqoop分为1和2两个版本,Sqoop1使用较为简单,Sqoo2则继承了更多功能,架构也更复杂。

//以sqoop1为例,其安装过程基本为解压。
//访问MySQL等数据库,则需要自行下载数据库连接组件(mysql-connector-java-x.jar),并复制到其lib目录中。
sqoop import --connect jdbc:mysql://node1:3306/database1 --table table1 --hbase-table player --column-family f1 --hbase-row-key playername --hbase-create-table --username 'root' -password '123456'
//从mysql中导入数据(import),之后指明了作为数据源的mysql的访问地址(node1)、端口(3306)、数据库名(database1)、表名(table1)。
//数据导入名为player的HBase表,并存入名为f1的列族,列名则和MySQL中保持一致,行键为MySQL表中名为playername的列。
//--hbase-create-table :HBase中建立这个表,最后指明了访问mysql的用户名和密码。

备份和恢复 

HBase支持将表或快照复制到HDFS,支持将数据复制到其他HBase集群,以实现数据备份和恢复功能。有四种方式:

//Export、Import、ExportSnapshot、CopyTable
//Export:将HBase的数据导出到HDFS。目的;备份,文件并不能直接以文本方式查看。
//参数中<tablename>为表名,<outputdir>为HDFS路径。
hbase org.apache.hadoop.hbase.mapreduce.Export <tablename> <outputdir>//Import:导出的数据可以恢复到HBase。
hbase org.apache.hadoop.hbase.mapreduce.Import <tablename> <outputdir>//ExportSnapshot
hbase org.apache.hadoop.hbase.mapreduce.ExportSnapshot -snapshot <snapshot name> -copy-to <outputdir>
//snapshot 快照名 ;outputdir为HDFS路径,导出的快照文件可以利用Import方法恢复到表中。//CopyTable:可以将一个表的内容复制到新表中,新表和原表可以在同一个集群内,也可以在不同的集群上。复制过程利用MapReduce进行。
//前提:新表已经建立起来
hbase org.apache.hadoop.hbase.mapreduce.CopyTable --new.name=<NEW_TABLE_NAME> -peer.adr=<zookeeper_peer:2181:/hbase> <TABLE_NAME>
//--new.name=<NEW_TABLE_NAME>参数描述新表的名字,如果不指定则默认和原表名相同。
//-peer.adr=<zookeeper_peer:2181:/hbase>参数指向目标集群Zookeeper服务中的hbase数据入口(包括meta表的地址信息等)//CopyTable帮助
hbase org.apache.hadoop.hbase.mapreduce.CopyTable --help

HappyBase API 实践

连接HBase

# _*_ coding : UTF-8_*_
# 开发者 : zhuozhiwengang
# 开发时间 : 2023/8/14 22:56
# 文件名称 : python_hbase_1.py
# 开发工具 : PyCharm
import happybasecon = happybase.Connection('192.168.43.11')
con.open()  # 打开传输
print(con.tables())  # 输出所有表名
con.close()  # 关闭传输

效果截图:

表操作

创建表

# _*_ coding : UTF-8_*_
# 开发者 : zhuozhiwengang
# 开发时间 : 2023/8/16 15:11
# 文件名称 : python_hbase_2
# 开发工具 : PyCharm
import happybasecon = happybase.Connection('192.168.43.11')  # 默认9090端口
con.open()  # 打开thrift传输,TCP连接families = {'wangzherongyao': dict(max_versions=2),  # 设置最大版本为2'hepingjingying': dict(max_versions=1, block_cache_enabled=False),'xiaoxiaole': dict(),  # 使用默认值.版本默认为3
}
con.create_table('games', families)  # games是表名,families是列簇,列簇使用字典的形式表示,每个列簇要添加配置选项,配置选项也要用字典表示print(con.tables())  # 输出表
con.close()  # 关闭传输

配置选项:

  • max_versions (int类型)
  • compression (str类型)
  • in_memory (bool类型)
  • bloom_filter_type (str类型)
  • bloom_filter_vector_size (int类型)
  • bloom_filter_nb_hashes (int类型)
  • block_cache_enabled (bool类型)
  • time_to_live (int类型)

 启动或禁用表 

温馨提示:设置或者删除表时,必须得先禁用表,再删除。只能禁用或启动一次,不能重复,否则报错。

# _*_ coding : UTF-8_*_
# 开发者 : zhuozhiwengang
# 开发时间 : 2023/8/16 15:15
# 文件名称 : python_hbase_3
# 开发工具 : PyCharm
# 禁用表
import happybasecon = happybase.Connection('192.168.43.11')  # 默认9090端口
con.open()  # 打开thrift传输,TCP连接con.disable_table('games')  # 禁用表,games代表表名
print(con.is_table_enabled('games'))  # 查看表的状态,False代表禁用,True代表启动
print(con.tables())  # 即使禁用了该表,该表还是存在的,只是状态改变了con.close()  # 关闭传输

 效果截图:

# _*_ coding : UTF-8_*_
# 开发者 : zhuozhiwengang
# 开发时间 : 2023/8/16 15:16
# 文件名称 : python_hbase_4
# 开发工具 : PyCharm# 启动表
import happybasecon = happybase.Connection('192.168.43.11')  # 默认9090端口
con.open()  # 打开thrift传输,TCP连接con.enable_table('games')  # 启动该表
print(con.is_table_enabled('games'))  # 查看表的状态,False代表禁用,True代表启动
print(con.tables())  # 即使禁用了该表,该表还是存在的,只是状态改变了con.close()  # 关闭传输

效果截图: 

删除表

删除一个表要先将该表禁用,之后才能删除。HappyBase 的delete_table函数不但可以禁用表还可以删除表。如果前面已经禁用了该表,delete_table函数就可以不用加第二个参数,默认为False

# _*_ coding : UTF-8_*_
# 开发者 : zhuozhiwengang
# 开发时间 : 2023/8/16 15:20
# 文件名称 : python_hbase_5.py
# 开发工具 : PyCharm
import happybasecon = happybase.Connection('192.168.43.11')  # 默认9090端口
con.open()  # 打开thrift传输,TCP连接con.delete_table('games', disable=True)  # 第一个参数表名,第二个参数表示是否禁用该表print(con.tables())con.close()

 效果截图:

数据操作 

建立数据

注意:如果写数据时没有这个列名,就新建这样的列名,再写数据。

在 hbase shell 中,使用put命令,一次只能写入一个单元格,而happybase库的put函数能写入多个。

# _*_ coding : UTF-8_*_
# 开发者 : zhuozhiwengang
# 开发时间 : 2023/8/16 15:24
# 文件名称 : python_hbase_6.py
# 开发工具 : PyCharmimport happybasecon = happybase.Connection('192.168.43.11')  # 默认9090端口
con.open()  # 打开传输biao = con.table('games')  # games是表名,table('games')获取某一个表对象wangzhe = {'wangzherongyao:名字': '别出大辅助','wangzherongyao:等级': '30','wangzherongyao:段位': '最强王者',
}
biao.put('0001', wangzhe)  # 提交数据,0001代表行键,写入的数据要使用字典形式表示# 下面是查看信息,如果不懂可以继续看下一个
one_row = biao.row('0001')  # 获取一行数据,0001是行键
for value in one_row.keys():  # 遍历字典print(value.decode('utf-8'), one_row[value].decode('utf-8'))  # 可能有中文,使用encode转码con.close()  # 关闭传输

效果截图:

查看操作 

下面连接之后,就创建一个表对象,然后对这个表对象进行操作,这里演示了多种查看操作,第一个是查看一行的数据,第二个是查看一个单元格的数据,因为我存储时使用了中文,在hbase中存储的不是中文,而是utf-8的编码,这里接收了hbase传过来的编码数据之后对它进行解码,第三个是获取多行的数据,第四个是使用扫描器获取整个表的数据。

# _*_ coding : UTF-8_*_
# 开发者 : zhuozhiwengang
# 开发时间 : 2023/8/16 15:34
# 文件名称 : python_hbase_7.py
# 开发工具 : PyCharm
import happybasecon = happybase.Connection('192.168.43.11')  # 默认9090端口
con.open()  # 打开传输biao = con.table('games')  # games是表名,table('games')获取某一个表对象print('-----------------------第一个-----------------------------')
one_row = biao.row('0001')  # 获取一行数据,0001是行键
for value in one_row.keys():  # 遍历字典print(value.decode('utf-8'), one_row[value].decode('utf-8'))  # 可能有中文,使用encode内置函数转码print('-----------------------第二个-----------------------------')
print(biao.cells('0001', 'wangzherongyao:段位')[0].decode('utf-8'))  # 获取一个单元格信息,返回列表,转码输出,0001是行键,wangzherongyao是列簇名,是列名print('-----------------------第三个-----------------------------')
for key, value in biao.rows(['0001', '0002']):  # 获取多行的数据,列表或元组中可以写入多个行键# print(key, '<=====>', value)  # 由于0002我没有写入数据,就查不到,也不返回信息for index in value.keys():  # 遍历字典print(key.decode('utf-8'), index.decode('utf-8'), value[index].decode('utf-8'))  # 可能有中文,使用encode转码print('-----------------------第四个----------------------------')
for rowkey, liecu in biao.scan():  # 获取扫描器对象,该对象是可迭代对象。扫描器记录了一个表的结构# print(rowkey, '<=====>', liecu)for index in liecu.keys():  # 遍历字典print(rowkey.decode('utf-8'), index.decode('utf-8'), liecu[index].decode('utf-8'))  # 可能有中文,使用encode转码con.close()  # 关闭传输

效果截图:

 删除数据

# _*_ coding : UTF-8_*_
# 开发者 : zhuozhiwengang
# 开发时间 : 2023/8/16 15:38
# 文件名称 : python_hbase_8.py
# 开发工具 : PyCharmimport happybasecon = happybase.Connection('192.168.43.11')  # 默认9090端口
con.open()  # 打开传输biao = con.table('games')  # games是表名,table('games')获取某一个表对象biao.delete('0003', ['wangzherongyao:段位'])  # 删除一个单元格信息
# biao.delete('0003', ['wangzherongyao:名字', 'wangzherongyao:等级'])  # 删除多个单元个信息
# biao.delete('0003', ['wangzherongyao'])  # 删除一列簇信息
# biao.delete('0003')  # 删除一整行信息# 查看数据,看看是否还在
for rowkey, liecu in biao.scan():  # 获取扫描器对象,该对象是可迭代对象。扫描器记录了一个表的结构# print(rowkey, '<=====>', liecu)for index in liecu.keys():  # 遍历字典print(rowkey.decode('utf-8'), index.decode('utf-8'), liecu[index].decode('utf-8'))  # 可能有中文,使用encode转码
con.close()  # 关闭传输

前面说过,删除是根据时间戳来删除最近的版本,再次查看时显示的下一个时间戳最近的版本,那么下面测试一下是不是这样。

# _*_ coding : UTF-8_*_
# 开发者 : zhuozhiwengang
# 开发时间 : 2023/8/16 15:45
# 文件名称 : python_hbase_9
# 开发工具 : PyCharm
import happybasecon = happybase.Connection('192.168.43.11')  # 默认9090端口
con.open()  # 打开传输biao = con.table('games')  # games是表名,table('games')获取某一个表对象
biao.put('0001', {'wangzherongyao:段位': '最强王者'})
biao.put('0001', {'wangzherongyao:段位': '永恒钻石V'})
biao.put('0001', {'wangzherongyao:段位': '尊贵铂金I'})  # 重复写三个值
print(biao.cells('0001', 'wangzherongyao:段位'))  # 查看单元格的数据显示为最后一个时间戳的版本,即尊贵铂金Ibiao.delete('0001', ['wangzherongyao:段位'])  # 删除单元格的信息,按照正常的理论查看时显示永恒钻石V
print(biao.cells('0001', 'wangzherongyao:段位'))  # 查看单元格的信息,显示为空con.close()  # 关闭传输

问题描述:使用happybase.delete  删除指定单元格数据 ,清空了全部指定单元格记录。按照理论应该删除最近一条单元格记录。

原因:happybase库的 delete 函数封装的是 hbase shell 中的 deleteall 函数,所以调用要delete函数时要谨慎。

批处理

batch()函数可以创建一个可执行对象,然后在进行批处理操作,其实该函数返回了Batch对象,Batch对象支持上下文管理协议,可以执行批量写put操作、批量删delete操作,然后还要使用发送send函数提交到服务器

参考文章:HBase Shell 及其命令操作

                 HappyBase 官方文档 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/93156.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT爆火,会给教育带来什么样的影响或者冲击?

近来&#xff0c;人工智能聊天机器人ChatGPT连上热搜&#xff0c;火爆全网。ChatGPT拥有强大的信息整合能力、自然语言处理能力&#xff0c;可谓是“上知天文&#xff0c;下知地理”&#xff0c;而且还能根据要求进行聊天、撰写文章等。 ChatGPT一经推出&#xff0c;便迅速在社…

生活随笔,记录我的日常点点滴滴.

前言 &#x1f618;个人主页&#xff1a;曲终酣兴晚^R的小书屋&#x1f971; &#x1f615;作者介绍&#xff1a;一个莽莽撞撞的&#x1f43b; &#x1f496;专栏介绍&#xff1a;日常生活&往事回忆 &#x1f636;‍&#x1f32b;️每日金句&#xff1a;被人暖一下就高热&…

SpringBoot的配置文件(properties与yml)

文章目录 1. 配置文件的作用2. 配置文件格式3. 配置文件的使用方法3.1. properties配置文件3.1.1. 基本语法和使用3.1.2. properties优缺点分析 3.2. yml配置文件3.2.1. 基本语法与使用3.2.2. yml中单双引号问题3.2.3. yml配置不同类型的数据类型及null3.2.4. 配置对象3.2.5. 配…

CS5263替代停产IT6561连接DP转HDMI音视频转换器ASL 集睿致远CS5263设计电路原理图

ASL集睿致远CS5263是一款DP1.4到HDMI2.0b转换器芯片&#xff0c;设计用于将DP1.4源连接到HDMI2.0b接收器。 CS5263功能特性&#xff1a; DP接口包括4条主通道、辅助通道和HPD信号。接收器支持每通道5.4Gbps&#xff08;HBR2&#xff09;数据速率。DP接收机结合了HDCP1.4和HDCP…

接口测试工具——Postman测试工具 Swagger接口测试+SpringBoot整合 JMeter高并发测试工具

目录 Postman测试工具接口测试工具swaggerKnife4j1.引入依赖2.配置3.常用注解4.接口测试 JMeter什么是JMeter?JMeter安装配置1.官网下载2.下载后解压3.汉语设置 JMeter的使用方法1.新建线程组2.设置参数3.添加取样器4.设置参数&#xff1a;协议&#xff0c;ip&#xff0c;端口…

使用Nginx解决跨域问题

前言&#xff1a; 项目是公司的老项目&#xff0c;只有部署在服务器上的时候&#xff0c;项目才可以正常运行&#xff08;接口是通的&#xff09;&#xff1b;现在需求&#xff1a;在现有的项目代码上进行修改&#xff0c;请求接口是第三方给的。接口是正常的&#xff0c;通过A…

stm32f407 ADC学习记录

主要特性&#xff1a; ● 可配置 12 位、10 位、8 位或 6 位分辨率 ● 在转换结束、注入转换结束以及发生模拟看门狗或溢出事件时产生中断 ● 单次和连续转换模式 ● 用于自动将通道 0 转换为通道“ n ”的扫描模式 ● 数据对齐以保持内置数据一致性&#xff08;16位的数据…

Python pycparser(c文件解析)模块使用教程

文章目录 安装 pycparser 模块模块开发者网址获取抽象语法树1. 需要导入的模块2. 获取 不关注预处理相关 c语言文件的抽象语法树ast3. 获取 预处理后的c语言文件的抽象语法树ast 语法树组成1. 数据类型定义 Typedef2. 类型声明 TypeDecl3. 标识符类型 IdentifierType4. 变量声明…

Jmeter快捷方式和应用图标设置

很多人在安装Jmeter,安装到本机却没有icon&#xff0c;每次使用的时候&#xff0c;每次打开应用都要找目录&#xff0c;不太方便。 【解决问题】 使用bin路径下的一个.bat文件&#xff0c;创建快捷方式。 【操作步骤】 Step1、将Jmeter 安装bin路径下的jmeter.bat 发送快捷方…

用node.js搭建一个视频推流服务

由于业务中有不少视频使用的场景&#xff0c;今天来说说如何使用node完成一个视频推流服务。 先看看效果&#xff1a; 这里的播放的视频是一个多个Partial Content组合起来的&#xff0c;每个Partial Content大小是1M。 一&#xff0c;项目搭建 &#xff08;1&#xff09;初…

微信小程序纯前端从阿里云OSS下载json数据-完整版

起因 因为云开发开始收费(貌似很久了),准备改造在以前的小程序,数据转到oss上,小程序使用原生,不算专业领域, 所以先百度.... 网上的教程真的是千篇一律,大部分开局就是require(ali-oss); 好点的npm install ali-oss --save开局,拼凑操作到最后发现要用云开发,因为云…

在Orangepi5开发板3588s使用opencv获取摄像头画面

先感谢香橙派群的管理员耐心指导&#xff0c;经过不断的调试修改最后成功通过opencv调用mipi摄像头获取画面 就记录分享一下大概步骤希望大家少踩点坑&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 我用的固件系统是ubuntu2022.0.4 固件是&#x…

【jwt】JWT原理,JWT是用来解决什么问题的,如何自定义生成JWT数据,并且实现jwt数据的解码

JWT&#xff1a; JSON Web Token 1. jwt概述 用户登录成功后&#xff0c;服务端 如何知道客户端的每次请求对应的是哪个用户呢&#xff1f;怎么做&#xff1a;目前有两种方式实现. 1.1. 一是通过sessionId的方式&#xff0c;登录成功后服务端返回sessionId给客户端&#xff0…

Linux_10_进程、系统性能和计划任务

目录 1 进程和内存管理1.1 什么是进程1.2 进程结构1.3 进程相关概念1.3.1 物理地址空间和虚拟地址空间1.3.2 用户和内核空间1.3.3 C代码和内存布局之间的对应关系1.3.4 进程使用内存问题1.3.4.1 内存泄漏: Memory Leak1.3.4.2 内存溢出: Memory Overflow1.3.4.3 内存不足: OOM …

【STM32RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠)

硬件&#xff1a;STM32F103ZET6、ST-LINK、usb转串口工具、4个LED灯、1个蜂鸣器、4个1k电阻、2个按键、面包板、杜邦线 文章目录 前言一、线程管理接口介绍二、任务&#xff1a;使用多线程的方式同时实现led闪烁和按键控制喇叭&#xff08;扫描法&#xff09;1. RT-Thread相关接…

STM32 FLASH 读写数据

1. 《STM32 中文参考手册》&#xff0c;需要查看芯片数据手册&#xff0c;代码起始地址一般都是0x8000 0000&#xff0c;这是存放整个项目代码的起始地址 2. 编译信息查看代码大小&#xff0c;修改代码后第一次编译后会有这个提示信息 2.1 修改代码后编译&#xff0c;会有提示…

ant-design-vue在ios使用AUpload组件唤起了相机,HTML的 `capture` 属性

在使用ant design vue组件的上传组件AUpload的时候有一个问题&#xff0c;直接按照demo写&#xff0c;在ios上会唤起相机&#xff0c;但是实际上我们的需求是弹出选择相册/相机这个弹框。 解决办法是加一个 cupture"null"这个属性即可 <a-upload:capture"nu…

注册中心Eureka和Nacos,以及负载均衡Ribbon

1.初识微服务 1.1.什么是微服务 微服务&#xff0c;就是把服务拆分成为若干个服务&#xff0c;降低服务之间的耦合度&#xff0c;提供服务的独立性和灵活性。做到高内聚&#xff0c;低耦合。 1.2.单体架构和微服务架构的区别&#xff1a; 单体架构&#xff1a;简单方便&#…

【后端必看】Redis 最佳实践

文章目录 1. Redis 键值设计1.1 优雅的 key 结构1.2 拒绝 BigKeyBigKey的危害如何发现BigKey①redis-cli --bigkeys② scan 扫描③第三方监控④网络监控 如何删除 BigKey 1.3 恰当的数据类型总结&#xff1a; 2. 批处理优化3. 服务器端优化-持久化配置4. 服务器端优化-慢查询优…

浅谈OCR中的David Shepard

在OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;中&#xff0c;David Shepard是一种早期的OCR技术&#xff0c;也被称为Shepards Method。 David Shepard是该OCR方法的原始作者。这种方法基于边界追踪算法&#xff0c;用于识别印刷体文本…