编辑:此问题和答案适用于遇到主题行中所述异常的任何人: TTransportException(type = 4,message ='TSocket read 0 bytes');是否涉及Cloudera和/或HappyBase。
(事实证明)根本问题是由于
protocol
上的transport
和/或client-side
格式与server-side
所实现的格式不匹配而引起的,这可以任何客户端/服务器配对都会发生。我的恰好是 Cloudera和HappyBase,但您不一定要这么做,并且您可能会遇到同样的问题。
最近有没有人尝试使用happybase v1.1.0 (latest)
Python软件包与Hbase
上的Cloudera CDH v6.1.x
进行交互?
我正在尝试各种选项,但是不断出现异常:
thriftpy.transport.TTransportException:
TTransportException(type=4, message='TSocket read 0 bytes')
这是我开始会话并提交简单呼叫以获取表列表的方式(使用Python v3.6.7
:
import happybase
CDH6_HBASE_THRIFT_VER='0.92'
hbase_cnxn = happybase.Connection(
host='vps00', port=9090,
table_prefix=None,
compat=CDH6_HBASE_THRIFT_VER,
table_prefix_separator=b'_',
timeout=None,
autoconnect=True,
transport='buffered',
protocol='binary'
)
print('tables:', hbase_cnxn.tables()) # Exception happens here.
这是Cloudera CDH v6.1.x
启动Hbase Thrift
服务器的方式(为简洁起见,被缩短了):
/usr/java/jdk1.8.0_141-cloudera/bin/java [... snip ... ] \
org.apache.hadoop.hbase.thrift.ThriftServer start \
--port 9090 -threadpool --bind 0.0.0.0 --framed --compact
我已经尝试了几种选项的变体,但是一无所获。
有人能用到它吗?
编辑:
接下来,我编译了Hbase.thrift
(来自Hbase
源文件-与HBase
使用的CDH v6.1.x
版本相同),并使用了Python thrift
绑定包(其他的话,我从等式中删除了happybase
并得到了相同的例外。
(._。);
谢谢!
答案 0 :(得分:1)
经过一天的努力,我的问题的答案如下:
import happybase
CDH6_HBASE_THRIFT_VER='0.92'
hbase_cnxn = happybase.Connection(
host='vps00', port=9090,
table_prefix=None,
compat=CDH6_HBASE_THRIFT_VER,
table_prefix_separator=b'_',
timeout=None,
autoconnect=True,
transport='framed', # Default: 'buffered' <---- Changed.
protocol='compact' # Default: 'binary' <---- Changed.
)
print('tables:', hbase_cnxn.tables()) # Works. Output: [b'ns1:mytable', ]
请注意,尽管此问答是在Cloudera
的背景下进行的,但事实证明(如您所见)这是Thrift
版本和Thrift
与服务器端配置相关的,因此它也适用于Hortonworks
和MapR
用户。
说明:
在Cloudera CDH v6.1.x
(可能还有将来的版本)上,如果您访问其管理U.I.的Hbase Thrift Server Configuration
部分,您会发现-以下是许多其他设置:
请注意,compact protocol
和framed transport
均已启用;因此需要在happybase
中更改其默认值(我在上面显示)。
正如我对第一个问题的 EDIT 后续文章中所述,我还研究了一种纯Thrift
(非happybase
)解决方案。在这种情况下,通过对Python代码进行类似的更改,我也可以正常工作。这是您应用于纯Thrift
解决方案的代码(请注意阅读下面的评论):
from thrift.protocol import TCompactProtocol # Notice the import: TCompactProtocol [!]
from thrift.transport.TTransport import TFramedTransport # Notice the import: TFramedTransport [!]
from thrift.transport import TSocket
from hbase import Hbase
# -- This hbase module is compiled using the thrift(1) command (version >= 0.10 [!])
# and a Hbase.thrift file (obtained from http://archive.apache.org/dist/hbase/
# -- Also, your "pip freeze | grep '^thrift='" should show a version of >= 0.10 [!]
# if you want Python3 support.
(host,port) = ("vps00","9090")
transport = TFramedTransport(TSocket.TSocket(host, port))
protocol = TCompactProtocol.TCompactProtocol(transport)
client = Hbase.Client(protocol)
transport.open()
# Do stuff here ...
print(client.getTableNames()) # Works. Output: [b'ns1:mytable', ]
transport.close()
我希望这可以减轻人们经历的痛苦。 =:)
信用: