hbase/thrift/go连接失败

问题

在通过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:

image-20220417134443514

image-20220417134458800

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

Python请求如下:

image-20220417134751836

Go请求如下:

image-20220417134903197

其中, 有一个字段两个是明显不一样的, 我很贴心的用红框圈出来了, 那么, 问题来了, 这个字段是什么呢? 我把上面的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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508351.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

printf缓冲区踩坑

问题 碰到了这样一段代码(经过简化的): #include "stdio.h" #include "unistd.h" #include "sys/wait.h"int main(){fork();printf("1\n");fork();printf("1\n");wait(NULL);return 0; }这里我们简单算一下, 结果会打印几…

进程切换时是如何保存上下文的

前言 当前操作系统大部分采用分时的进程调度, 既每个进程运行一小段时间, 然后切换到下一个进程运行, 依次往复. 当进程运行的时候是独占CPU的, 此时操作系统是无法强行介入的, 为了将执行权让出来, 就需要硬件的配合了. 硬件每个一个时钟周期(比如10ms), 就会产生一个时钟中…

GO/testing包

前言 之前在写GO单元测试的时候, 使用了这个结构testing.T. 进来无事翻了翻, 发现testing包中还有一些其他的结构体, 想来是不同用处. 没想到GO的testing包竟然默默做了这么多支持, 之前竟然不知道. 在testing包中包含一下结构体: testing.T: 这就是我们平常使用的单元测试t…

CPU的分支预测

前言 最近在进行性能调优的时候, 碰到了这样的一段代码(为了展示问题而简化的代码): <?php // 第一次运行 $start microtime(true); for ($i 0; $i < 100; $i) {for ($j 0; $j <1000; $j) {for ($k 0;$k < 10000; $k) {}} } $end microtime(true); echo fi…

PHP获取Opcode及C源码

是什么 在开始之前, 必须要先介绍一下Opcode是什么. 众所周知, Java在执行的时候, 会将.java后缀的文件预先编译为.class字节码文件, JVM加载字节码文件进行解释执行. 而字节码文件存在的意义, 就是为了加速执行. 那么PHP的Opcode与之类似, 也是从.php文件到执行的过程中, 所…

PHP require/include 区别

前言 在PHP中, 载入文件可以选择使用require, 也可以使用include, 那么那他们有什么区别呢? 看了网上的一些文章, 说他们使用场景不同, require一般在文件开头引入文件, include一般在函数中动态引入文件. 但是我觉得并不是这么简单, require是作为语言结构(关键字)出现的, …

Golang 接口原理

问题 小提示, 若想直接查看原理, 可从接口原理开始查看. 有这样一段GO代码: func main() {var obj interface{}fmt.Printf("obj nil. %b\n", obj nil)type st struct{}var s *stobj sfmt.Printf("s nil. %b\n", s nil)fmt.Printf("obj nil. …

三星识别文字_比亚迪电子助力三星Galaxy Note 10系列霸气首发!

三星有子初长成气宇轩昂 秀美俊逸减之一分则嫌柔增之一分则嫌赘2019年8月7日于纽约巴克莱发布Galaxy Note 10系列用简约 重构美三星Galaxy Note 10与Galaxy Note 10分别搭载了6.3英寸和6.8英寸的超感官全视曲面屏&#xff0c;均采用单摄挖孔屏&#xff0c;开孔位于屏幕正上方。…

lisp 设计盘形齿轮铣刀_机械设计基础——周转轮系传动比的计算

点击上方蓝色字体&#xff0c;关注我们15(视频来源于网络&#xff0c;仅供学习交流&#xff0c;侵权请联系删除)机械计重点学习指导机械原理全书重点提要轴的结构改错机械设计作业集01机械设计作业集02机械设计作业集答案机械原理作业集机械原理作业集答案轴的强度计算院校推荐…

b+树阶怎么确定_B站公布年度弹幕,这个排名我不太服气

也忘记了是从什么时候开始&#xff0c;B站开始公布自己的年度弹幕了&#xff0c;今年的年度弹幕排名前五的分别是&#xff1a;爷青回、武汉加油、有内味了、双厨狂喜、禁止套娃。话说今年真的是不容易啊&#xff0c;过年那段时间以及上半年不会忘记那一幕幕感人深邃的瞬间&…

css打印适应纸张_从生态平衡到打印机故障分析

生态平衡(ecological equilibrium)是指在一定时间内生态系统中的生物和环境之间、生物各个种群之间&#xff0c;通过能量流动、物质循环和信息传递&#xff0c;使它们相互之间达到高度适应、协调和统一的状态。也就是说当生态系统处于平衡状态时&#xff0c;系统内各组成成分之…

html5调用系统声音1s响一次_20款奔驰GLC260提车改柏林之声音响,音乐诉请,为爱发声!...

奔驰GLC车型在2020上半年可谓是风生水起&#xff0c;尤其是2020年1-5月份的豪华品牌SUV排名中&#xff0c;奔驰GLC车型以58982的销售量遥遥领先&#xff0c;同比增长了2%&#xff0c;奔驰GLC5月销量高达15275辆&#xff0c;再次打败老对手奥迪Q5L&#xff0c;夺得豪华SUV销量冠…

kotlin将对象转换为map_将网站转换为Photoshop文档

WebToLayers是一款能够帮助大家将网页转换成图像格式的软件&#xff0c;能够Web页面转换成PNG&#xff0c;JPG以及PSD格式的图片。当网页转换为PSD的时候&#xff0c;网页的各个要素都会自动转换为相应的图层&#xff0c;使得大家能够对PSD格式的网页进行设计与管理。WebToLaye…

centos更换网卡后怎么更新配置_CentOS安装

服务器使用的Linux操作系统都使用了CentOS来进行安装&#xff0c;CentOS是一个开源的Linux发行版&#xff0c;具有很好的稳定性和更多的可扩展行。为了能够正常使用Docker&#xff0c;我们将使用CentOS7及以上版本。​下载地址&#xff1a;https://www.centos.org/download/ ​…

centos普通用户修改文件权限_Linux实战014:Centos创建用户并添加root授权

刚收到在腾讯云申请的云服务器8台&#xff0c;现在准备分配给不同项目组来使用。为了确保系统及账号的安全&#xff0c;root账号不能直接给到他们。因为root的权限太大&#xff0c;任何的误操作就可能导致系统异常或者数据丢失找不回来。而且我们这是生产环境&#xff0c;账号会…

mongodb 导出txt_(干货)前端实现导出excel的功能

前言 导出功能其实在开发过程中是很常见的,平时我们做导出功能的时候基本都是后台生成&#xff0c;我们直接只需要调一支接口后台把生成的文件放到服务器或者数据库mongodb中,如果是放到mongodb中的话,我们需要从mongodb中通过唯一生成的id去拿到文件,最后window.location.href…

1971旗舰cpu intel_CPU的历史

很多人都对电脑硬件有一点的了解&#xff0c;本人也算略懂一二&#xff0c;所以今天来为大家说说电脑的主要硬件之一––CPU(中央处理器)。那么我们知道世界上造CPU的公司主要就是Intel和AMD。其实仔细想想&#xff0c;CPU的主要成分是什么?是硅(Si)&#xff0c;硅从那里来&am…

文本显示变量_【RPA课堂】UiPath中的变量、数据类型和组件

自动化出现的那一天起&#xff0c;就有了各种各样的工具来满足自动化的需要。无论是用于windows桌面自动化的简单工具&#xff0c;还是用于企业自动化大量任务的工具&#xff0c;它们都有自己的功能。UiPath就是这样的工具&#xff0c;在本文中&#xff0c;我们介绍一些非常基本…

bootstrap上传图片可实现查看上一张图片和下一张图片_如何实现像人民日报微信推文一样的的点亮效果?...

如何实现向人民日报微信推文一样的的点亮效果&#xff1f;有两种方法&#xff1a;方法一&#xff1a;就是使用代码在编辑器进行编辑emmmmmm这个方法贼麻烦&#xff0c;需要调至HTML模式……方法二&#xff1a;在现有编辑器模板下利用SVG动画进行编辑&#xff0c;因为点亮效果本…

设置log缓存_node多级缓存之redis缓存

在node项目开发过程中&#xff0c;缓存常常被用来解决高性能、高并发等问题。在我们的实际项目中&#xff0c;运用缓存的思路是内存缓存-->接口-->文件缓存。前面的总结中已经详细的说明了怎么实现和封装内存缓存和文件缓存。虽然二级缓存已经基本能够满足现在的所有场景…