GAEのために出来た、という歴史的な背景からもあまりGCEから使うこともなかった Cloud SQL (1st generation)ですが、昨年 2nd generation がベータとなりました。パフォーマンスの高さについてはアナウンスされていますが、この記事はFailOverを中心に、2nd generationを探っていきます。

Cloud SQLとは

AWSで言うところのRDS、マネージドSQL(RDB もっと言うと MySQL)です。VMインスタンスに自前でMySQLを入れるよりも勿論割高ですが、バックアップとかフェイルオーバとかの面倒をGoogleが見てくれるというものです。

最初に結論

  • アクセスIPアドレスは、相変わらず Global IPのみ
  • アクセス元IPアドレスで制限
  • GCEの内部ネットワークに作成は出来ないが、GCE内から接続する分には、ネットワーク速度的なペナルティーはない(多分)
  • RDSのMulti-AZに相当する機能はある、が、そもそもGCEはZone (AZ) がどれ位離れているかとか明言されていない
  • Multi-AZと書いたが、Active/Standbyではない、Active/Active(RO) なので、どちらかと言うと AWS Auroraに近い (語弊を生む乱暴な言い方だが、構成としては)
  • FailOverの機能はある、が、自動的にエンドポイントを書き換える機能は無い
  • レプリケーション構成(semisync)

構成と役割

20160207132316

1つのDBクラスタとして管理します。各ロールについて

  • マスタサーバ
    文字通り
  • フェイルオーバレプリカ(RO)
    レプリカですが、フェイルオーバ時にマスタ昇格の対象となるものです。 必ずマスタサーバと同じインスタンスタイプとなります
  • リードレプリカ(RO)
    文字通りのレプリカ、マスタが死んでもこいつはマスタ昇格しない。マスタサーバと異なるインスタンスタイプでもOKです

フェイルオーバレプリカ はAuroraのReaderに近い存在です。それに加えて、絶対にマスタ(Writer)に昇格しないノードがリードレプリカです。

実践

Developers Consoleからポチポチしていれば出来ます。が、注意点のみ記載します

1) GCEからの接続前提であれば、勿論リージョンをあわせること

2) マスタのバックアップを取らないと、レプリカが作れない これは フェイルオーバレプリカでもリードレプリカでも同じ

20160207133312

接続確認

mysqlコマンドで接続できます。初期ユーザは root & パス無しなので、とっととパスワードを指定しましょう。

レプリケーションの様子

  • マスターノード
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000006 |      120 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.08 sec)

mysql> select @@binlog_format;
+-----------------+
| @@binlog_format |
+-----------------+
| ROW             |
+-----------------+
1 row in set (0.09 sec)
  • フェイルオーバレプリカ
mysql> show slave status G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: [master global ip]
                  Master_User: cloudsqlreplica
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000006
          Read_Master_Log_Pos: 120
               Relay_Log_File: relay-log.000005
                Relay_Log_Pos: 283
        Relay_Master_Log_File: mysql-bin.000006
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 120
              Relay_Log_Space: 613
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: Yes
           Master_SSL_CA_File: master_server_ca.pem
           Master_SSL_CA_Path: /mysql/datadir
              Master_SSL_Cert: replica_cert.pem
            Master_SSL_Cipher:
               Master_SSL_Key: replica_pkey.pem
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: [master server id]
                  Master_UUID: 5c40936b-cca9-11e5-8416-0242ac110009
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
1 row in set (0.14 sec)

mysql> select @@read_only;
+-------------+
| @@read_only |
+-------------+
|           1 |
+-------------+
1 row in set (0.12 sec)
  • リードレプリカ
# show slave statusはほぼ同じ

mysql> select @@read_only;
+-------------+
| @@read_only |
+-------------+
|           1 |
+-------------+
1 row in set (0.12 sec)

FailOver

2016/02/06現在、gcloiudコマンドでもFailOver発動のコマンドはありません。ただし、Cloud SQL APIを叩けば発動出来ます。 https://cloud.google.com/sql/docs/high-availability#test

FailOver手動発動

curlで叩けと書いてありますが、ちょっとむずかしいので API Exprolerで簡単に打ちます。 まず、Cloud SQL API を有効化させます。

20160207134812

ご丁寧に誘導リンクがあるので、そのままGo

20160207134842

20160207134904

上記のドキュメント通りに打つのですが、SettingsVersion ってなんやねん! ということで、これを先に取得します。gcloudで取得可能

gcloud sql instances describe 

....
  kind: sql#settings
  locationPreference:
    kind: sql#locationPreference
  pricingPlan: PER_USE
  replicationType: SYNCHRONOUS
  settingsVersion: '19'
  tier: db-g1-small
state: RUNNABLE

この場合だと 19です。
これで実行可能です

20160207134913

Failoverの挙動

こんな感じです

  1. マスター止まる
  2. フェイルオーバレプリカが昇格
  3. 元マスター復帰
  4. 元マスタ-がマスターに昇格、同時にフェイルオーバレプリカダウン
  5. フェイルオーバレプリカがスレーブに戻る

AWSとは異なり、DNSに依存しないIPベースと言うポリシーは、悪い意味でも一貫しています。あくまで、意図的にフェイルオーバを起こした場合の動きですが、実際の障害時も同じ動作になると思います。
特筆することは、マスターのIPやエンドポイントが一定ではないという点です。上記パターンでもマスターは マスター -> スレーブ -> マスターと切り替わっていますが、エンドポイント(IP)はそれを追従していません。文字通りDBのフェイルオーバのみが実行されています。
この点をどう扱う(える)かが1つの導入への障害となりえます。フェイルオーバの一連の作業の中で、各サーバのマスタ昇格のイベントを捕まえることが出来ないので、HAPoxyの設定を変えてエンドポイントを変更したり、consulとかも難しいと思います。
ただ、これはエンジニアの勘ですが、最近この手のエンドポイント問題は、クライアントライブラリ側で吸収するのが主流となっていく気がします(mongoを除く) 。すでにPHPでもmysqlnd-msなど Read/Write spplitingを含めてHA構成のエンドポイント探しは、ライブラリ側の方が柔軟でかつ賢い実装がすでに出揃いつつあると感じています。

あとから変えられる?

1st に比べてかなりの部分が Pre-Provisionな感じになりましたが。。

ディスク

増やせますが、減らせません。1st-genの時は完全オンデマンドだったので、そちらも選べればよかったのですが。10 -> 15GBしか試していませんが – ダウンタイムはゼロ – ディスク拡張中のパフォーマンスは言及されていない

なお、容量アップにかかる時間は、恐らくもともとのディスク容量に依存するかは試していません。ただし、10 -> 15GB の場合は、一瞬でした。 ですが、問題があります!ここは後述

インスタンスタイプ

変更できます。が、もちろんサービス断有りです。所用時間は 2 – 4 分程度で、結構遅いな-

その他

以外なところではフラグ = サーバパラメータの変更でも再起動が必須な点でしょうか、下記ダイアログが出ます

20160207162554

フェイルオーバレプリカと変更

ここが結構問題です。マスターのディスクをでかくしたら、勝手にスレーブ(フェイルオーバレプリカ)もデカくしてくれそうなもんですよね?
インスタンスタイプを変えたらスレーブも変わりそうなもんですよね?最初に一緒にしないとダメとか言うなら。
それが変わらないんですよ。

20160207162533

ということは、マスターのスペックを変えたらフェイルオーバレプリカ作り直しということになります。これはイケてないなー
ちなみにこの点はドキュメントと矛盾しています。

After the failover replica is created, you can change all configuration settings of the instance, except that you can not enable backups or change the activation policy.

まとめ Pros/Cons

Pros

  • 1stから、DB限界データサイズが大幅UP
  • リードレプリカ台数調整可能
  • 自動FailOver
  • インスタンスタイプが明確GCEと同じ感覚で指定できる

Cons

  • 1stにあったデータ従量課金が無くなった
  • IP制限がGlobal IPのみなので、タグとかで制限出来ない、具体的にGCEでもエフェメラルIPを使っている場合は、Cloud SQL Proxyというのを使う必要がある。https://cloud.google.com/sql/docs/sql-proxy
  • 自動FailOverするが、エンドポイント書き換えはない
  • フェイルオーバレプリカのスペック変更ができない(ドキュメントはできるっぽいことかいてあるが、、)

元記事はこちら

Google Cloud SQL 2nd GenerationのFailOverなど