それが僕には楽しかったんです。

僕と MySQL と時々 MariaDB

etcd を golang で使う

はじめに

最近、OpenStackのインストールで無限に消耗しているけんつです。

OpenStackのインストールがまじで辛いので現実逃避のために etcd を Golang で使ってみたのでなんとなく気分で記事にしてみます。

etcdとは

そもそも etcd とは何かというと、簡潔にまとめているサイトの引用によると*1

etcd は、分散KVS (Key Value Store) です。クラスタのマシンでデータを共有できます。 アプリケーションから etcd にデータの読み書きが行えます。 etcd は、 CoreOS のコンポーネントとして使われます。

とのこと。


Golangで実装されており、HTTP(正確には gRPC)でJSONを使ってやり取りすることが可能となっている。
まてKVSであり、キーやディレクトリの変更を監視し値が変わった場合にそれを検知することができる。

gRPC

gRPCの前にRPCとは何かというところに触れる。 RPCとはプログラムから別のネットワーク上などに存在するコード等をリモートで呼び出すものらしい。

gRPCはその高性能なフレームワークであり、ロードバランスやトレースなどのサポートによってデバイスやモバイル、ブラウザをバックエンドサービスに接続することができる。*2

具体的な実装例があったので紹介しておく。
medium.com

上のサイトではメッセージ送信に関しては従来のプロセスと何も変わらないが、redisのpub/subとgRPC サーバを接続することでメッセージの受信を高速化したとのこと。

etcd をインストールする

Ubuntu上では apt を使って導入できるようだが、以下のサイトにしたがってインストールする。
computingforgeeks.com

$ etcd --version
etcd Version: 3.3.12
Git SHA: d57e8b8
Go Version: go1.10.8
Go OS/Arch: linux/amd64

(中略)

$ systemctl status etcd.service
● etcd.service - etcd key-value store
   Loaded: loaded (/etc/systemd/system/etcd.service; disabled; vendor preset: enabled)
   Active: active (running) since 木 2019-05-16 23:07:43 JST; 9s ago
     Docs: https://github.com/etcd-io/etcd
 Main PID: 19379 (etcd)
    Tasks: 13
   Memory: 3.7M
      CPU: 101ms
   CGroup: /system.slice/etcd.service
           └─19379 /usr/local/bin/etcd

etcdをGolangから使う

公式のクライアントを使う。

$ go get go.etcd.io/etcd/client
package main

import (
    "go.etcd.io/etcd/client"
    "time"
    "context"
    "fmt"
)


func main() {

    config := client.Config{
        Endpoints: []string{"http://127.0.0.1:2379"},
        Transport: client.DefaultTransport,
        HeaderTimeoutPerRequest: 2 * time.Second,
    }

    clt, err := client.New(config)
    if err != nil {
        panic(err)
    }

    keyapi := client.NewKeysAPI(clt)

    //Set key with value
    response, err := keyapi.Set(context.Background(), "/test", "test set", nil)
    if err != nil {
        panic(err)
    } else {
        fmt.Printf("Set is Done. Metadata is %q\n", response)
    }

    response2, err := keyapi.Get(context.Background(), "/test", nil)
    if err != nil {
        panic(err)
    } else {
        fmt.Printf("Get is Done. Metadata is %q\n", response2)
        fmt.Printf("%q key has %q value\n", response2.Node.Key, response2.Node.Value)
    }

}
$ go run main.go 
Set is Done. Metadata is &{"set" "{Key: /test, CreatedIndex: 4, ModifiedIndex: 4, TTL: 0}" <nil> '\x04' "cdf818194e3a8c32"}
Get is Done. Metadata is &{"get" "{Key: /test, CreatedIndex: 4, ModifiedIndex: 4, TTL: 0}" <nil> '\x04' "cdf818194e3a8c32"}
"/test" key has "test set" value

$ etcdctl ls
/test
$ etcdctl get /test
test set

おわりに

ひとまずetcdをgolangから使うことはできたので次はいくつかdockerコンテナを建てて
etcdを使った監視を実際にやってみる。