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

РЕДАКТИРОВАТЬ: Этот вопрос и ответ относится ко всем, кто испытывает исключение, указанное в строке темы: 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) и использовал Питон thrift пакет привязок (другими словами, я удалил happybase из уравнения) и получил то же исключение.

(._.);

Спасибо!

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

Обратите внимание, что хотя этот вопрос и ответы были сформулированы в контексте Cloudera оказывается (как вы увидите), что это было Thrift версии и Thrift Конфигурации на стороне сервера, связанные, и поэтому это относится к Hortonworks а также MapR пользователи тоже.

Пояснение:

На Cloudera CDH v6.1.x (и, вероятно, будущие версии тоже), если вы посетите 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()

Я надеюсь, что это избавит людей от боли, через которую я прошел. знак равно

КРЕДИТЫ:

Я также столкнулся с этой проблемой, когда использовал CDH 6.3.2 HBaseв последнее время. Недостаточно следовать указанной выше конфигурации. Также нужно закрыть hbase.regionserver.thrift.http а также hbase.thrift.support.proxyuser для успешного подключения

Другие вопросы по тегам