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