時系列データベース「OpenTSDB」を試してみる

今回、時系列データベース[”OpenTSDB”](http://opentsdb.net/overview.html)の基本動作を試してみました。
OpenTSDBについては、こちらのSlideShare「[HBaseCon 2015: OpenTSDB and AsyncHBase Update](http://www.slideshare.net/HBaseCon/operations-session-3-49043534?qid=5547eada-f70d-4730-bacb-6aeb6f37c068&v=&b=&from_search=5)」が参考になると思います。
なお、OpenTSDBで扱う時系列データは、Apache HBase/hadoopクラスタ構成上に、保管されます。
今回は、OpenTSDB基本動作を試す目的なので、クラスタ構成は行っておりません。

#⬛︎ OpenTSDB環境構築
実際の構築にあたって、こちらのドキュメントを参考にしました。
http://opentsdb.net/docs/build/html/installation.html#id1
## (1) Linux環境準備
- Ubunts環境整備する

```
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS"

$ sudo apt-get update
$ sudo apt-get install git
$ sudo apt-get install autoconf
$ sudo apt-get install make
```
- ネットワーク設定確認する

```
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:47:78:62 brd ff:ff:ff:ff:ff:ff
    inet 192.168.195.164/24 brd 192.168.195.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe47:7862/64 scope link 
       valid_lft forever preferred_lft forever
```
- JDK環境をインストールし、JAVA_HOME環境変数にセットする

```
$ sudo apt-get install default-jdk
$ sudo update-alternatives --list java
/usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java

$ cd $HOME
$ vi .profile
export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
```

- OpenTSDB用logディレクトリを作成しておく

```
$ cd /var/log/
$ sudo mkdir opentsdb
$ sudo chmod 777 opentsdb
```

## (2) Apache ZooKeeper環境構築
- ZooKeeperをダウンロードする

```
$ cd $HOME
$ wget http://www-eu.apache.org/dist/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz
$ sudo tar -C /opt -xzf zookeeper-3.4.6.tar.gz
$ cd /opt/zookeeper-3.4.6/conf
$ cp zoo_sample.cfg zoo.cfg
```
- ZooKeeper設定ファイルを編集する

```
$ vi zoo.cfg
... (snip)

## the zookeeper server quorum
server.0=192.168.195.164:2888:3888
```
- ZooKeepコマンドのパスを、ログイン環境設定に追加する

```
$ cd $HOME
$ vi .profile
export PATH=/opt/zookeeper-3.4.6/bin:$PATH

$ source .profile
```
- ZooKeeperを起動する

```
$ zkServer.sh start
JMX enabled by default
Using config: /opt/zookeeper-3.4.6/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
```
## (3) Apache HBase環境構築
- HBaseをダウンロードする

```
$ wget http://www.apache.org/dist/hbase/hbase-0.94.27/hbase-0.94.27.tar.gz
$ tar xfz hbase-0.94.27.tar.gz
$ cd hbase-0.94.27/
```

- HBase設定ファイルを編集する

```
$ vi conf/hbase-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>hbase.rootdir</name>
    <value>file:///tmp/hbase-${user.name}/hbase</value>
  </property>
  <property>
    <name>hbase.zookeeper.property.dataDir</name>
    <value>/tmp/zookeeper</value>
  </property>
  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>192.168.195.164</value>
  </property>
  <property>
    <name>hbase.zookeeper.property.clientPort</name>
    <value>2182</value>
  </property>
</configuration>


$ vi conf/hbase-env.sh
export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
```
- HBaseを起動する

```
$ ./bin/start-hbase.sh
starting master, logging to /home/tsubo/hbase-0.94.27/bin/../logs/hbase-tsubo-master-OpenTSDB.out
```

- HBaseのマスタ状態を確認する

Webブラウザから、http://192.168.195.164:60010 にアクセスして、HBaseのマスタ状態を確認する
![HBASE.png](https://qiita-image-store.s3.amazonaws.com/0/103595/cbe50f81-a025-4269-44a0-8d31891008a3.png)

- HBase Shellを起動して、HBase上のテーブルを確認しておく

```
$ ./bin/hbase shell
HBase Shell; enter 'help<RETURN>' for list of supported commands.
Type "exit<RETURN>" to leave the HBase Shell
Version 0.94.27, rfb434617716493eac82b55180b0bbd653beb90bf, Thu Mar 19 06:17:55 UTC 2015

hbase(main):001:0> list
TABLE                                                                              
0 row(s) in 0.6220 seconds
```

## (4) OpenTSDB環境構築
- OpenTSDBをダウンロードする

```
$ cd $HOME
$ git clone git://github.com/OpenTSDB/opentsdb.git
```
- ビルドする

```
$ cd opentsdb/
$ ./build.sh
```

- OpenTSDB用テーブルを構築する

```
$ env COMPRESSION=NONE HBASE_HOME=$HOME/hbase-0.94.27 ./src/create_table.sh
HBase Shell; enter 'help<RETURN>' for list of supported commands.
Type "exit<RETURN>" to leave the HBase Shell
Version 0.94.27, rfb434617716493eac82b55180b0bbd653beb90bf, Thu Mar 19 06:17:55 UTC 2015

create 'tsdb-uid',
  {NAME => 'id', COMPRESSION => 'NONE', BLOOMFILTER => 'ROW'},
  {NAME => 'name', COMPRESSION => 'NONE', BLOOMFILTER => 'ROW'}
0 row(s) in 1.9140 seconds


create 'tsdb',
  {NAME => 't', VERSIONS => 1, COMPRESSION => 'NONE', BLOOMFILTER => 'ROW'}
0 row(s) in 1.0620 seconds

  
create 'tsdb-tree',
  {NAME => 't', VERSIONS => 1, COMPRESSION => 'NONE', BLOOMFILTER => 'ROW'}
0 row(s) in 1.0630 seconds

  
create 'tsdb-meta',
  {NAME => 'name', COMPRESSION => 'NONE', BLOOMFILTER => 'ROW'}
0 row(s) in 1.0480 seconds
```

- OpenTSDBを起動する

```
$ tsdtmp=${TMPDIR-'/tmp'}/tsd
$ ./build/tsdb tsd --port=4242 --staticroot=build/staticroot --cachedir="$tsdtmp" --zkquorum=localhost:2182
2016-03-06 17:06:45,219 INFO  [main] TSDMain: Starting.
2016-03-06 17:06:45,222 INFO  [main] TSDMain: net.opentsdb.tools 2.2.0 built at revision e2efe9a (MINT)
2016-03-06 17:06:45,223 INFO  [main] TSDMain: Built on 2016/03/05 04:52:57 +0000 by tsubo@OpenTSDB:/home/tsubo/opentsdb/build
2016-03-06 17:06:45,226 INFO  [main] Config: Successfully loaded configuration file: opentsdb.conf
2016-03-06 17:06:45,263 INFO  [main] Config: Successfully loaded configuration file: opentsdb.conf
2016-03-06 17:06:45,334 WARN  [main] PluginLoader: Unable to locate any plugins of the type: net.opentsdb.query.filter.TagVFilter
2016-03-06 17:06:45,354 INFO  [main] ZooKeeper: Client environment:zookeeper.version=3.4.5-1392090, built on 09/30/2012 17:52 GMT
2016-03-06 17:06:45,354 INFO  [main] ZooKeeper: Client environment:host.name=OpenTSDB
2016-03-06 17:06:45,354 INFO  [main] ZooKeeper: Client environment:java.version=1.7.0_95
2016-03-06 17:06:45,355 INFO  [main] ZooKeeper: Client environment:java.vendor=Oracle Corporation
2016-03-06 17:06:45,355 INFO  [main] ZooKeeper: Client environment:java.home=/usr/lib/jvm/java-7-openjdk-amd64/jre
2016-03-06 17:06:45,355 INFO  [main] ZooKeeper: Client environment:java.class.path=/home/tsubo/opentsdb/build/third_party/hbase/asynchbase-1.7.1.jar:/home/tsubo/opentsdb/build/third_party/guava/guava-18.0.jar:/home/tsubo/opentsdb/build/third_party/slf4j/log4j-over-slf4j-1.7.7.jar:/home/tsubo/opentsdb/build/third_party/logback/logback-classic-1.0.13.jar:/home/tsubo/opentsdb/build/third_party/logback/logback-core-1.0.13.jar:/home/tsubo/opentsdb/build/third_party/jackson/jackson-annotations-2.4.3.jar:/home/tsubo/opentsdb/build/third_party/jackson/jackson-core-2.4.3.jar:/home/tsubo/opentsdb/build/third_party/jackson/jackson-databind-2.4.3.jar:/home/tsubo/opentsdb/build/third_party/netty/netty-3.9.4.Final.jar:/home/tsubo/opentsdb/build/third_party/protobuf/protobuf-java-2.5.0.jar:/home/tsubo/opentsdb/build/third_party/slf4j/slf4j-api-1.7.7.jar:/home/tsubo/opentsdb/build/third_party/suasync/async-1.4.0.jar:/home/tsubo/opentsdb/build/third_party/zookeeper/zookeeper-3.4.5.jar:/home/tsubo/opentsdb/build/third_party/apache/commons-math3-3.4.1.jar:/home/tsubo/opentsdb/build/tsdb-2.2.0.jar:/home/tsubo/opentsdb/build/../src
2016-03-06 17:06:45,355 INFO  [main] ZooKeeper: Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib
2016-03-06 17:06:45,360 INFO  [main] ZooKeeper: Client environment:java.io.tmpdir=/tmp
2016-03-06 17:06:45,360 INFO  [main] ZooKeeper: Client environment:java.compiler=<NA>
2016-03-06 17:06:45,361 INFO  [main] ZooKeeper: Client environment:os.name=Linux
2016-03-06 17:06:45,361 INFO  [main] ZooKeeper: Client environment:os.arch=amd64
2016-03-06 17:06:45,361 INFO  [main] ZooKeeper: Client environment:os.version=3.19.0-25-generic
2016-03-06 17:06:45,361 INFO  [main] ZooKeeper: Client environment:user.name=tsubo
2016-03-06 17:06:45,362 INFO  [main] ZooKeeper: Client environment:user.home=/home/tsubo
2016-03-06 17:06:45,362 INFO  [main] ZooKeeper: Client environment:user.dir=/home/tsubo/opentsdb
2016-03-06 17:06:45,363 INFO  [main] ZooKeeper: Initiating client connection, connectString=localhost:2182 sessionTimeout=5000 watcher=org.hbase.async.HBaseClient$ZKClient@5773a483
2016-03-06 17:06:45,381 INFO  [main] HBaseClient: Need to find the -ROOT- region
2016-03-06 17:06:45,383 INFO  [main-SendThread(localhost:2182)] ClientCnxn: Opening socket connection to server localhost/0:0:0:0:0:0:0:1:2182. Will not attempt to authenticate using SASL (unknown error)
2016-03-06 17:06:45,387 INFO  [main-SendThread(localhost:2182)] ClientCnxn: Socket connection established to localhost/0:0:0:0:0:0:0:1:2182, initiating session
2016-03-06 17:06:45,395 INFO  [main-SendThread(localhost:2182)] ClientCnxn: Session establishment complete on server localhost/0:0:0:0:0:0:0:1:2182, sessionid = 0x1534a850315001c, negotiated timeout = 5000
2016-03-06 17:06:45,413 INFO  [main-EventThread] HBaseClient: Connecting to -ROOT- region @ 127.0.1.1:47707
2016-03-06 17:06:45,454 INFO  [main-EventThread] ZooKeeper: Session: 0x1534a850315001c closed
2016-03-06 17:06:45,454 INFO  [main-EventThread] ClientCnxn: EventThread shut down
2016-03-06 17:06:45,471 INFO  [AsyncHBase I/O Worker #1] HBaseClient: Added client for region RegionInfo(table=".META.", region_name=".META.,,1", stop_key=""), which was added to the regions cache.  Now we know that RegionClient@1357170721(chan=[id: 0xaa9ff3b0, /127.0.0.1:59915 => /127.0.1.1:47707], #pending_rpcs=0, #batched=0, #rpcs_inflight=1) is hosting 1 region.
2016-03-06 17:06:45,473 INFO  [AsyncHBase I/O Worker #1] HBaseClient: Added client for region RegionInfo(table="tsdb", region_name="tsdb,,1457244762546.76cd3d0dd1b8bc496a49bb8e03ea9ecf.", stop_key=""), which was added to the regions cache.  Now we know that RegionClient@1357170721(chan=[id: 0xaa9ff3b0, /127.0.0.1:59915 => /127.0.1.1:47707], #pending_rpcs=0, #batched=0, #rpcs_inflight=1) is hosting 2 regions.
2016-03-06 17:06:45,474 INFO  [AsyncHBase I/O Worker #1] HBaseClient: Added client for region RegionInfo(table="tsdb-uid", region_name="tsdb-uid,,1457244762301.042959f02556c889749d5d9ab0f651e8.", stop_key=""), which was added to the regions cache.  Now we know that RegionClient@1357170721(chan=[id: 0xaa9ff3b0, /127.0.0.1:59915 => /127.0.1.1:47707], #pending_rpcs=0, #batched=0, #rpcs_inflight=1) is hosting 3 regions.
2016-03-06 17:06:45,514 INFO  [main] RpcHandler: TSD is in rw mode
2016-03-06 17:06:45,514 INFO  [main] RpcHandler: CORS domain list was empty, CORS will not be enabled
2016-03-06 17:06:45,515 INFO  [main] RpcHandler: Loaded CORS headers (Authorization, Content-Type, Accept, Origin, User-Agent, DNT, Cache-Control, X-Mx-ReqToken, Keep-Alive, X-Requested-With, If-Modified-Since)
2016-03-06 17:06:45,518 WARN  [main] PluginLoader: Unable to locate any plugins of the type: net.opentsdb.tsd.HttpSerializer
2016-03-06 17:06:45,530 INFO  [main] TSDMain: Ready to serve on /0.0.0.0:4242
```

## (5) OpenTSDBの動作確認
- 別ターミナルから、OpenTSDBプロセス動作状態を確認する

```
$ jps
10164 QuorumPeerMain
15435 Jps
10672 HMaster
15301 TSDMain
```
- HBase Shellを起動して、OpenTSDB用テーブル構成を確認する

```
$ cd $HOME
$ cd hbase-0.94.27/
$ ./bin/hbase shell
HBase Shell; enter 'help<RETURN>' for list of supported commands.
Type "exit<RETURN>" to leave the HBase Shell
Version 0.94.27, rfb434617716493eac82b55180b0bbd653beb90bf, Thu Mar 19 06:17:55 UTC 2015

hbase(main):001:0> list
TABLE                                                                           
tsdb                                                                            
tsdb-meta                                                                       
tsdb-tree                                                                       
tsdb-uid                                                                        
4 row(s) in 0.7050 seconds
```
"tsdb", "tsdb-meta", "tsdb-tree", "tsdb-uid"の４テーブルが追加されておりました。

```
hbase(main):015:0* describe 'tsdb'
DESCRIPTION                                                          ENABLED                              
 'tsdb', {NAME => 't', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => true                                 
  'ROW', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => '                                      
 NONE', MIN_VERSIONS => '0', TTL => '2147483647', KEEP_DELETED_CELLS                                      
  => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', ENCODE_ON_                                      
 DISK => 'true', BLOCKCACHE => 'true'}                                                                    
1 row(s) in 0.0430 seconds

hbase(main):016:0> describe 'tsdb-meta'
DESCRIPTION                                                          ENABLED                              
 'tsdb-meta', {NAME => 'name', DATA_BLOCK_ENCODING => 'NONE', BLOOMF true                                 
 ILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '3', COMPRESS                                      
 ION => 'NONE', MIN_VERSIONS => '0', TTL => '2147483647', KEEP_DELET                                      
 ED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', EN                                      
 CODE_ON_DISK => 'true', BLOCKCACHE => 'true'}                                                            
1 row(s) in 0.0370 seconds

hbase(main):017:0> describe 'tsdb-tree'
DESCRIPTION                                                          ENABLED                              
 'tsdb-tree', {NAME => 't', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILT true                                 
 ER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION                                      
  => 'NONE', MIN_VERSIONS => '0', TTL => '2147483647', KEEP_DELETED_                                      
 CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', ENCOD                                      
 E_ON_DISK => 'true', BLOCKCACHE => 'true'}                                                               
1 row(s) in 0.0350 seconds

hbase(main):018:0> describe 'tsdb-uid'
DESCRIPTION                                                          ENABLED                              
 'tsdb-uid', {NAME => 'id', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILT true                                 
 ER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '3', COMPRESSION                                      
  => 'NONE', MIN_VERSIONS => '0', TTL => '2147483647', KEEP_DELETED_                                      
 CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', ENCOD                                      
 E_ON_DISK => 'true', BLOCKCACHE => 'true'}, {NAME => 'name', DATA_B                                      
 LOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE =>                                      
  '0', VERSIONS => '3', COMPRESSION => 'NONE', MIN_VERSIONS => '0',                                       
 TTL => '2147483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '6                                      
 5536', IN_MEMORY => 'false', ENCODE_ON_DISK => 'true', BLOCKCACHE =                                      
 > 'true'}                                                                                                
1 row(s) in 0.0390 seconds
```

#⬛︎ OpenTSDBの基本動作を試してみる
時系列データベース「OpenTSDB」へのデータ参照/更新を行うためには、REST-APIが活用できます。
実際のREST-APIの使い方は、["OpenTSDB 2.2 documentation"](http://opentsdb.net/docs/build/html/index.html)が参考になります。

## (1) 事前準備として、metricを登録します
まずは、こちらの["OpenTSDB 2.2 documentation >> User Guide >> CLI Tools"](http://opentsdb.net/docs/build/html/user_guide/cli/mkmetric.html)
に従って、metricを登録します

- "sample-metric"という名前のmetricを登録します

```
$ cd $HOME
$ cd opentsdb
$ ./build/tsdb mkmetric sample-metric --zkquorum=localhos2182
metrics sample-metric: [0, 0, 1]
```

## (2) OpenTSDBクライアント環境を整備します
OpenTSDBのREST-APIを自由に利用できるように、クライアント整備します。

- https://golang.org/doc/install を参考に、golang環境を作成します。

- opentsdb-goclientをインストールします。

```
$ go get github.com/bluebreezecf/opentsdb-goclient
```

## (3) /api/putの動作を確認します
それでは、早速、時系列データを登録してみます。
こちらの["OpenTSDB 2.2 documentation >> HTTP API >> /api/put"](http://opentsdb.net/docs/build/html/api_http/put.html)
に従って、REST経由で、登録することになります。

- 時系列データ登録スクリプトを配置します。

```go:sample_api_put.go
package main

import (
	"fmt"
	"github.com/bluebreezecf/opentsdb-goclient/client"
	"github.com/bluebreezecf/opentsdb-goclient/config"
        "time"
)

var metric string = "sample-metric"
var port string = "fe-1/1/1"
var PutDataPointNum int = 9

func main() {
	opentsdbCfg := config.OpenTSDBConfig{
		OpentsdbHost: "192.168.195.164:4242",
	}
	tsdbClient, err := client.NewClient(opentsdbCfg)
	if err != nil {
		fmt.Printf("%v\n", err)
		return
	}

        //POST /api/put
        fmt.Println("Begin to test POST /api/put.")
        sampleDatas := make([]client.DataPoint, 0)
        time.Sleep(2 * time.Second)
        tags := make(map[string]string)
        tags["port"] = port
        i := 0
        for {
                time.Sleep(1000 * time.Millisecond)
                data := client.DataPoint{
                        Metric:    metric,
                        Timestamp: time.Now().Unix(),
                        Value:     i,
                }
                data.Tags = tags
                sampleDatas = append(sampleDatas, data)
                fmt.Printf("  %d.Prepare datapoint %s\n", i, data.String())
                if i < PutDataPointNum {
                        i++
                } else {
                        break
                }
        }

        if resp, err := tsdbClient.Put(sampleDatas, "details"); err != nil {
                fmt.Printf("  Error occurs when putting datapoints: %v", err)
        } else {
                fmt.Printf("  %s", resp.String())
        }
        fmt.Println("Finish testing POST /api/put.")

}
```

- 時系列データ登録スクリプトを実行します。

```
$ go run sample_api_put.go 
Begin to test POST /api/put.
  0.Prepare datapoint {"metric":"sample-metric","timestamp":1457249790,"value":0,"tags":{"port":"fe-1/1/1"}}
  1.Prepare datapoint {"metric":"sample-metric","timestamp":1457249791,"value":1,"tags":{"port":"fe-1/1/1"}}
  2.Prepare datapoint {"metric":"sample-metric","timestamp":1457249792,"value":2,"tags":{"port":"fe-1/1/1"}}
  3.Prepare datapoint {"metric":"sample-metric","timestamp":1457249793,"value":3,"tags":{"port":"fe-1/1/1"}}
  4.Prepare datapoint {"metric":"sample-metric","timestamp":1457249794,"value":4,"tags":{"port":"fe-1/1/1"}}
  5.Prepare datapoint {"metric":"sample-metric","timestamp":1457249795,"value":5,"tags":{"port":"fe-1/1/1"}}
  6.Prepare datapoint {"metric":"sample-metric","timestamp":1457249796,"value":6,"tags":{"port":"fe-1/1/1"}}
  7.Prepare datapoint {"metric":"sample-metric","timestamp":1457249797,"value":7,"tags":{"port":"fe-1/1/1"}}
  8.Prepare datapoint {"metric":"sample-metric","timestamp":1457249798,"value":8,"tags":{"port":"fe-1/1/1"}}
  9.Prepare datapoint {"metric":"sample-metric","timestamp":1457249799,"value":9,"tags":{"port":"fe-1/1/1"}}
  {"StatusCode":200,"failed":0,"success":10}
Finish testing POST /api/put.
```
以上より、時系列データを１０件、保存することができました。

## (4) /api/queryの動作を確認します
先ほど、保存した時系列データを参照してみます。
こちらの["OpenTSDB 2.2 documentation >> HTTP API >> /api/query"](http://opentsdb.net/docs/build/html/api_http/query/index.html)
に従って、REST経由で、参照することになります。

- 時系列データ参照スクリプトを配置します。

```go:sample_api_query.go
package main

import (
    "fmt"
    "time"
    "github.com/bluebreezecf/opentsdb-goclient/client"
    "github.com/bluebreezecf/opentsdb-goclient/config"
)

var host string = "192.168.195.164:4242"
var metric string = "sample-metric"
var aggregator string = "sum"
var port string = "fe-1/1/1"
var rate bool = false

func main() {
    st2 := time.Now().Unix()
    st1 := st2 - 300

    // create New Client
    opentsdbCfg := config.OpenTSDBConfig{
        OpentsdbHost: host,
    }
    tsdbClient, err := client.NewClient(opentsdbCfg)
    if err != nil {
        fmt.Printf("%v\n", err)
        return
    }

    // POST /api/query to query
    tags := make(map[string]string)
    tags["port"] = port
    queryParam := client.QueryParam{
        Start: st1,
        End:   st2,
    }
    subqueries := make([]client.SubQuery, 0)
    subQuery := client.SubQuery{
        Aggregator: aggregator,
        Rate: rate,
        Metric: metric,
        Tags:   tags,
    }
    subqueries = append(subqueries, subQuery)
    queryParam.Queries = subqueries

    fmt.Println("===================== seach metrics =====================")
    fmt.Println("Start time :", time.Unix(st1, 0).UTC(), " ->", st1)
    fmt.Println("End time   :", time.Unix(st2, 0).UTC(), " ->", st2)
    fmt.Println("Aggregator :", aggregator)
    fmt.Println("Rate       :", rate)
    fmt.Println("Metric     :", metric)
    fmt.Println("Tags       :", tags)
    fmt.Println("===================== search result =====================")

    if queryResp, err := tsdbClient.Query(queryParam); err != nil {
        fmt.Printf("Error occurs when querying: %v", err)
    } else {
        fmt.Printf("%s\n", queryResp.String())
    }
}
```

- 時系列データ参照スクリプトを実行します。

```
$ go run sample_api_query.go 
===================== seach metrics =====================
Start time : 2016-03-06 07:31:50 +0000 UTC  -> 1457249510
End time   : 2016-03-06 07:36:50 +0000 UTC  -> 1457249810
Aggregator : sum
Rate       : false
Metric     : sample-metric
Tags       : map[port:fe-1/1/1]
===================== search result =====================
{"StatusCode":200,"queryRespCnts":[{"metric":"sample-metric","tags":{"port":"fe-1/1/1"},"aggregateTags":[],"dps":{"1457249790":0,"1457249791":1,"1457249792":2,"1457249793":3,"1457249794":4,"1457249795":5,"1457249796":6,"1457249797":7,"1457249798":8,"1457249799":9}}],"error":null}
```
実行結果として、次のような時系列データを参照することができました。
"1457249790":0,
"1457249791":1,
"1457249792":2,
"1457249793":3,
"1457249794":4,
"1457249795":5,
"1457249796":6,
"1457249797":7,
"1457249798":8,
"1457249799":9

<b>なお、時系列データ参照スクリプトの都合上、時系列データを保存してから、５分以内に、時系列データを参照する必要があります。</b>
使用上、ご注意ください。

#⬛︎ 最後に
今回は、OpenTSDB環境をシンプルに構築する方法を試してみたに過ぎません。
実運用では、BigData領域への活用を見据えて、Apache HBase/hadoopによるクラスタ基盤を前提に環境を構築する必要があると思います。ただし、OpenTSDBクラスタ構築に必要となるスキル習得は、なかなか、難易度が高いと思います。
巷には、OpenTSDBを勉強するにふさわしい技術書籍など、皆無に等しいので、もう少し、注目を集めても良いと感じました。