Code snippets for using a HBase golang client
January 17th, 2025
Getting started with github.com/tsuna/gohbase was a bit confusing, leaving behind some useful snippets for the Joe Schmoe.
Installation
Installation on macOS was easy
brew install hbase
brew services start hbase
Admin
DDL is separated out from other statements. HBase has the idea of “column families” which are the groups of columns: {column-family: {column: value}}
. Column families have some co-location benefit, in a distributed HBase scenario. From what I can tell, the columns created aren’t really enforced. I also never figured out what the point of the “value” was, despite googling around quite a bit.
Create table
admin := gohbase.NewAdminClient("localhost")
// Create Table
family := map[string]map[string]string{"cf1": {}, "cf2": {}}
createTableRequest := hrpc.NewCreateTable(ctx, []byte("t1"), family, func(ct *hrpc.CreateTable) {})
err := admin.CreateTable(createTableRequest)
if err != nil {
panic(err)
}
Drop table
To drop a table, you need to disable it first.
disableTableReq := hrpc.NewDisableTable(ctx, []byte("t1"))
if err := admin.DisableTable(disableTableReq); err != nil {
panic(err)
}
deleteTableReq := hrpc.NewDeleteTable(ctx, []byte("t1"))
if err := admin.DeleteTable(deleteTableReq); err != nil {
panic(err)
}
Application
Inserting
You can just make up columns.
client := gohbase.NewClient("localhost")
values := map[string]map[string][]byte{"cf1": {"c1": []byte("Hello, world!")}}
putRequest, err := hrpc.NewPutStr(ctx, "t1", "k1", values)
if err != nil {
panic(err)
}
_, err := client.Put(putRequest)
if err != nil {
panic(err)
}
Read
Get
getRequest, err := hrpc.NewGetStr(ctx, "t1", "k2", hrpc.Families(family))
if err != nil {
panic(err)
}
getRsp, err := client.Get(getRequest)
if err != nil {
panic(err)
}
if getRsp == nil {
panic(errors.New("Get response is nil"))
}
for _, cell := range getRsp.Cells {
fmt.Println("key", string(cell.Row), "value", string(cell.Value))
}
Scan
HBase organizes rows lexographically, so scanning nearby rows is very efficient (versus random filters).
scanRequest, err := hrpc.NewScanRange(ctx, []byte("t1"), []byte("k1"), []byte("k4"), hrpc.Families(family))
if err != nil {
panic(err)
}
client.Get(scanRequest)
scanRsp := client.Scan(scanRequest)
for {
r, err := scanRsp.Next()
if err != nil {
if err == io.EOF {
break
}
panic(err)
}
for _, cell := range r.Cells {
fmt.Println("key", string(cell.Row), "value", string(cell.Value))
}
}