フューチャーアーキテクト Advent Calendar 2017の4日目です。
前提
- AWSのPrivate SubnetでHBase on EMRを構築
- クライアントPCのHBaseクライアントで、踏み台サーバ(Bastion Server)経由でHBaseにアクセスを行いたい
サーバ接続情報例
サーバ | public IP | private IP | private DNS |
---|---|---|---|
踏み台サーバ | 1.2.3.4 | 172.16.1.2 | - |
HBase(Master) | - | 172.16.2.3 | ip-172-16-2-3.ap-northeast-1.compute.internal |
HBase(RegionServer) | - | 172.16.2.4 | ip-172-16-2-4.ap-northeast-1.compute.internal |
確認環境
- クライアントOS
- Windows7 64bit
- SSHクライアント
- PuTTY
- HBaseクラスタ
- EMR 5.4.0 (Master1台、RegionServer1台)
- HBaseクライアント
- gohbase (master branch)
課題点・実現方法
- HBaseの踏み台サーバ経由でHBaseのポートにアクセスする必要がある
- ⇒ SSHのPort forwardingを行うことで解決するが、下記2の問題が発生
- HBaseはクラスタ単位で見るとポートが重複する(例: Master、RegionServerの両方共2181ポートを利用するため、localhostの2181ポートが競合する)
- ⇒ HBaseのサーバごとにクライアントPCのローカルアドレスを分けて、Port forwardingを行う
- HBaseクライアントでアクセスする際にプライベートDNS(ip-xx-xx-xx-xx.ap-northeast-1.compute.internal)で接続情報が返り、クライアントPCでは解決できずGet、Putが失敗する
- ⇒ Hostsに接続情報を追加することで解決
作業
HBaseのサーバごとにクライアントPCのローカルアドレスを分けて、SSH Port forwarding(課題点#1, #2を解決)
- zookeeperとHBaseのTCPポートをローカルアドレスにPort forwarding
- HBase(Master)は2181と16000ポートをPort forwarding
- HBase(RegionServer)は2181と16020ポートをPort forwarding
ローカルアドレス「127.0.0.3」をHBase(Master)に、ローカルアドレス「127.0.0.4」をHBase(RegionServer)に、割り当てた場合の設定
転送先 IP | 転送先 Port | 転送元 IP | 転送元 Port |
---|---|---|---|
127.0.0.3 | 16000 | 172.16.2.3 | 16000 |
127.0.0.3 | 2181 | 172.16.2.3 | 2181 |
127.0.0.4 | 16000 | 172.16.2.4 | 16020 |
127.0.0.4 | 2181 | 172.16.2.4 | 2181 |
- putty設定イメージ
- 注意
- EMRでは、HBaseのTCPポートがデフォルトと異なる
Hostsへの接続情報の追加(課題点#3を解決)
- Port forwarding作業時のローカルアドレスをもとにhostsにHBaseのプライベートDNSを追加
hosts
## HBase Master
127.0.0.3 ip-172-16-2-3.ap-northeast-1.compute.internal
## HBase RegionServer
127.0.0.4 ip-172-16-2-4.ap-northeast-1.compute.internal
確認
-
gohbaseで動作確認を行った
-
確認コード(エラー処理は割愛)
main.go
package main
import (
"fmt"
"context"
"github.com/tsuna/gohbase"
"github.com/tsuna/gohbase/hrpc"
)
func main() {
// MasterのDNSを指定
client := gohbase.NewClient("ip-172-16-2-3.ap-northeast-1.compute.internal")
defer client.Close()
family := map[string][]string{"testcf": []string{"testkey"}}
getRequest, _ := hrpc.NewGetStr(context.Background(), "testtable", "testrow", hrpc.Families(family))
getRsp, _ := client.Get(getRequest)
fmt.Println(string(getRsp.Cells[0].Value))
}
- 実行結果
> go run main.go
testvalue
まとめ・感想
- SSH Port forwardingとHostsへのサーバ追加で、踏み台経由でもHBaseにアクセスできた
- DNSやhostnameを返すサービスであれば、同様の方法で接続ができるはず
- この方法だと接続するサーバ台数が複数台になってもPortが干渉しないのが利点
- EMRの再作成を行うとアドレスが変わり、再度作業を行う必要があるのが難点