Cloudera / CDH v6.1.x + Python HappyBase v1.1.0:TTransportException(type = 4,message ='TSocket read 0 bytes')

问题描述 投票:0回答:1

编辑:此问题和答案适用于遇到主题行中所述异常的任何人: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)并获得了相同的异常。

(._.);

谢谢!

python hbase thrift cloudera-cdh happybase
1个回答
2
投票

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

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', ]

请注意,虽然这个Q&A是在Cloudera的背景下构建的,但事实证明(正如您将看到的)这是Thrift版本和Thrift服务器端配置相关,因此它也适用于HortonworksMapR用户。

说明:

Cloudera CDH v6.1.x(也可能是未来版本)上,如果你访问其管理U.I.的Hbase Thrift Server Configuration部分,你会发现 - 在许多其他设置中 - 这些:


CDH6.1.x Hbase Thrift Server Configuration U.I.

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

我希望这能让人们痛苦地度过难关。 = :)

鸣谢:

© www.soinside.com 2019 - 2024. All rights reserved.