出典について
この記事はPercona Data Performance Blog内のVadim Tkachenko氏によるAmazon Aurora – Looking Deeper(2015/11/16)を翻訳したものです。
最近、私のPerconaの同僚であるYves Trudeauと業界の仲間であるMarco TusaがAmazon Auroraに関する記事を発表しました。実際のところ、Amazon Auroraは最近のホットな話題で、お客様からもAuroraの技術に関して多くの質問をいただいています。私は自分の意見を明らかにすることを決心しました。個人の実際に手を動かした経験に勝るものはありませんし、それを共有しようと思います。
私がこれから言及する資料は次のものです。
- [1] Amazon Re:Inventのプレゼンテーション: https://www.youtube.com/watch?v=CwWFrZGMDds
- [2] 上記のプレゼンテーションで使われたスライド: http://www.slideshare.net/AmazonWebServices/amazon-aurora
- [3] Sysbenchのベンチマーク結果をのせたAmazonのホワイトペーパー: https://d0.awsstatic.com/product-marketing/Aurora/RDS_Aurora_Performance_Assessment_Benchmarking_v1-2.pdf
プレゼンテーション [1]は最初に概要を確認するには非常に良い資料です。しかしながら、プレゼンターの方が述べていたある主張があり、私はそれに焦点をあてたいと思います。すなわち「Amazon AuroraはMySQL互換のリレーショナルデータベースエンジンで、ハイエンドの商用データベースのスピードおよび高可用性と、オープンソースのデータベースの簡易さおよびコスト効率の両方を兼ね備えています」というものです。
これはAmazon Auroraがオープンソースデータベースであるといっているわけではありませんが、Amazonをオープンソースと同等にするというゴールがあるに違いありません。
私はAmazon Auroraがオープンソースでないことを明確にしておきたいと思います。Amazon AuroraはオープンソースのMySQLエディションをベースとしていますが、それ自体はオープンソースではなく、独自の、クローズドソースデータベースです。
Amazon Auroraを選ぶことで、バグフィクスあるいはアップグレードを完全にAmazonに依存することになります。この観点からAmazon RDSにロックインされることになります。OracleあるいはMS-SQLのような商用データベースのようなロックインとは事情が違います。現段階ではまだ比較的簡単にアプリケーションをコミュニティーエディションのMySQLに移行できます。
AmazonはGPLv2の穴をついており、これはクラウドモデルにおいてソースコードを公開しないことを許容している、というものです。Amazon AuroraはPercona ServerやMariaDBとどのように異なるのでしょうか?これらの両プロジェクトはソースコードを公開することを求められています。これは配布モデルの問題にいきつきます。GPLv2は昔ながらの配布モデルに制限を加えています。つまり、ソフトウェアをダウンロードできるかソフトウェアバイナリのハードコピーを受け取れるなら、それに対応するソースコードを要求する権利があります。クラウドコンピューティングにおいてはこれは該当しません。何もダウンロードしませんし、ただインスタンスを起動するだけです。GPLv2はこのケースにいかなる制限も加えないため、AmazonはGPLv2に準拠しているわけです。
バグ修正
バグ修正に関しては、Amazon Auroraは自身で「version: 5.6.10, version_comment: MySQL Community Server (GPL)
」と開示しています。MySQL 5.6.10は2013年2月1日にリリースされており、2年半前となります。Auroraが2.5年分のバグ修正をしていて、バージョンを更新していないのか、あるいはこれが本当に2.5年前のコードベースのバイナリであるのかは明確にはわかりません。
例えば、次のMySQLのバグ http://bugs.mysql.com/bug.php?id=70577の例を見てみると、これは5.6.15で修正されていますが、Amazon Aurora 5.6.10でバグ修正がされていることを確認できませんでした。
他の例、http://bugs.mysql.com/bug.php?id=68041は、MySQL 5.6.13で修正されていますが、まだAmazon Auroraでは修正されていません。
InnoDBのコードベースについてはどうでしょうか?全文検索に関する次のバグhttp://bugs.mysql.com/bug.php?id=72548はMySQL 5.6.20(1年以上前のリリース、2014年7月31日)で修正されていますが、まだAmazon Auroraでは修正されていません。
この事実から、私は全体的なAuroraのコードベースは最近更新されていないような印象を受けました。
しかしながら、Amazonはinnodb_versionを変更しているようです。現在は1.2.10ですが、数週間前はinnodb_versionは1.2.8でした。
ここにおける私の疑問は、AmazonはMySQLのバグ修正に追従し、定期的にソフトウェアをアップデートしうるのだろうか、ということです。これまでのところ、できないようにみえます。
Amazon Auroraのアーキテクチャ
私のAmazon Auroraに対する理解は単純化すると下記のとおりです。
つまり、全てのAuroraインスタンスは同一のストレージを共有しており、同じデータで新たな「Reader」インスタンスを開始するのがとても簡単になっています。
Writerと(Writerは1ノードのみ)とReaderの通信はInnoDBのredoログレコードと似通っています。これによりWriterの制限(1つのみ)が発生しています。私はredoレコードベースで2つのWriter間の適切なトランザクションコーディネーターは実装できないと考えています。
同じ方法が共有ストレージに保存されるデータの更新に利用され、Auroraはredoログレコードをデータに適用すれば良いだけとなっています。
このようにデータを更新することでAuroraは下記のことが出来ます。
- ストレージへのデータ書込みが不要に
- バイナリログが不要に
- InnoDBのトランザクションログが不要に
- ダブルライトの無効化
- InnoDBのチェックサムの無効化
Auroraは顕著な性能向上があると謳っていますが、我々は各書込みが直接ストレージに行われ、6つの複製のうち4つの書込み応答が得られる必要がある(同期書込み)ことに注意する必要があります(訳注: Amazon Aurora はデータベースの各単位を 3 つのAZにかけて 6 個レプリケーションします)。AuroraのWriterは「ライトスルー」モードのように動作し、これは私が理解した限りにおいては、Readerが変更を即時に参照できるようにする為、必要となると理解しています。私はこれは性能面で不利な要素の1つであり、性能面の有利な点(performance gain)が不利な点(performance penalty)を上回るかどうかはワークロード依存となると予測しています。
現在は、Amazonのエンジニアリングチームはトランザクションのredoログの送信および適用を正しく実装している、と信じておりすばらしいことと思います。InnoDBエンジンを変更するにはしなければならないことがたくさんあったはずですし、我々が知るかぎりAmazonがAuroraを安定化させるのにはおおよそ1年(GAのアナウンスまで)かかっています。しかしながら、Amazonが主なコードベースをオープンソースのデータベースとしているにも関わらず、その変更をクローズドにしているのはとても良くないことです。
トランザクション分離レベルについてみてみる
分散コンピューティングはトランザクション処理の観点からはとりわけ複雑ですので(例となるシナリオをご覧ください)、Amazon Auroraが異なるノード上でどのようにトランザクション分離レベルを扱っているかを確認したくなりました。
幸せなことに、Auroraでは簡単になっています。Readerでは読込みのSQL文のみが許可されているためです。しかし、いくつかのケースでは依然として確認する必要があります。
トランザクション分離レベル(TRANSACTION ISOLATION
レベル)の中でサポートされているのは、REPEATABLE-READ
だけのようです。SERIALIZABLE
あるいはREAD-COMMITTED
に変更しようとしたときに、Auroraはエラーを発生させませんが、サイレントに無視されます。tx_isolation
がREPEATABLE-READ
のままとなります。
mysql> SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @@GLOBAL.tx_isolation, @@tx_isolation;
+-----------------------+-----------------+
| @@GLOBAL.tx_isolation | @@tx_isolation |
+-----------------------+-----------------+
| REPEATABLE-READ | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec)
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @@GLOBAL.tx_isolation, @@tx_isolation;
+-----------------------+-----------------+
| @@GLOBAL.tx_isolation | @@tx_isolation |
+-----------------------+-----------------+
| REPEATABLE-READ | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec)
実際のところ、これとは別の少し心配なことがありました。Auroraで周知なくひっそり変更が行われたのです。
数週間前にSERIALIZABLE
レベルを利用した時は、"SERIALIZABLE is not supported"
というエラーを出して失敗していたのです。現在時点ではサイレントに無視するだけとなっています。したがって、Amazonは変更を続けているものと考えています。これはinnodb_version
の1.2.8から1.2.10への変更の1つではないかと思っています。どこかに確認できる完全な変更履歴はあるのでしょうか?
SERIALIZABLE
がないことは大きな問題ではないと考えています。最終的にPercona XtraDB Clusterでもサポートしなくなっています。
READ-COMMITTED
が使えないことはいくつかのアプリケーションにとっては問題となるでしょう。READ-COMMITTED
がサイレントにREPEATABLE-READ
に変更されても、アプリケーションが正しく動作するかどうか確認する必要があります。
もう1つ普通でない動作がありました。ALTER TABLE
文をWriter上で実行しようとしたときの、ReaderとWriterの間の挙動です(これはクラスタのもう1つの困難な課題で、具体的にはデータ・ディクショナリの同期です)。
- シナリオ:
- READER: 次の長いクエリを発行している。
SELECT col1 FROM tab1
- WRITER: SELECTが実行中の間に、
ALTER TABLE tab1 ADD COLUMN col2
を実行する。
- READER: 次の長いクエリを発行している。
- 発生事象:
- READERのSELECTは即時に次のエラーを返す。
"ERROR 1866 (HY000): Query execution was interrupted on a read-only database because of a metadata change on the master"
- READERのSELECTは即時に次のエラーを返す。
Auroraは現在のアーキテクチャでは1方向のコミュニケーションを行うことがベストであると考えたのではないかと思います。すなわち、Readerの読込みステートメントをkillすることを選択したのです。
クエリキャッシュ
クエリキャッシュの改善はとても良い拡張なので、ご紹介しておく必要があります。クエリキャッシュは標準で有効化されており、AmazonはMySQLのクエリキャッシュの主な問題を解消しています。すなわち、クエリキャッシュのエントリの無効化を待つため更新クエリが長時間ストールするというものです。
この問題はAmazon Auroraでは発生しません。同時にAmazonはWriterとReaderのキャッシュの同期の問題にも適切に対処しています。Writeでデータが変更された時にReaderの対応するエントリのクエリキャッシュは無効化されます。
コンフィグの確認
AuroraのMySQLの設定を簡単に確認してみましょう。
デフォルト値から変更できないものがいくつかあります。
| innodb_change_buffering | none |
| innodb_checksum_algorithm | none |
| innodb_checksums | OFF |
| innodb_doublewrite | OFF |
| innodb_flush_log_at_trx_commit | 1 |
ダブルライトとチェックサムが無効化されているのは、既に言及済みなので驚くべきことではないでしょう。
innodb_flush_log_at_trx_commit
が厳密に1に設定されており、これはAuroraのredoログレコードの扱い方に関係していると考えています。
innodb_change_buffering
が無効化されているのも興味深く、これは性能上良いことではありません。私は、Amazonは変更がただちに共有ディスクに書き込まれるように、更新のバッファリングを無効化する必要があるのではないか、と考えています。
診断(diagnostic)
従来からRDSはvmstatとiostatなどのシステムメトリックにアクセスしやすいようになっておらず、これによりトラブルシューティングがとても難しくなっています。MySQLのスロークエリーログも利用不可能で、我々に残されたのはPERFORMANCE_SCHEMA
(デフォルトでOFF)のみとなります。
良い点としては、SHOW GLOBAL STATUS
にはアクセス可能となっており、モニタリングソフトウェア向けに利用することが出来ます。
面白いことにヘビーな書込み負荷のあとでも、次のカウンタは0のままでした。
| Innodb_buffer_pool_pages_dirty | 0 |
| Innodb_buffer_pool_bytes_dirty | 0 |
| Innodb_buffer_pool_pages_flushed | 0 |
| Innodb_pages_written | 0 |
これは私のアーキテクチャに関する考えを肯定する1つの要素で、すなわちAuroraはメモリに変更されたページを一切持たず、全てをストレージに直接書き込んでいるのではないかと思います。
最終的な考え
この投稿についてはベンチマークを行ってからフォローアップする予定です。すなわち、ダブルライトとバイナリログを使わないようにする効果があるとはいえ、アーキテクチャ上の大きな性能のペナルティーがあると予測しています。
概して、Amazon AuroraはMySQLを大きく進化させたプロプライエタリなバージョンであると考えています。しかしながら、これは革新ではなく、Amazonが主張しているように「考えなおされたRDB(reimagined relational databases)」ではありません。このテクノロジーは書込みのスケーリング、シャーディング、そしてノード間をまたがったトランザクションの扱いの問題に言及していません。
他の欠点としては、公式のバグデータベースがなく、詳細なユーザードキュメントがなく、Auroraのコードが古いMySQLのソースコードに基づいている、ことがあると思います。