go語言-通過thrift+連接池訪問hbase

背景

近期有通過go語言訪問阿里雲hbase增強版的需求,博主進行簡單實現,並且加以記錄。主要藉助了thrift和github.com/silenceper/pool的連接池實現。

實戰

阿里雲提供的thrift連接hbase的demo

參考文檔:https://github.com/aliyun/aliyun-apsaradb-hbase-demo/tree/master/hbase/thrift2/go?spm=a2c4g.11186623.2.30.69f329aa8PJzw2
看了一下demo,代碼畢竟簡單:

  1. 創建client
  2. 利用client進行增刪改查等操作

但是有一點需求注意:thrift的client是線程不安全的(言外之意,多線程訪問必須要使用不同的client實例),爲此,必須要引入連接池。

silenceper連接池

博主直接使用:github.com/silenceper/pool
大體看了一下代碼,流程如下:

  1. 創建連接池配置(例如:最大連接數、idle連接數等)
  2. 根據配置,創建連接池
  3. 獲取連接
  4. 業務處理
  5. 返還連接

實現代碼

package main

import (
	"./gen-go/hbase"
	"context"
	"fmt"
	"github.com/apache/thrift/lib/go/thrift"
	"github.com/silenceper/pool"
	"time"
	"unsafe"
)

const (
	HOST = "xxxxxxxxxxxxxxxx"
	// 用戶名
	USER = "xxx"
	// 密碼
	PASSWORD = "xxxx"
)

// 創建連接
func getHbaseClient() (interface{}, error) {
	protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
	trans, err := thrift.NewTHttpClient(HOST)
	if err != nil {
		return nil, err
	}
	// 設置用戶名密碼
	httClient := trans.(*thrift.THttpClient)
	httClient.SetHeader("ACCESSKEYID", USER)
	httClient.SetHeader("ACCESSSIGNATURE", PASSWORD)
	if err := trans.Open(); err != nil {
		return nil, err
	}
	return hbase.NewTHBaseServiceClientFactory(trans, protocolFactory), nil
}

// 關閉連接(這裏暫不考慮)
func clientClose(client interface{}) error {
	return nil
}

func main() {
	tableInbytes := []byte("ns:table1")
	defaultCtx := context.Background()
	// 創建連接池配置
	poolConfig := &pool.Config{
		InitialCap:  2,
		MaxIdle:     4,
		MaxCap:      5,
		Factory:     getHbaseClient,
		Close:       clientClose,
		IdleTimeout: 300 * time.Second,
	}
	// 創建連接池
	p, _ := pool.NewChannelPool(poolConfig)
	time.Sleep(2 * time.Second)
	// 併發獲取連接
	go asyncPrint(p, defaultCtx, tableInbytes)
	go asyncPrint(p, defaultCtx, tableInbytes)
	go asyncPrint(p, defaultCtx, tableInbytes)
	go asyncPrint(p, defaultCtx, tableInbytes)
	time.Sleep(2 * time.Second)
	go asyncPrint(p, defaultCtx, tableInbytes)
	go asyncPrint(p, defaultCtx, tableInbytes)
	go asyncPrint(p, defaultCtx, tableInbytes)
	time.Sleep(10 * time.Second)
}

func asyncPrint(p pool.Pool, ctx context.Context, tableInBytes []byte) {
	client, _ := p.Get()
	res, _ := client.(*hbase.THBaseServiceClient).Get(ctx, tableInBytes, &hbase.TGet{Row: []byte("row1")})
	fmt.Println(res)
	_ = p.Put(client)
}

評價

實現了初步通過thrift訪問hbase的操作。
後續需要確認:

  1. 連接長時間沒有數據交互的情況處理(考慮ping操作)
  2. close連接的操作
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章