フロムスクラッチ開発者ブログ

from scratch Engineers' Blog

Amazon RDSでMySQLからAuroraに移行する方法

こんにちは。フロムスクラッチのインフラチームに所属している山崎です。
今回は「Amazon RDSでMySQLからAuroraへの移行」について投稿させて頂きます。

 
AWSの運用管理者の方の中には、「MySQLをAuroraに移行したい」という思いを抱いている方もいるのではないでしょうか?私もそのうちの1人でした。結局、移行を実施したのですが、移行の方法についてまとまっている手順がAWSドキュメントやネット記事に無かったので、断片的なドキュメントをまとめつつ、検証を行い完成させました。今回は、その手順について共有させて頂きます。

 

f:id:daisuke-yamasaki:20180322171802p:plain

 

結論から言うと、「Auroraリードレプリカを作成後、移行対象MySQLの更新を止め(Read-onlyにする)、Auroraリードレプリカを昇格、その後アプリの接続をMySQLからAuroraに切り替える」という方法をとります。簡単なイメージ図は次の通りです。

f:id:daisuke-yamasaki:20180322174341p:plain

 

 こちらが手順の目次になります。以降、手順を解説していきます。

----------------------------------------------------------------------- 

◆事前作業
 1.移行対象MySQL専用のパラメータグループを作成
 2.Auroraリードレプリカを作成

  
◆移行作業
 1.移行対象MySQLのパラメータグループを変更して、Read-onlyにする
 2.レプリカラグが無いことを確認
 3.Auroraリードレプリカの昇格
 4.アプリの切り替え(移行対象MySQL→昇格したAurora)
 5.事後確認
 6.移行対象MySQLの削除

----------------------------------------------------------------------- 

 

<手順の解説>

◆事前作業

本番の移行作業では、「移行対象MySQLの更新を止める(Read-only)」、「Auroraリードレプリカが作成されている」の2点が必要です。そのための準備をここで実施します。

 

1.移行対象MySQL専用のパラメータグループを作成

Read-onlyはRDSのパラメータグループを用いて実現します。

(1)移行対象MySQLのパラメータグループをコピーして、ユニークなパラメータグループを作成

AWS RDSダッシュボード>移行対象MySQLのパラメータグループを選択>コピー>名前を任意にして作成

 

(2)(1)で作成したパラメータグループを編集、read_onlyの値を1にする

AWS RDSダッシュボード>(1)で作成したパラメータグループを選択>パラメータの編集>read_onlyの値を1にして作成

 


2.Auroraリードレプリカを作成


移行作業前に作成します。作成時間は環境によるので、事前検証を行い作成時間を見積もっておいて下さい。

(1)Auroraリードレプリカを作成

AWS RDSダッシュボード>移行対象MySQLを選択>インスタンスの操作>Auroraリードレプリカの作成を選択

作成時の設定は、Aurora独自の設定(パラメータグループ)以外は移行対象MySQLと同じにする。

 

 (2)作成完了の確認 

次の項目で、作成の完了を確認する。
・移行対象MySQLのレプリケーション欄で、Auroraリードレプリカのロールが”レプリカ”となっていること
・Auroraリードレプリカのレプリケーション欄で、DBクラスターロールが”レプリカ”であること

 

 

◆移行作業


移行作業では、Read-only、接続断がそれぞれ数分発生するので、サービス影響が最も無い時間帯に実施します。


1.移行対象MySQLのパラメータグループを変更して、Read-onlyにする

(1)移行対象MySQLのパラメータグループを、事前準備の1で作成したものに変更

AWS RDSダッシュボード>移行対象MySQLを選択>インスタンスの操作>変更>パラメータグループを変更

 

(2)移行対象MySQLを再起動する 

AWS RDSダッシュボード>移行対象MySQLを選択>インスタンスの操作>再起動

 
(3)移行対象MySQLでRead-onlyであることを確認

移行対象MySQLに接続後、次のようなコマンドを実行し、Read-onlyであることを確認する。

 


 mysql> create table hogehoge;

 次のエラーが出ること。
 ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it  cannot execute this statement

 

 

2.レプリカラグが無いことを確認

移行対象MySQLとAuroraリードレプリカとでデータの差(レプリカラグ)が無いことを確認する。Auroraリードレプリカに接続し以下を実行、レプリケーションラグが無いこと.

 


 mysql> show slave status\G

(`Seconds_Behind_Master: 0`)を確認する。

 


3.Auroraリードレプリカの昇格

(1)昇格を実行する

Auroraリードレプリカを選択>インスタンスの操作>リードレプリカの昇格

 

(2)昇格完了を確認する

昇格したAuroraの詳細欄で、DBクラスターロール=マスターを確認

 

 


4.アプリの切り替え(移行対象MySQL→昇格したAurora)

アプリの接続先(エンドポイント)を「移行対象MySQL」から「昇格したAurora」に切り替えます。切り替えは、ご自身の環境に応じて実行して下さい。


なお、この方法では移行対象MySQL(インスタンス名をAとする)を別名の昇格したAurora(インスタンス名をBとする)に変える形なります。インスタンス名が変わるので、それを避けたい場合は、次の手順でインスタンス名の入れ替えを行って下さい。 

Bの昇格後、Aのインスタンス名をCにする。
その後、Bのインスタンス名をAにする。

 


5.事後確認

ご自身の環境に応じて、適切に正常性を確認して下さい。

 


6.移行対象MySQLの削除

不要な移行対象MySQLを削除します。

AWS RDSダッシュボード>移行対象MySQLを選択>インスタンスの操作>削除

 

  

 

以上です。作業実施前は、必ず作業の検証(リハーサル)を実施して下さい。
ご覧頂きありがとうございました。

大規模SaaS運用におけるAWSコスト削減7箇条

 こんにちは。フロムスクラッチのインフラチームに所属している山崎です。
今回は「大規模SaaS運用におけるAWSコスト削減」について投稿させて頂きます。

AWSのコスト管理に悩んでいる方は多いんじゃないかと思います。時間あたり費用は微々たるものですが、積もり積もると「え、こんなに使ったっけ?」ってなりますよね。

以下、私が実施してきたコスト削減の方法を大まかに挙げていきます。

 

(1)不要なサービスを停止・削除する。
簡単にAWS費用を分けると下記のようになります。

 1.サービス利用料
 2.サポート費用
 3.税金

3項目とも使用時間が長いほど請求されるので、身も蓋もない言い方をすれば、いかに使わないかがコスト削減の鍵になります。影響確認を実施して必要な手順を踏んだ後、ガンガンと停止・削除を進めていきましょう!(じゃないと、コストは下がりません)

◆AWSサポートプラン

f:id:daisuke-yamasaki:20180306181605p:plain

  

(2)本番環境と開発環境でサポートのプランを分ける(アカウントを分ける)
(1)で示したサポート費用はプランが4つに別れ、それぞれでサービス・費用が異なります。環境に合わせた適切なプランを選択しましょう。

https://aws.amazon.com/jp/premiumsupport/signup/

例えば、本番環境は「ビジネス」か「エンタープライズ」プランのアカウント、開発環境は「開発者」プランのアカウントに分けるだけでコストを削減できます。

◆アカウント作成

f:id:daisuke-yamasaki:20180306181738p:plain

  

(3)RIを利用する。
RI(reserved instance)を利用することで、通常のオンデマンド費用を割引額で利用することができます。RIは、EC2,RDS,Redshift,DynamoDB,Elasticacheの各種サービスで適用することが可能です。割引額は、EC2でだいたい20%~50%です。ただし、1年または3年の長期契約となるので、サービスや財務の見通しを考えて購入しましょう。AWSは変化が早く年単位で新世代のインスタンスがリリースされることがあるので、期間1年のRIを支払い方法「一部前払い」で購入することをオススメします。「一部前払い」も「全前払い」もあまり割引率が変わりませんので、キャッシュアウトが少なくてすむ「一部前払い」のほうが良いでしょう。

 

購入後のRI数の確認についてですが、RIとオンデマンドインスタンス数がリアルタイムで分かるように監視ツールを整えれば、現状確認をスムーズに行うことができます。

最後になりますが、EC2のRIは「統合」「分割」ができます。例えば、同時購入した「m4.xlarge」が2つあれば、「m4.2xlarge」に「統合」でき、その逆に「m4.2xlarge」を2つの「m4.xlarge」に分割できます。この機能を利用できる機会ができたら、コスト削減に利用しましょう。

◆EC2 リザーブドインスタンス

f:id:daisuke-yamasaki:20180306181901p:plain

  

(4)夜間・休日はサーバを止める。
主に開発環境の話になりますが、使わない時間帯のサーバを自動で止め、コストを削減しましょう。

  

(5)過剰な冗長設定を外す。
RDSの「マルチAZ」が本当に必要か、リードレプリカの数やELBに繋がったEC2の数は妥当か検討しましょう。「マルチAZ」だと「シングルAZ」の2倍の費用を払う必要があります。サービスローンチ当初はインシデントを防ぐため「マルチAZ」を選びがちですが、必要ないと判断できたら「シングルAZ」にしましょう。

 

 (6)定期的に性能を見直す。
リソース状態を見て、サーバの性能が過剰になっていないか検討しましょう。(インシデントを防ぐため、その逆も実施しましょう)EC2の性能は高すぎないか、数を集約できないか、Redshiftのノード数は適切か、などです。ただし、性能を落とすことはサービス影響のリスクがあるので慎重に実施しましょう。

 

 (7)不要なAMIやスナップショットは定期的に削除する。
地味ですが、不要なバックアップ類は管理されないと増え続けます。1ヶ月に1回など定期的な削除機会を作り、定期削除を実施しましょう。

 

以上、AWSインフラのコスト削減方法について記載しました。ご覧頂きありがとうございました。

Apache ZooKeeperの内部解析してみる vol.2 ~ZooKeeper操作編~

こんにちは、fukuです。

前回に引き続きApache ZooKeeperについて書いていきます。前回ではZooKeeperの概要の説明を行いました。ZooKeeperではznodeから構成されるデータノードを管理しており、クラアントはAPIを通じてデータノードの操作を行うことができます。 今回は実際にZooKeeperを操作することでZooKeeperのAPIなどについての理解を深めていきましょう。

インストール

ZooKeeperのダウンロードページApache ZooKeeper - Releasesからダウンロードを行います。今回はZooKeeperのバージョン3.5.3-beta(何事も先取って検証)を対象とし、macOS Sierra(バージョン10.12.6)のOS環境上で検証を行いました。 ダウンロードしたzookeeper-3.5.3-beta.tar.gzファイルを任意のディレクトリに置き、以下のコマンド群を実行することで、ZooKeeperの起動の準備をします。

$ tar zxvf zookeeper-3.5.3-beta.tar.gz
$ cd zookeeper-3.5.3-beta.tar.gz
$ cp conf/zoo_sample.cfg conf/zoo.cfg

上記のコマンドを実行でZooKeeperが起動できるようになったので、以下のコマンドからスタンドアローンモードでZooKeeperをバックグラウンド(デフォルトポート2181)で起動することができます。

$ bin/zkServer.sh start

またサブコマンドを変更することでフォアグラウンドで実行することも可能です。

$ bin/zkServer.sh start-foreground

サーバを停止する時は、以下のコマンドを実行してください。

$ bin/zkServer.sh stop

ZooKeeperの利用

サーバを立ち上げた状態で、ZooKeeperのディレクトリにおいて以下のコマンドを実行することで、クライアントを起動することができます。

$ ./bin/zkCli.sh

無事に接続が確立すると、クライアントコマンドの待ち受け状態になります。ここでhelpを入力して、コマンド一覧を表示してみましょう(実際にはhelpというコマンドは存在せず、存在しないコマンドを入力することで以下のようなUSAGE情報が表示されます)。

[zk: localhost:2181(CONNECTED) 0] help
ZooKeeper -server host:port cmd args
    addauth scheme auth
    close 
    config [-c] [-w] [-s]
    connect host:port
    create [-s] [-e] [-c] [-t ttl] path [data] [acl]
    delete [-v version] path
    deleteall path
    delquota [-n|-b] path
    get [-s] [-w] path
    getAcl [-s] path
    history 
    listquota path
    ls [-s] [-w] [-R] path
    ls2 path [watch]
    printwatches on|off
    quit 
    reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*]
    redo cmdno
    removewatches path [-c|-d|-a] [-l]
    rmr path
    set [-s] [-v version] path data
    setAcl [-s] [-v version] path acl
    setquota -n|-b val path
    stat [-w] path
    sync path
Command not found: Command not found help

今回はいくつかのコマンドを実際に実行することで、ZeeKeeperで行えることをみていきましょう。

データツリーの操作

まずlsコマンドを使ってZooKeeperのデータノードを覗いてみましょう。

[zk: localhost:2181(CONNECTED) 1] ls /
[zookeeper]

上記から、データノードのルートノードには[zookeeper]のznodeがあることがわかります。[zookeeper]ノードはZooKeeperのシステム情報を管理するためのノードとなります。

それでは次にcreateコマンドからznodeを作成してみましょう。

[zk: localhost:2181(CONNECTED) 2] create /clients ""
Created /clients
[zk: localhost:2181(CONNECTED) 3] ls /              
[zookeeper, clients]

このようにcreateコマンドの第1引数にznodeの名前、第2引数でznodeに格納するデータを指定することで、znodeが作成されます。 ちなみに今回のcreateコマンドでできたznodeはPERSISTENTノードとなります。

getコマンドではznodeの情報を参照することができます。

[zk: localhost:2181(CONNECTED) 4] get /clients

ここでは、出力としてcreate`コマンドで指定したデータ(今回は空文字列)が出力されます。

続いてsetコマンドで、znodeのデータを変更してみましょう。

[zk: localhost:2181(CONNECTED) 5] set /clients "hogehoge"
[zk: localhost:2181(CONNECTED) 6] get /clients           
hogehoge

上位のようにznodeに格納されているデータが空文字列から"hogehoge"に変わっていることがわかります。znodeのデータセットで注意しなければならないことは、データが置き換わるということです。そのためデータを追記したりすることはできません。

クライアントのセッションを終了するにはquitコマンドを実行します。

[zk: localhost:2181(CONNECTED) 7] quit
Quitting...
2017-12-30 20:32:17,295 [myid:] - INFO  [main:ZooKeeper@687] - Session: 0x160a6c05dcf0004 closed
2017-12-30 20:32:17,298 [myid:] - INFO  [main-EventThread:ClientCnxn$EventThread@520] - EventThread shut down for session: 0x160a6c05dcf0004

znodeのモード

ここでは前回記事で紹介したznodeのいろいろなモードを試していきたいと思います。createコマンドにはモードを指定するオプションが存在しており、オプションを指定する事によって、いろいろなモードのznodeを作成することができます。

PERSISTENT

PERSISTENTモードのznodeは、先ほどのようにcreateのオプションなしで作成することができます。

[zk: localhost:2181(CONNECTED) 0] create /clients/c1 "PERSISTENT"
Created /clients/c1

PERSISTENTモードではznodeが永続化されるので、セッションを終了してから、再度セッションを開始してもznodeがそのまま存在することが確認できます。

PERSISTENTモードのznodeを削除するにはdeleteコマンドによって、明示的に削除を行う必要があります。

[zk: localhost:2181(CONNECTED) 1] delete /clients/c1
[zk: localhost:2181(CONNECTED) 2] ls /clients
[]

EPHEMERAL

EPHEMERALモードではznodeの作成を行なったセッションが切断されると、znodeは自動的に削除されます。createコマンドで-eオプションの指定でEPHEMERALモードのznodeを作成することができます。ここではクライアントを2つ立ち上げてEPHEMERALモードのznodeをみていきます。

#  クライアント1
[zk: localhost:2181(CONNECTED) 0] create -e /clients/ephemeral-client "EPHEMERAL"
Created /clients/ephemeral-client

#  クライアント2
[zk: localhost:2181(CONNECTED) 0] ls /clients
[ephemeral-client]

#  クライアント1
[zk: localhost:2181(CONNECTED) 1] quit
Quitting...
2017-12-30 20:47:29,178 [myid:] - INFO  [main:ZooKeeper@687] - Session: 0x160a6c05dcf0006 closed
2017-12-30 20:47:29,180 [myid:] - INFO  [main-EventThread:ClientCnxn$EventThread@520] - EventThread shut down for session: 0x160a6c05dcf0006

# クライアント2
[zk: localhost:2181(CONNECTED) 1] ls /clients
[]

上記のようにクライアント1でEPHEMERALモードのznodeを作成すると、クライアント2でも作成したznodeの確認が行えます。次にクライアントのセッションを終了して、クライアント2でznodeの確認を行うとEPHEMERALモードのznodeのノードが削除されていることがわかります。

CONTAINER

CONTAINERモードのznodeは自身の子ノードが削除されると自動的にznodeが削除されます。createコマンドの-cオプションによって、CONTAINERモードを指定することができます。

[zk: localhost:2181(CONNECTED) 0] create -c /container ""
Created /container
[zk: localhost:2181(CONNECTED) 1] create  /container/child ""
Created /container/child
[zk: localhost:2181(CONNECTED) 2] delete /container/child 
[zk: localhost:2181(CONNECTED) 3] ls /
[clients, container, zookeeper]

<しばらくした後>

[zk: localhost:2181(CONNECTED) 4] ls /
[clients, zookeeper]

上記のようにCONTAINERモードのznode(/container)を作成して、子ノードを作成・削除します。その後にCONTAINERモードのznodeはすぐには削除されませんが、一定時間ののちにZooKeeperによって自動的に削除されます。

PERSISTENT_TTL

PERSISTENT_TTLモードがznodeの生存時間を指定することができ、指定時間後にZooKeeperによって自動的に削除されます。createコマンドの-tオプションによってPERSISTENT_TTLモードを指定することができます。

[zk: localhost:2181(CONNECTED) 0] create -t 600 /ttl_node ""
[zk: localhost:2181(CONNECTED) 1] ls /
[clients, ttl_node, zookeeper]

<しばらくした後(600ms以上)>

[zk: localhost:2181(CONNECTED) 2] ls /
[clients, zookeeper]

生存時間は-tオプションの後ろにミリ秒単位で指定します(上記は600ms)。作成直後はznodeが存在していることが確認できますが、600ms後しばらくしてから、確認するとznodeが削除されていることが確認できます。

ここで注意しなければいけないのは、ちょうど600ms後に削除されるのではなく、ZooKeeperの定期的にTTLモード(CONTAINERモードも同様)の削除を行うタイミングで削除が行われるという点です。そのため600ms後に初めてのZooKeeperの削除サイクルのタイミングが来た時に削除されます。デフォルトではZooKeeperの削除サイクルの時間間隔は2000msとなります。

長くなってしまったので、今回はこの辺で....

おわりに

今回は実際にZooKeeperをスタンドアローンモードで起動して、CLIからデータツリーに対するさまざまな操作を行いました。 次回はソースコードからデータツリーがどのように管理されているのかをみていこうと思います。

ではでは...