hbase报错TTransportException(type=4,message=’TSocket read 0 bytes’)解决方案

hbase报错TTransportException(type=4,message=’TSocket read 0 bytes’)解决方案

(1)报错信息:

thrift.transport.TTransport.TTransportException: TSocket read 0 bytes

(2)产生原因:

可能是因为thrift 的server端和client端的协议不匹配造成的。
Python要使用TCompactProtocol,而不能使用TBinaryProtocol。
TBinaryProtocol:缺省简单的二进制序列化协议。
TCompactProtocol:高效的二进制序列化协议。

(3)解决办法:

1.在服务端修改hbase-site.xml,增加TFramedTransport和TCompactProtocol功能,即:

   <property>
      <name>hbase.regionserver.thrift.framed</name>
     <value>true</value>
   </property>
   <property>
      <name>hbase.regionserver.thrift.compact</name>
      <value>true</value>
   </property>

2.然后重启thrift:$HBASE_HOME/bin/hbase-daemon.sh restart thrift

3.在客户端建立连接时增加protocol,transport参数:

conn = happybase.Connection(host="10.255.111.92",port=9090)
#修改为:
conn = happybase.Connection(host="10.255.111.92",port=9090,protocol='compact',transport='framed')
(4)然而问题并没有解决!!!(重点)

经过测试脚本测试(建立连接往Hbase写入一条数据然后time.sleep(601)之后再次写入一条数据)发现又出现了TTransportException(type=4, message=‘TSocket read 0 bytes’)的报错,继续排查原因。
看到一个网页内容:

问题背景

测试环境是三台服务器搭建的Hadoop分布式环境。Hadoop版本是:hadoop-2.7.3;Hbase-1.2.4; 
zookeeper-3.4.9。 
使用thrift c++接口向hbase中写入数据,每次都是刚开始写入正常,过一段时间就开始报错。 
但之前使用的hbase-0.94.27版本就没遇到过该问题,配置也相同,一直用的好好地。

thrift接口报错

解决办法

通过抓包可以看出,hbase server响应了RST包,导致连接中断。 
通过 bin/hbase thrift start -threadpool命令可以readTimeout的设置为60s。

thriftpool

经过验证却是和这个设置有关,配置中没有配置过该项,通过查看代码发现60s是默认值,如果没有配置即按照以该值为准。

因此在conf/hbase-site.xml中添加上配置即可:

<property>
         <name>hbase.thrift.server.socket.read.timeout</name>
         <value>6000000</value>
         <description>eg:milisecond</description>
</property>

然而问题在一段时间之后又一次出现了,又开始了查找原因发现是hbase该版本自带的问题,它将所有连接(不管有没有在使用)都默认为idle的状态,然后有个hbase.thrift.connection.max-idletime的配置,所以我将此项配置为31104000(一年),问题解决了!
解决方法
即在hbase-site.xml增加了如下内容,并重新启动thrift和hbase,问题得到解决

<property>
         <name>hbase.thrift.server.socket.read.timeout</name>
         <value>6000000</value>
</property>
<property>
    <name>hbase.thrift.connection.max-idletime</name>
    <value>31104000</value>
</property>

2021年1月15更新:
问题又一次出现了,经过了多次尝试hbase.thrift.server.socket.read.timeout参数并不是秒为单位的
当将该值设置为70000时候 通过脚本向HBase写入数据间隔69秒写入一次 没有报错 但将间隔时间设置为71秒之后又出现了thriftpy2.transport.base.TTransportException: TTransportException(type=4, message=‘TSocket read 0 bytes’)的报错,所以推测出hbase.thrift.server.socket.read.timeout参数的单位为毫秒 我将此参数设置成了86400000(一天)问题得到了解决

<property>
         <name>hbase.thrift.server.socket.read.timeout</name>
         <value>86400000</value>
</property>
<property>
    <name>hbase.thrift.connection.max-idletime</name>
    <value>31104000</value>
</property>

2022年6月9日更新:
可以尝试使用hbase连接池的方式(待验证)

import happybase
import json

# 通过size控制连接池中的连接数量
pool = happybase.ConnectionPool(size=3,host="10.255.111.92",port=9090,protocol='compact',transport='framed')
# 从连接池中取出一个连接
with pool.connection() as conn:
    table = conn.table('test_table')
    # TODO 执行操作
    pass
    # 操作完成 及时close 保证每次操作都是一个新启动的连接
    conn.close()

参考链接:
https://blog.51cto.com/13103353/2107257

  • 10
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值