0

编辑:此问题和答案适用于遇到主题行中所述异常的任何人:TTransportException(type=4, message='TSocket read 0 bytes') ; 是否涉及 Cloudera 和/或 HappyBase。

根本问题(事实证明)源于与正在实现的内容不匹配protocol和/或transport格式,这可能发生在任何客户端/服务器配对中。我的恰好是Cloudera 和 HappyBase,但你的不一定是,你可能会遇到同样的问题。client-sideserver-side

最近有没有人尝试使用happybase v1.1.0 (latest)Python 包与Hbaseon交互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)并使用 Pythonthrift绑定包(换句话说,我happybase从等式中删除)并得到相同的异常。

(._.);

谢谢!

4

2 回答 2

3

经过一天的努力,我的问题的答案如下:

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(也可能是未来的版本)上,如果您访问Hbase Thrift Server Configuration其管理 UI 的部分,您会发现——在许多其他设置中——这些:


CDH6.1.x Hbase Thrift 服务器配置 UI

请注意compact protocolframed 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()

我希望这能让人们免于我所经历的痛苦。=:)

学分

于 2019-02-13T02:57:21.913 回答
0

CDH 6.3.2 HBase最近使用的时候也遇到了这个问题。仅遵循上述配置是不够的。hbase.regionserver.thrift.http也需要关闭hbase.thrift.support.proxyuser才能连接成功

于 2021-10-24T16:09:16.497 回答