4.7 在Python下使用HBase

一、前期工作

在Linux(我用的Ubuntu18.04)已经安装好Apache Hadoop2和Anaconda3,并已经安装了HBase(可参考4.6 HBase基本使用实践)

二、新建Python环境

先新建一个Python环境(如果使用之前建立好的则可以忽略此步骤)。
在shell中输入以下命令

$ conda create -n hadoop python=3.7

这样就创建了一个名为hadoop的python3.7环境。
然后激活此环境

$ conda activate hadoop

三、安装thrift和happybase

thrift 是facebook开发并提交给Apache的开源二进制通讯中间件通过thrift,我们可以用Python来操作Hbase。
happybase是Python通过Thrift访问HBase的库。
在上述Python环境下输入如下命令来安装thrift和happybase

pip install thrift
pip install happybase

注意:安装happybase可能会遇到错误

    unable to execute 'gcc': No such file or directory
    error: command 'gcc' failed with exit status 1

这是因为没有安装gcc(GNU Compiler Collection)。执行

sudo apt-get install gcc

安装好gcc后,再重新执行happybase安装命令即可。

四、启动HBase for Python

这里使用伪分布模式的HBase(配置方法参考https://www.jianshu.com/p/11f15025d6b2
假设现在刚启动计算机(没有进入任何环境),首先启动HDFS——因为我已经把HDFS的目录添加在.bashr的PATH了,所以可以不加目录

$ start-dfs.sh #或输入完全路径/usr/local/hadoop/sbin/start-dfs.sh

接着启动HBase

$ start-hbase.sh #或输入完全路径/usr/local/hbase/bin/start-hbase.sh

以上是HBase核心启动过程(通常使用HBase都要有的步骤),下面是Python使用HBase的必要步骤。
启动thrift

$ hbase-daemon.sh start thrift

这时可以输入jps查看已启动的Java进程

4512 HQuorumPeer
3121 DataNode
5298 Jps
2914 NameNode
3379 SecondaryNameNode
5172 ThriftServer
4777 HRegionServer
4634 HMaster

Jps是Java的主进程,NameNode、SecondaryNameNode和DataNode是HDFS的进程,HMaster、HRegionServer和HQuorumPeer是HBase的进程,ThriftServer是Thrift的进程。八个进程都出现说明启动成功。

如果使用完毕要退出,则依次输入以下命令:
hbase-daemon.sh stop thrift
stop-hbase.sh
stop-dfs.sh

然后我们可以进入刚才建立的conda环境

$ conda activate hadoop

我使用Spyder来写Python脚本。如果没有安装,可输入

$ conda install spyder

安装好之后,输入

$ spyder

即进入Python IDE环境。
注意如果启动了SSH则可能无法使用Spyder(报错“QXcbConnection: Could not connect to display”)。如果不想使用IDE,也可以直接输入“python”进入Python命令行来操作。

五、Python下操作HBase

1. 创建HBase连接

在Python环境下,引入happybase库

import happybase

创建HBase连接

conn=happybase.Connection() #等效于conn=happybase.Connection()

其默认设置是

happybase.Connection(host=‘localhost’, port=9090, timeout=None, autoconnect=True, table_prefix=None, table_prefix_separator=b’_’, compat=‘0.98’, transport=‘buffered’, protocol=‘binary’)

连接建立好之后查看可以使用的table

print(conn.tables())

用其他方式(如shell)在HBase建立的table也会显示出来。如果还没有建立任何表则返回

[]

2. 新建表

创建表一个名为student2的表,包含五个属性(即列族)Sname、Ssex、Sage、Sdept和course

conn.create_table(
    'student2',
    {
        'Sname': dict(max_versions=10),
        'Ssex': dict(),
        'Sage': dict(),
        'Sdept': dict(),
        'course': dict()
    }
)

max_versions是指定最多保留的版本数,可缺省。
这时再输入

print(conn.tables())

则返回

[b'student2']

3. 添加数据

要操作已经创建的表,则先获取其table实例

ts=conn.table('student2')

添加主键(默认,可视为学号)为95001,名字(Sname列族)为YangXing的一行数据——注意所有输入都必须是字符串

ts.put(row='95001',data={'Sname:':'YangXing','course:math':'90'})

注意即使没有列限定符冒号也不能省(如上面的“Sname:”),这点和shell操作HBase不同。
put方法每输入一行都要和HBase通信一次,如果想多行一次性批量写入HBase可以使用batch

bat = ts.batch()
bat.put(row='95001',data={'course:english':'82'})
bat.put(row='93020',data={'Sname:':'WeiLiu','course:math':'87'})
bat.send()

为方便可利用上下文管理器with/as实现

with ts.batch() as bat:
    bat.put(row='95001',data={'course:english':'82'})
    bat.put(row='93020',data={'Sname:':'WeiLiu','course:math':'87'})

4. 查看数据

这里介绍三种方法:row、rows和scan。功能不同,酌情使用。

(1) row

如果想获取一行的数据,如行号95001

ts.row('95001')

输出

{b'Sname:': b'YangXing', b'course:english': b'82', b'course:math': b'90'}

如果想获取某行的某列族,如行号95001的course列族

ts.row(row='95001',columns=['course'])

注意course后不能加冒号,输出

{b'course:english': b'82', b'course:math': b'90'}

即输出此列族的所有列限定符内容。
如果想获取某行的某列族的某列限定符内容,如行号95001的course列族的english列

ts.row(row='95001',columns=['course:english'])

输出

{b'course:english': b'82'}

另外,可以通过设定来显示时间戳

ts.row(row='95001',columns=['course:english'],include_timestamp=True)

输出

{b'course:english': (b'82', 1587562954464)}

注意columns只能传入list或tuple,如[course]或(course,)。

(2) rows

可使用rows来获取多行

ts.rows(rows=['95001','93020'])

输出

[(b'95001', {b'Sname:': b'YangXing', b'course:english': b'82', b'course:math': b'90'}),
 (b'93020', {b'Sname:': b'WeiLiu', b'course:math': b'87'})]

也可指定列族

ts.rows(rows=['95001','93020'],columns=['course'])

输出

[(b'95001', {b'course:english': b'82', b'course:math': b'90'}),
 (b'93020', {b'course:math': b'87'})]

甚至列限定符

ts.rows(rows=['95001','93020'],columns=['course:math'])

输出

[(b'95001', {b'course:math': b'90'}), (b'93020', {b'course:math': b'87'})]

同row一样,rows也可以设置include_timestamp=True来显示时间戳。

(3) scan

如果想遍历整个表的所有内容

for key,value in ts.scan():
    print(key,value)

输出

b'93020' {b'Sname:': b'WeiLiu', b'course:math': b'87'}
b'95001' {b'Sname:': b'YangXing', b'Sname:a': b'ss', b'course:english': b'82', b'course:math': b'90'}

也可设置起始行键(行键的顺序由系统自动排列)

for key,value in ts.scan(row_start='95001'):
    print(key,value)

输出

b'95001' {b'Sname:': b'YangXing', b'Sname:a': b'ss', b'course:english': b'82', b'course:math': b'90'}

或终止行键

for key,value in ts.scan(row_stop='95001'):
    print(key,value)

输出

b'93020' {b'Sname:': b'WeiLiu', b'course:math': b'87'}
[b'student', b'student2', b'zhy']

也可以row_start和row_stop同时设定,注意是前闭后开区间。
同row一样,scan也可以设置include_timestamp=True来显示时间戳。

5. 删除数据

使用delete命令删除某行的若干列族/列数据。注意delete命令会删除所有历史数据(类似于shell的deleteall)。
删除一整行,如93020行

ts.delete(row='93020')

执行后93020这行的所有数据(包括任何列的所有历史版本)都被删除
删除某行某列族,如95001行的course列族

ts.delete(row='95001',columns=['course'])

注意course后面没有冒号
删除某行某列族某列,如95001行的course列族的english列

ts.delete(row='95001',columns=['course:english'])

Reference:
https://blog.csdn.net/qq_21153619/article/details/82619925
https://www.jianshu.com/p/62f687ba0c11
https://blog.csdn.net/weixin_33860722/article/details/92385409
https://blog.csdn.net/ytusdc/article/details/78679100
https://www.cnblogs.com/tashanzhishi/p/10917956.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,367评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,959评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,750评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,226评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,252评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,975评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,592评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,497评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,027评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,147评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,274评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,953评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,623评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,143评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,260评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,607评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,271评论 2 358

推荐阅读更多精彩内容