«TSocket прочитал 0 байт» во время длительного выполнения запроса вставки куста - PullRequest
0 голосов
/ 05 октября 2018

Я выполняю длинный запрос вставки в Hive с использованием PyHive 0.6.1, и он завершается неудачно с thrift.transport.TTransport.TTransportException: TSocket read 0 bytes примерно через 5 минут работы.На стороне сервера запрос продолжает выполняться до успешного завершения.У меня нет этой проблемы с быстрыми запросами.

Я не могу воспроизвести это локально на моем Mac с той же версией Python: код корректно ждет, пока запрос не завершится.Среда, в которой это происходит, - это контейнер Docker, основанный на python: 3.6-slim.Помимо прочего, я устанавливаю пакеты libsasl2-dev и libsasl2-modules, а также пакет pyhive [hive] python.

Любая подсказка, почему это происходит?Заранее спасибо.

Код, который я использую:

import contextlib
from pyhive.hive import connect

def get_conn():
    return connect(
        host='my-host',
        port=10000,
        auth='NONE',
        username='username',
        database='database'
    )

with contextlib.closing(get_conn()) as conn, \
        contextlib.closing(conn.cursor()) as cur:
    cur.execute('My long insert statement')

Это полный возврат

Traceback (most recent call last):
  File "<stdin>", line 5, in <module>
  File "/usr/local/lib/python3.6/site-packages/pyhive/hive.py", line 364, in execute
    response = self._connection.client.ExecuteStatement(req)
  File "/usr/local/lib/python3.6/site-packages/TCLIService/TCLIService.py", line 280, in ExecuteStatement
    return self.recv_ExecuteStatement()
  File "/usr/local/lib/python3.6/site-packages/TCLIService/TCLIService.py", line 292, in recv_ExecuteStatement
    (fname, mtype, rseqid) = iprot.readMessageBegin()
  File "/usr/local/lib/python3.6/site-packages/thrift/protocol/TBinaryProtocol.py", line 134, in readMessageBegin
    sz = self.readI32()
  File "/usr/local/lib/python3.6/site-packages/thrift/protocol/TBinaryProtocol.py", line 217, in readI32
    buff = self.trans.readAll(4)
  File "/usr/local/lib/python3.6/site-packages/thrift/transport/TTransport.py", line 60, in readAll
    chunk = self.read(sz - have)
  File "/usr/local/lib/python3.6/site-packages/thrift_sasl/__init__.py", line 166, in read
    self._read_frame()
  File "/usr/local/lib/python3.6/site-packages/thrift_sasl/__init__.py", line 170, in _read_frame
    header = self._trans.readAll(4)
  File "/usr/local/lib/python3.6/site-packages/thrift/transport/TTransport.py", line 60, in readAll
    chunk = self.read(sz - have)
  File "/usr/local/lib/python3.6/site-packages/thrift/transport/TSocket.py", line 132, in read
    message='TSocket read 0 bytes')
thrift.transport.TTransport.TTransportException: TSocket read 0 bytes

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 5, in <module>
  File "/usr/local/lib/python3.6/contextlib.py", line 185, in __exit__
    self.thing.close()
  File "/usr/local/lib/python3.6/site-packages/pyhive/hive.py", line 221, in close
    response = self._client.CloseSession(req)
  File "/usr/local/lib/python3.6/site-packages/TCLIService/TCLIService.py", line 218, in CloseSession
    return self.recv_CloseSession()
  File "/usr/local/lib/python3.6/site-packages/TCLIService/TCLIService.py", line 230, in recv_CloseSession
    (fname, mtype, rseqid) = iprot.readMessageBegin()
  File "/usr/local/lib/python3.6/site-packages/thrift/protocol/TBinaryProtocol.py", line 134, in readMessageBegin
    sz = self.readI32()
  File "/usr/local/lib/python3.6/site-packages/thrift/protocol/TBinaryProtocol.py", line 217, in readI32
    buff = self.trans.readAll(4)
  File "/usr/local/lib/python3.6/site-packages/thrift/transport/TTransport.py", line 60, in readAll
    chunk = self.read(sz - have)
  File "/usr/local/lib/python3.6/site-packages/thrift_sasl/__init__.py", line 166, in read
    self._read_frame()
  File "/usr/local/lib/python3.6/site-packages/thrift_sasl/__init__.py", line 170, in _read_frame
    header = self._trans.readAll(4)
  File "/usr/local/lib/python3.6/site-packages/thrift/transport/TTransport.py", line 60, in readAll
    chunk = self.read(sz - have)
  File "/usr/local/lib/python3.6/site-packages/thrift/transport/TSocket.py", line 132, in read
    message='TSocket read 0 bytes')
thrift.transport.TTransport.TTransportException: TSocket read 0 bytes

1 Ответ

0 голосов
/ 05 октября 2018

Исключение для кода приведено ниже:

  def read(self, sz):
        try:
            buff = self.handle.recv(sz)
        except socket.error as e:
            if (e.args[0] == errno.ECONNRESET and
                    (sys.platform == 'darwin' or sys.platform.startswith('freebsd'))):
                # freebsd and Mach don't follow POSIX semantic of recv
                # and fail with ECONNRESET if peer performed shutdown.
                # See corresponding comment and code in TSocket::read()
                # in lib/cpp/src/transport/TSocket.cpp.
                self.close()
                # Trigger the check to raise the END_OF_FILE exception below.
                buff = ''
            else:
                raise
        if len(buff) == 0:
            raise TTransportException(type=TTransportException.END_OF_FILE,
                                      message='TSocket read 0 bytes')
        return buff

Я думаю, что это может быть вызвано ошибкой errno.ECONNRESET, которая может возникнуть, когда сервер намеренно закрыл соединение.(Согласно этому node-js-econnreset , сервер может прервать соединение, если он слишком занят и обнаружил, что соединение истекло по тайм-ауту «keep-alive») *

Вы можете проверить свойлоги сервера и выясните, существует ли какое-то поведение, вызывающее разрыв соединения.

Я не уверен в этом, просто размышляю.

...