Python 操作 HBase —— Trift Trift2 Happybase 安装使用

Python无法直接访问HBase,必须通过Thrift。

HBase与Thrift之间又支持两种接口标准,两种标准互不兼容,功能也互不覆盖。

Thrift连接HBase还有超时自动断开的大坑。

  • 安装Thrift依赖(Server端)

Centos: yum install automake libtool flex bison pkgconfig gcc-c++ boost-devel libevent-devel zlib-devel python-devel ruby-devel openssl-devel

Ubuntu: apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libboost-system-dev libboost-filesystem-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev

  • 安装Boost(Server端)

可以尝试yum/apt-get安装libboost1.53(或其他版本),安装完尝试Thrift是否正常启动,如果无法安装或安装完版本不兼容则手动下载安装

wget http://sourceforge.net/projects/boost/files/boost/1.53.0/boost_1_53_0.tar.gz

tar xvf boost_1_53_0.tar.gz

cd boost_1_53_0

./bootstrap.sh

./b2 install

cp /usr/local/lib/libboost_unit_test_framework.a /usr/lib/

  • 修改文件(安装Thrift报错:error: ‘uintptr_t’ was not declared)

vim /usr/local/include/boost/cstdint.hpp

第43行左右,将上面语句屏蔽,更新为下面语句
//#if defined(BOOST_HAS_STDINT_H) && (!defined(__GLIBC__) || defined(__GLIBC_HAVE_LONG_LONG))
#if defined(BOOST_HAS_STDINT_H) 
    && (!defined(__GLIBC__) 
    || defined(__GLIBC_HAVE_LONG_LONG) 
    || (defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) 
    && (__GLIBC_MINOR__ >= 17)))))
  • 安装Thrift(Server端)

从http://thrift.apache.org/下载最新版本的Thrift

tar -xvf thrift-0.12.0.tar.gz

cd thrift-0.12.0

./configure --libdir=/usr/lib

make

make install

  • 启动HBase-Thrift(Server端)

找到hbase-daemon.sh(如果是ambari安装则在/usr/hdp/版本号/hbase目录下面)

启动Thrift:hbase-daemon.sh start thrift

启动Thrift2:hbase-daemon.sh start thrift2

默认启动HBase与Thrift交互端口为9095,Thrift外部端口为9090

多个Thrift同时启动会端口冲突,可以通过--infoport 9096 -p 9091命令来指定内部和外部端口,同时还需要找到hbase-daemon.sh上层目录conf下面的hbase-site.xml,修改/新增hbase.thrift.info.port和hbase.regionserver.thrift.port配置,这个没有尝试过,不知道有没有其他坑

  • 配置HBase-Thrift(调用Thrift报错:TTransportException)

TTransportException错误分两种情况

一种是一条结果都获取不了,这种情况一般是使用问题,比如用Thrift2的接口调用Thrift,或者混淆了bytes和str

另一种情况是可以正常使用,但过几分钟莫名其妙就断了,这种是由于HBase配置有bug

需要在hbase-site.xml加入以下两项(如果设定超时时间为一天),然后重启HBase和Thrift

<property>
         <name>hbase.thrift.server.socket.read.timeout</name>
         <value>86400000</value>
</property>

<property>
         <name>hbase.thrift.connection.max-idletime</name>
         <value>86400000</value>
</property>
  • 安装Thrift/Thrift2环境(Client端)

pip install thrift

  • 使用Thrift方式一:pip安装(Client端)

pip install hbase-thrift

安装包安装到python安装目录lib/hbase或lib/site-packages/hbase下面

from thrift import Thrift
from thrift.transport import TSocket, TTransport
from thrift.protocol import TBinaryProtocol

# 连接
tsocket = TSocket.TSocket("10.0.0.1", 9090)
tsocket.setTimeout(5000)
ttransport = TTransport.TBufferedTransport(tsocket)
protocol = TBinaryProtocol.TBinaryProtocol(ttransport)

from hbase import Hbase

# 客户端
client = Hbase.Client(protocol)
tsocket.open()

#关键字
tableName = bytes("namespace:table", encoding='utf8')
rowkey = bytes("rowkey", encoding='utf8')

# 获取所有表名
tableNames = client.getTableNames()
print('tableNames:',tableNames)

# 获取列族
columnDescriptors = client.getColumnDescriptors(tableName)
print("columnName:",columnDescriptors)

# 获取行
row = client.getRow(tableName,rowkey)
print("row:",row)

使用hbase-thrift包的优点是包含的接口比较全面,比如获取所有tables、修改table属性等,缺点是读取方法很少,很多读取方法无法实现

  • 使用Thrift方式二:源码编译安装(Client端)

如果hbase使用的是源码安装包安装的,可以找到Server端源码其中的hbase/thrift/Hbase.thrift

或者上http://svn.apache.org/viewvc/hbase/trunk/hbase-thrift/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift下载最新版本的Hbase.thrift

执行thrift -r --gen py Hbase.thrift

当前目录下生成gen-py

将gen-py/hbase中的内容覆盖到Client端python安装目录的lib/hbase或lib/site-packages/hbase下面

from thrift import Thrift
from thrift.transport import TSocket, TTransport
from thrift.protocol import TBinaryProtocol

# 连接
tsocket = TSocket.TSocket("10.0.0.1", 9090)
tsocket.setTimeout(5000)
ttransport = TTransport.TBufferedTransport(tsocket)
protocol = TBinaryProtocol.TBinaryProtocol(ttransport)

from hbase import Hbase

# 客户端
client = Hbase.Client(protocol)
tsocket.open()

#关键字
tableName = bytes("namespace:table", encoding='utf8')
rowkey = bytes("rowkey", encoding='utf8')

# 获取所有表名
tableNames = client.getTableNames()
print('tableNames:',tableNames)

# 获取列族
columnDescriptors = client.getColumnDescriptors(tableName)
print("columnName:",columnDescriptors)

# 获取行
row = client.getRow(tableName,rowkey,attributes={})
print("row:",row)

最新官方的Hbase.thrift生成的包中包含了一些新接口新功能,如getRow()函数的attributes参数,但是实测并没有什么作用

  • 使用Thrift方式三:Happybase(Client端)

pip install happybase

import happybase

connect = happybase.Connection(host="10.0.0.1", port=9090)
connect.open()
table = connect.table("namespace:table")
print(table.row('rowkey', timestamp=1554277000000, include_timestamp=True))
connect.close()

happybase的优势是封装较好,使用方便

  • 使用Thrift2(Client端)

如果需要对表中的内容进行更细致的操作,比如提取某个时间段之间的columns,使用Thrift无法实现,只能使用Thrift2

找到源码包中的hbase/thrift2/hbase.thrift或者下载http://svn.apache.org/viewvc/hbase/trunk/hbase-thrift/src/main/resources/org/apache/hadoop/hbase/thrift2/hbase.thrift

执行thrift -r --gen py Hbase.thrift

将gen-py/hbase中的内容拷贝到Client端python安装目录的lib/hbase或lib/site-packages/hbase2(为了区分thrift与thrift2,如果不用共存也可命名为hbase或其他名称)

from thrift import Thrift
from thrift.transport import TSocket, TTransport
from thrift.protocol import TBinaryProtocol

# 连接
tsocket = TSocket.TSocket("10.0.0.2", 9090)
tsocket.setTimeout(5000)
transport = TTransport.TBufferedTransport(tsocket)
protocol = TBinaryProtocol.TBinaryProtocol(transport)

import hbase2

# 客户端
client = hbase2.THBaseService.Client(protocol)
tsocket.open()

# 获取行
get = TGet()
get.row = bytes("rowkey", encoding='utf8')
#get.timestamp = 1554278944040
get.timeRange = TTimeRange()
get.timeRange.minStamp = 1554277751530
get.timeRange.maxStamp = 1554277751550
result = client.get(bytes('namespace:table', encoding='utf8'), get)

 Thrift2的数据接口完善很多,可以实现一些Thrift无法实现的查询功能,但是不包含获取table列表之类的接口

参考文献:

https://www.cnblogs.com/zhang-ke/p/9008228.html

https://blog.csdn.net/caojinlei_91/article/details/82761157

https://blog.csdn.net/kelonsen/article/details/78477152

https://blog.51cto.com/13103353/2107257

https://blog.csdn.net/wwlhz/article/details/56012053

https://blog.csdn.net/qq_36330643/article/details/83106759

http://www.aiuxian.com/article/p-3104971.html

原文地址:https://www.cnblogs.com/jhc888007/p/10655785.html