日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hbase/thrift/go连接失败

發布時間:2024/8/23 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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方法是可以獲取到數據的, 那么, 就是說僅Go的GetScannerResults方法是有問題的???

當問題追溯到這里的時候, 我已經有些懵了, 嘗試這谷歌查找原因, 各種關鍵詞都試過了, 沒有找到想要的答案(這也是為什么我要把這個錯記下來, 因為沒查到啊)

抓包比較差異

找了半天沒有找到問題, 既然Python可以查到數據 而Go查不到, 那么, 就可以嘗試抓包比較兩者差異了嘛.

依然使用上面的GetScannerResults, 分別對python和go進行抓包分析, 通過命令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连接失败的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。