问题

在通过Go连接hbase的过程中, 发现 get操作可以查到数据, 但是scanner命令访问数据失败, 也没有报错, 就是单纯的查不到数据. 而且Python PHP都一切正常.

这里简单复述一下我出现问题的情况, 安装过程和网上大部分内容一致, 这里简单列一下, 只是为了查询问题时参考安装过程的差异:

# 安装hbase
wget -O /opt/hbase.tar.gz https://dlcdn.apache.org/hbase/2.4.11/hbase-2.4.11-bin.tar.gz
tar -xzf /opt/hbase.tar.gz -C /opt/
rm /opt/hbase.tar.gz
# 安装thrift
apt install -y libboost-dev  \libboost-test-dev  \libboost-program-options-dev  \libevent-dev  \automake  \libtool  \flex  \bison  \pkg-config  \g++  \libssl-dev \gcc  \autoconf \make \&& wget -O /opt/thrift.tar.gz https://dlcdn.apache.org/thrift/0.16.0/thrift-0.16.0.tar.gz \&& tar -xzf /opt/thrift.tar.gz -C /opt \&& rm /opt/thrift.tar.gz \&& cd /opt/thrift-0.16.0 \&& ./configure \&& make \&& make install
# 测试使用, 将hbase服务改为单机模式
cat > /opt/hbase-2.4.11/conf/hbase-site.xml <<- EOF
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration><!-- hbase存放数据目录 --><property><name>hbase.rootdir</name><value>file:///data/hbase</value></property><!-- ZooKeeper数据文件路径 --><property><name>hbase.zookeeper.property.dataDir</name><value>/data/zookeeper</value></property><property><name>hbase.unsafe.stream.capability.enforce</name><value>false</value></property>
</configuration>
EOF
# 启动hbase服务
/opt/hbase-2.4.11/bin/start-hbase.sh
# 启动htrift服务
/opt/hbase-2.4.11/bin/hbase-daemon.sh start thrift2 -p 9091# 生成go和python的thrift工具文件
wget -O ~/hbase_src.tar.gz https://dlcdn.apache.org/hbase/2.4.11/hbase-2.4.11-src.tar.gz
tar -xzf ~/hbase_src.tar.gz -C ~
cd ~/hbase-2.4.11/hbase-thrift/src/main/resources/org/apache/hadoop/hbase/thrift2
thrift --gen go hbase.thrift
thrift --gen py hbase.thrift

服务启动后, 使用GO进行查询(其中test表已经提前放入数据):

transport, err := thrift.NewTSocket(net.JoinHostPort("127.0.0.1", "9091"))
if err != nil {panic(err)
}
protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
client := hbase.NewTHBaseServiceClientFactory(transport, protocolFactory)
transport.Open()
scan := &hbase.TScan{}
ret, err := client.GetScannerResults(context.Background(), []byte("test"), scan, 100)
if err != nil {panic(err)
}
fmt.Println("scanner result")
fmt.Println(ret)

发现使用go查询不到数据???这个就奇怪了, 因此开始进行检查(简单复现一下问题查询步骤).

原因追溯

首先, 在使用GO查询之前已经使用hbase shell连接过了, 因此可以确定不是hbase启动失败的问题. 因此思考各种问题逐一排查.

端口未开启

使用命令telnet 127.0.0.1 9091进行验证, 端口没有问题, 可以排除.

是否仅Go有问题

使用python php进行连接并访问相同方法, 发现是有返回数据的, Python代码:

from thrift.transport import TSocket
from thrift.protocol import TBinaryProtocol
from thrift.transport import TTransport
from hbase import THBaseService
from hbase.ttypes import TScanif __name__ == '__main__':transport = TTransport.TBufferedTransport(TSocket.TSocket('127.0.0.1', 9091))protocol = TBinaryProtocol.TBinaryProtocolAccelerated(transport)client = THBaseService.Client(protocol)transport.open()# 使用 client 实例进行操作ret = client.getScannerResults(table="test",tscan=TScan(),numRows=100)print(ret)transport.close()

由此可以证明, thrift也没有问题, 一定是Go在连接的时候出了问题.

是否Go所有方法都有问题

尝试调用thrift其他方法, 判断是仅scanner方法有问题, 还是所有方法都有问题:

tGet := hbase.TGet{Row: []byte("row1"), // row1 数据是存在的
}
getRet, err := client.Get(context.Background(), []byte("test"), &tGet)
if err != nil {panic(err)
}
fmt.Println("get result")
fmt.Println(getRet)

查询后发现, Get方法是可以获取到数据的, 那么, 就是说仅GoGetScannerResults方法是有问题的???

当问题追溯到这里的时候, 我已经有些懵了, 尝试这谷歌查找原因, 各种关键词都试过了, 没有找到想要的答案(这也是为什么我要把这个错记下来, 因为没查到啊)

抓包比较差异

找了半天没有找到问题, 既然Python可以查到数据 而Go查不到, 那么, 就可以尝试抓包比较两者差异了嘛.

依然使用上面的GetScannerResults, 分别对pythongo进行抓包分析, 通过命令tmpdump port 9091 -w thrift.cap:

可以看到, 其中的thrift请求也能够被wireshark识别了, 那就太好了, 不用比较二进制了, 来看一下两个请求的区别:

Python请求如下:

Go请求如下:

其中, 有一个字段两个是明显不一样的, 我很贴心的用红框圈出来了, 那么, 问题来了, 这个字段是什么呢? 我把上面的hbase.thrift文件中的一部分拿出来, 就很明显了:

/*** Any timestamps in the columns are ignored but the colFamTimeRangeMap included, use timeRange to select by timestamp.* Max versions defaults to 1.*/
struct TScan {1: optional binary startRow,2: optional binary stopRow,3: optional list<TColumn> columns4: optional i32 caching,5: optional i32 maxVersions=1,6: optional TTimeRange timeRange,7: optional binary filterString,8: optional i32 batchSize,9: optional map<binary, binary> attributes10: optional TAuthorization authorizations11: optional bool reversed12: optional bool cacheBlocks13: optional map<binary,TTimeRange> colFamTimeRangeMap14: optional TReadType readType15: optional i32 limit16: optional TConsistency consistency17: optional i32 targetReplicaId18: optional binary filterBytes}service THBaseService {/*** Get results for the provided TScan object.* This helper function opens a scanner, get the results and close the scanner.** @return between zero and numRows TResults*/list<TResult> getScannerResults(/** the table to get the Scanner for */1: required binary table,/** the scan object to get a Scanner for */2: required TScan tscan,/** number of rows to return */3: i32 numRows = 1) throws (1: TIOError io)
}

虽然我没用过thrift, 但是看着这个数据包, 在看看这个数据结构的定义, 很明显Field Id就是定义文件中前面的数字啊.

很好, 这就可以定位到不用的字段为: maxVersion, 而这个字段指定了返回的版本数量, 0个版本自然就没有数据咯.

解决

既然查询到时因为maxVersion字段不同而导致的问题, 那么在查询的时候手动指定即可. 修改代码后重试:

scan := &hbase.TScan{maxVersion: 1
}
ret, err := client.GetScannerResults(context.Background(), []byte("test"), scan, 100)
if err != nil {panic(err)
}
fmt.Println("scanner result")
fmt.Println(ret)

OK, 现在有数据了, 查半天没想到是这个问题. 至此, 问题解决…

我是不懂为什么不同语言访问还有这种差异? 是因为字段的默认值不同? 搞不懂.

再顺便提一句, 难道大家都没有碰到这个问题么? 我搁网上查了半天, 愣是没找到一个沾边的…若你也碰到了这个问题, 希望能够帮到你

原文地址: https://hujingnb.com/archives/767

hbase/thrift/go连接失败相关推荐

  1. HBase thrift C++编程

    HBase & thrift & C++编程.pdf 目录 目录 1 1. 前言 1 2. 启动和停止thrift2 1 2.1. 启动thrift2 1 2.2. 停止thrift2 ...

  2. HBase: Thrift写数据报错——socket.error: [Errno 32] Broken pip

    博主用的是python来读写hbase 需要安装 pip install thrift 和 pip install hbase-thrift hbase客户端创建: from thrift impor ...

  3. php hbase thrift,PHP使用Thrift操作Hbase

    系统架构图 HBase 启动 Thrift服务 hbase启动thrift服务 // 进入安装的hbase bin目录下 // 执行 hbase-daemon.sh start thrift2 需要注 ...

  4. 华为更新云空间配置 显示无法连接服务器,更新服务器连接失败

    更新服务器连接失败 内容精选 换一换 本章节指导您使用MongoDB客户端和Robo 3T工具,通过公网连接GaussDB(for Mongo)集群实例.操作系统使用场景:弹性云服务器的操作系统以Li ...

  5. 手机备份显示连接服务器失败,备份服务器连接失败

    备份服务器连接失败 内容精选 换一换 edgectl解析域名失败.域名不存在节点未配置DNS服务器节点无法连接DNS服务器DNS服务器不工作依次检查:在域名解析服务正常的节点上尝试解析对应域名,看是否 ...

  6. mysql刷新连接_MYSQL频繁出现连接失败,刷新后正常的解决办法

    服务器出现MYSQL频繁掉线,提示连接失败,刷新后又正常的问题.刚开始还以为是mysql连接数的问题,改了无数次,还是一样没解决问题.后来终于找到什么原因了!微软9月9日发布了TCP/IP更新补丁(K ...

  7. centos mysql拒绝连接失败_CentOS下mysql远程连接的失败的解决方法

    mysql远程连接失败的解决方法(CentOS版) (1)先将mysql服务停掉 # /etc/init.d/mysqld stop (2)查看mysql配置文件 # vi /etc/my.cnf 特 ...

  8. 有道云笔记 网络连接失败

    今天有道云老是提示 网络连接失败,按照他官网上的操作去做,到最后还是不生效.我当时就不想用有道云笔记了.草! 忙了一上午,终于可以了. 在有道云设置里面,给他设置代理.我想,或许是因为我们公司的网络是 ...

  9. 屏蔽firefox浏览器连接失败页面的广告

    现象 最近一直在使用firefox浏览器(版本:57.0.1(64位)),同步书签特别方便,但是最近发现当访问的一个不存在的网址时,连接失败页面竟然有广告!firefox不是号称没有广告吗? 分析 F ...

最新文章

  1. 安装eclipse的maven插件
  2. opencv 释放内存
  3. office2016打开提示不能加载VBE6EXT.OLB解决方法
  4. 人工智能:第八章 自动规划
  5. 对话OTTVerse创始人Krishna Rao Vijayanagar:创业之初,挑战与机遇并存
  6. 超详细设置 Idea 类注释模板和方法注释模板
  7. san分布式共享文件系统_SAN网络存储共享软件全攻略剖析
  8. python concat_python的concat等多种用法详解
  9. WPF的ComboBox 数据模板自定义
  10. VS2010与SVN
  11. pandas series 判断是否包含某个值
  12. linux编译c代码错误,linux - 使用ASAN时如何解决错误“无法运行C编译程序” - 堆栈内存溢出...
  13. c51汇编语言extrn data,ASM51调用C51函数的实现
  14. windows7 安装docker
  15. iOS字体(UIFont)的相关知识
  16. 小程序 — 关于图片Base64转换及空间大小问题
  17. 向量加减法首尾规律_平面向量加减法口诀
  18. 基于 Verilog 的经典数字电路设计(3)选择器
  19. MATLAB强化学习实战(十一) 使用自定义训练循环训练强化学习策略
  20. 深度学习 经典网络模型对比分析 LeNet / AlexNet / VGGNet / GoogLeNet / ResNet / DenseNet

热门文章

  1. 阿里云服务器安装JDK指南
  2. spring boot controller 增加指定前缀的两种方法
  3. matlab函数输出,优化求解器输出函数
  4. 怎么安装aptdaemon模块_自己开发一个React Native 模块
  5. python集合可以修改吗_修改包含Python3中的集合的集合列表-问答-阿里云开发者社区-阿里云...
  6. 太吾绘卷第一世攻略_建平中学高二数学周练卷(2020.09)
  7. collect的功能是什么?其底层如何实现的?_为什么你要用 Spring ?
  8. mysql选取最小值_MySQL:选择x最小值
  9. java 委托_java 能不能自己写一个类叫 java.lang.System/String 正确答案
  10. 计算机字体原理,字体图标生成原理(1)