Vitessを用いてコンテナでスケーラブルなデータベースを構築する


コンテナでデータベースを構築する方法を調べていたところ、Youtubeが使っているというVitessというものが見つかったので概要とインストール方法をまとめました。

参考

* [Scaling MySQL in the cloud with Vitess and Kubernetes](http://googlecloudplatform.blogspot.jp/2015/03/scaling-MySQL-in-the-cloud-with-Vitess-and-Kubernetes.html)

* [YouTubeがMySQLをスケールアウトする「Vitess」をオープンソースで公開。Kubernetesに対応](http://www.publickey1.jp/blog/15/youtubemysqlvitesskubernetes.html)


## Vitess とは

[Vitess](http://vitess.io/)はスケーラブルなMySQLを実現するもので以下の特徴をもっています。


* **Scalability** MySQLの機能にシャーディングを追加
* **Performance** データパフォーマンスに悪影響を与えるクエリの書き換え
* **Connection** pooling MySQLのコネクションのメモリオーバヘッドを削減
* **Manageability** フェールオーバやバックアップ機能

## アーキテクチャ
![VitessOverview.png](https://qiita-image-store.s3.amazonaws.com/0/27509/d355eaab-2010-e211-6003-3d3d3e919398.png "VitessOverview.png")

（図は http://vitess.io/overview/#architecture より借用）


* **Topology** 稼働しているサーバ情報やシャーディングスキーム、リプリケーショングラフなどを保存するメタデータストア
* **vtgate** アプリケーションからのクエリを正しいvttabletに振り分け、vttabletからの結果をまとめてアプリケーションに返す、軽量なプロキシサーバ
* **vttablet** MySQLのスループットを最大化するためにMySQLの前に設置されたプロキシサーバ
* **vtctl** Vitessクラスタを管理するCLIツール
* **vtctld** GUIでVitessクラスタを管理するためのHTTPサーバ

## インストール on Google Cloud Platform

### 環境

* Mac OSX 10.11.1
* go 1.5.1
* gcloud 2015.10.23

### 構築手順

#### vtctlclientのインストール

```
$ go get github.com/youtube/vitess/go/cmd/vtctlclient
```

#### Google Cloud Platformの設定 *課金対象なので注意

```
$ gcloud auth login
$ gcloud config set project [プロジェクト名]
$ gcloud components update kubectl
$ gcloud config set compute/zone asia-east1-a
$ gcloud beta container clusters create example --machine-type n1-standard-4 --num-nodes 5 --scopes storage-rw
$ gsutil mb gs://my-backup-bucket # バックアップ用バケットを作成
```

#### Vitessクラスタの設定

```
$ cd $GOPATH/src/github.com/youtube/vitess/examples/kubernetes
$ ./configure.sh
### example output:
# Backup Storage (file, gcs) [gcs]: [gcsを選ぶ]
# Google Developers Console Project [my-project]: [プロジェクト名]
# Google Cloud Storage bucket for Vitess backups: [バックアップ用バケット名]
# Saving config.sh...
```

#### Topology(etcd)の作成

```
$ ./etcd-up.sh
$ kubectl get pods # 全てRunningになるまで待つ
```

#### vtctldの作成

```
$ ./vtctld-up.sh
$ kubectl proxy --port=8001
```

[http://localhost:8001/api/v1/proxy/namespaces/default/services/vtctld:web/](http://localhost:8001/api/v1/proxy/namespaces/default/services/vtctld:web/)からWeb管理画面にアクセス可能。また、コマンドラインからは`./kvtctl.sh`で各種実行可能

#### vttabletの作成

```
$ ./vttablet-up.sh
```

4つのコンテナができ、各コンテナにMySQLとvttabletが動きます

```
$ ./kvtctl.sh ListAllTablets test
### example output:
# test-0000000100 test_keyspace 0 spare 10.64.1.6:15002 10.64.1.6:3306 []
# test-0000000101 test_keyspace 0 spare 10.64.2.5:15002 10.64.2.5:3306 []
# test-0000000102 test_keyspace 0 spare 10.64.0.7:15002 10.64.0.7:3306 []
# test-0000000103 test_keyspace 0 spare 10.64.1.7:15002 10.64.1.7:3306 []
# test-0000000104 test_keyspace 0 spare 10.64.2.6:15002 10.64.2.6:3306 []
```

#### MySQLの初期化

```
$ ./kvtctl.sh RebuildKeyspaceGraph test_keyspace
$ ./kvtctl.sh InitShardMaster -force test_keyspace/0 test-0000000100
$ ./kvtctl.sh ListAllTablets test
### example output:
# test-0000000100 test_keyspace 0 master 10.64.1.6:15002 10.64.1.6:3306 []
# test-0000000101 test_keyspace 0 replica 10.64.2.5:15002 10.64.2.5:3306 []
# test-0000000102 test_keyspace 0 replica 10.64.0.7:15002 10.64.0.7:3306 []
# test-0000000103 test_keyspace 0 rdonly 10.64.1.7:15002 10.64.1.7:3306 []
# test-0000000104 test_keyspace 0 rdonly 10.64.2.6:15002 10.64.2.6:3306 []
```

`./kvtctl.sh ListAllTablets test`で確認すると、各vttabletコンテナに役割（マスター/レプリカ/リードオンリー）がつきます

#### テーブルの作成

```
$ ./kvtctl.sh ApplySchema -sql "$(cat create_test_table.sql)" test_keyspace
```

#### vtgateの作成

```
$ ./vtgate-up.sh
```

### サンプルアプリケーションの実行

#### FWの設定 *外から80ポートにアクセス可能になるため注意

```
$ gcloud compute firewall-rules create guestbook --allow tcp:80
```

#### ゲストブックの実行

```
$ ./guestbook-up.sh

```

`kubectl get -o yaml service guestbook | grep ip`でロードバランサのIPアドレスを確認し、ブラウザでアクセスしてください


### 後片付け

```
$ gcloud container clusters delete example
$ gcloud compute firewall-rules delete guestbook
```