我正在使用 PyHive 0.6.1 在 Hive 中运行一个较长的插入查询,运行大约 5 分钟后失败并显示
thrift.transport.TTransport.TTransportException: TSocket read 0 bytes
。在服务器端,查询将继续运行,直到成功完成。我在快速查询时没有这个问题。
我无法使用相同的 python 版本在我的 Mac 上本地重现它:代码正确地等待查询完成。发生这种情况的环境是基于 python:3.6-slim 的 Docker 容器。除此之外,我正在安装 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
引发异常的代码如下:
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”超时时终止连接)
您可以检查一下您的服务器日志,看看是否存在某种杀连接行为。
我不太确定,只是提供我的想法。
您找到这个问题的答案了吗?我遇到了同样的问题