【レポート】DAT301: Deep-dive to Amazon Aurora #reinvent #dat301

ウィスキー、シガー、パイプをこよなく愛する大栗です。

本記事はAWS re:Invent 2017のセッション「DAT301 - Deep Dive on the Amazon Aurora MySQL-compatible Edition」のレポートです。

登壇者

AWSのVPであるAnurag Gupta氏が登壇しました。Anurag Gupta氏はAuroraの論文である「Amazon Aurora: Design Considerations for High Throughput Cloud-Native Relational Databases」1の執筆者の1人です。

レポート

アジェンダ

  • Auroraの基本
  • 最近の改善
  • 近日公開

Amazon Aurora

クラウドでRDBを再設計した

  • ハイエンドな商用データベースの性能と可用性
  • シンプルでOSSデータベース並にコスト効果が高い
  • MySQLとPostgreSQL互換
  • シンプルに使っただけの支払い

マネージドサービスとして提供する

クラウドのために設計されていないRDB

SQL、トランザクション、キャッシュ、ログがモノリシックなアーキテクチャになっており障害時の影響範囲が大きい

スケールアウト、分散アーキテクチャ

  • ログストラクチャーの分散ストレージとして作成
  • ストレージボリュームは3AZの数百ストレージノードに跨る
  • 6個のデータコピー、AZ毎に2個のコピー

なぜ6個のコピーが必要なのか?

  • 巨大な群ではいつでも故障が発生する
  • AZ障害は運命を共有する
  • AZ + 1個の障害を許容する必要がある
  • そのため3AZで6コピーが必要となる

復旧時間の最小化

  • セグメントが小さいと復旧が短くなる
  • Auroraは10GBのセグメントを使用している
  • フォルトトレランスのために
    • インパクトがないパッチ
    • ホットとコールドノードのバランス

失速無しのメンバーシップ変更

  • ほとんどのシステムのメンバーシップ変更では失速やゆらぎが起こる
  • Auroraではクォーラムセットと世代を使用している
  • 失速無し、AZ + 1のフォルトトレランス、障害検出

筆者注:動作の詳細はAmazon Aurora Under the Hood: クオーラムメンバーシップを参照

クォーラム読み取りを避ける

  • 全てのデータブロックでクォーラムグループ内の少なくとも4個が最新データを持っている
  • 4ノードのうちの1個を読めば最新データが返る

  • ほとんどのクォーラムシステムでは読み取りは高コストである

  • Auroraは最新データのノードとお互いのレイテンシを知っている
  • 復旧やクラッシュリカバリに必要な読み込みクォーラム

Auroraのパフォーマンス

どのように達成したか

  • より少なく
    • IOを少なく
    • ネットワークパケットを最小化
    • 結果のキャッシュ
    • DBエンジンのオフロード
  • より効果的に
    • 非同期に実行
    • レイテンシの低減
    • ロックフリーなデータ構造を使用
    • 一緒にまとめて運用

AuroraのIOトラフィック

  • パフォーマンス(MySQLとの比較)
    • 35倍のトランザクション
    • 7.7分の1のトランザクション当たりのI/O

AuroraのIOトラフィック(ストレージノード)

  • 観察
    • 前ステップが非同期
    • ステップ1と2がフォアグラウンドのレイテンシのパスとなる
    • 入力キューはMySQLと比べて46分の1になっている
    • 待ち時間にセンシティブな処理を優先
    • ディスクの空きを使用してアクティブなスパイクをバッファリングする

インスタンスクラッシュリカバリ

  • 基礎のストレージはディスク読み取りの一部としてオンデマンドでREDOレコードを再実行します
  • 並列、分散、非同期で行われる
  • 開始時に再実行しない

Auroraのクラッシュリカバリ

  • インスタンスはボリュームの全ストレージノードとオープンになっている
  • VCLはクォーラムが合った全てのレコードの最大ポイントを指す
  • CPLはVCL以下の最大のコミットレコードの最大ポイントを指す
  • すべての過去のCPLはクラッシュリカバリで削除される
    • ストレージノードを跨るコミットで2PCのための必要性を取り除く
    • データベースの開始前にRedoやUndoは必要ない

高速データベースクローニング(2017年8月)

  • データコピー無しでデータベースをクローン
    • ほぼ瞬間的なクローンの作成 -書き込みする時のみデータコピーが発生する - オリジナルかクローンのボリュームでデータが異なる
  • ユースケース
    • 商用環境のDBをテストに使用する
    • データベースの再編成
    • 商用環境のシステムに影響を与えることなく、分析のために特定時点のスナップショットを保存

Auroraのバックアップとリストア

各セグメントは定期的に並列でSnapshotをとる。継続的にS3へ送るがパフォーマンスや可用性への影響はない。リストアは適切なセグメントのSnapshotとログストリームをストレージノードへ転送して適用していく。

Backtrackでほぼ瞬間的にリストア(Coming soon)

  • Backtrackは望んだ時刻へデータベースを素早く戻す。
  • バックアップからリストアしない。データコピーはない。破壊的でない。
  • 誤ったDML/DDLのオペレーションから素早く復元する

リードレプリカエンドポイントのオートスケール(2017年11月)

  • 最大15インスタンスまでリードレプリカを複数のAZに跨って増やせる
  • Redoログベースのレプリケーションはレプリカラグが少なくなる - おおよそ10ms未満
  • 負荷分散とオートスケールに対応するリーダーエンドポイント NEW

オンラインDDL:Aurora対MySQL

MySQL
  • バックグラウンドでテーブルをすべてコピー
  • 全てのインデックスを再作成 - 数時間から数日かかる
  • DDL操作がDMLのスループットに影響を与える
  • DMLの変更でテーブルがロックされる
Aurora
  • スキーマバージョンを使用してブロックをデコードする
  • 最新のスキーマにアップグレードするための書き込み時変更プリミティブ
  • 現在テーブルの末尾にNULL許容カラムを追加する機能をサポート
  • 任意の場所にカラムを追加しデフォルト値の対応は近日公開

非同期キープレフェッチ

  • BKAアルゴリズム+MRR最適化を使用した問合せの動作
  • JOINを評価する時にセカンダリからプライマリのインデックスを実行する
  • バックグラウンドで非同期に使用する

バッチスキャン(coming soon)

  • 標準的なMySQLは、行を1つずつ処理するため、オーバーヘッドが大きくなる
    • 繰り返される関数呼び出し
    • ロックとラッチング
    • カーソルストアとリストア
    • InnoDBからMySQLへのフォーマット変換
  • Amazon AuroraはInnoDBバッファプールのタプルをバッチでスキャンする
    • テーブルフルスキャン
    • インデックスフルスキャン
    • インデックスレンジスキャン

ハッシュジョイン(coming soon)

  • バッチキーアクセス(BKA)ジョインアルゴリズムとのレイテンシの向上要因を比較
  • 意思決定支援システムのベンチマーク、r3.8xlarge、コールドバッファーキャッシュ(全データがキャッシュされている場合は改善率が低い)

Aurora Serverless

Aurora Serverlessとは

  • オンデマンドで起動し、未使用時はシャットダウンする
  • 自動的にスケールアップ/ダウンする
  • スケーリング時のアプリケーションに影響無し
  • 毎秒課金、最小1分

データベースエンドポイントのプロビジョニング

  • データベースをプロビジョニングすると、Aurora Serverlessは
    • アプリケーション接続のためにVPCエンドポイントをプロビジョニングする
    • 接続を受け入れるためにリクエストルーターを初期化する
    • Auroraストレージボリュームを作成する
  • データベースインスタンスは最初のリクエストが来た時にプロビジョニングされる

インスタンスのプロビジョニングをスケーリング

  • 最初のリクエストがインスタンスのプロビジョニングを開始する。通常1-3秒
  • ワークロード変更に応じてインスタンスは自動でスケールアップとダウンする。通常1-3秒
  • ユーザー指定の非アクティブ期間の後にインスタンスが休止する
  • スケーリング操作はアプリケーションに透過的 - ユーザーセッションは終了しない
  • データベースストレージはユーザーが確実に削除するまで永続的である

Aurora マルチマスタ

分散ロックマネージャ

  • 共有ディスククラスタ
    • キャッシング層での通信
  • ロッキングプロトコルメッセージ
    • グローバルリソースマネージャ
長所
  • 全ノードが全データを使用できる
  • アプリケーションを簡単に構築できる
  • マルチプロセッサと同様のキャッシュコヒーレンシ
短所
  • ロック毎に重量級のキャッシュ一貫性を保つトラフィックが発生する
  • ネットワークが効果になりがち
  • ホットブロックでは性能が落ちる

2フェースコミットやPaxosコミットによる一貫性

  • シェアードナッシング
    • SQL層での通信
長所
  • クエリが分割されてデータノードに送信される
  • 一貫性のためのトラフィックが少ない - コミットのみ
  • 多数のノードでスケール可能
短所
  • 重量級コミットとメンバーシップ変更プロトコル
  • レンジパーティショニングは、ホットブロックだけでなくホットパーティションが発生する可能性がある。再パーティショニングは高コスト。
  • クロスパーティション操作は高コスト。 小さなリクエストの方が良い。

分散台帳を使用したコンフリクト解決

  • Auroraには多くの一貫性の「オアシス」がある
  • データベースノードは、そのノードからのトランザクションのオーダーを知っている
  • ストレージノードは、そのノードに適用されたトランザクションのオーダー知っている
  • 複数のデータベースのノードと複数のストレージノードの両方でデータが変更された場合にのみコンフリクトが発生する
  • 必要な強制がより少ない

階層的なコンフリクトの解決

  • 両方のマスタが2つのページP1とP2に書き込んでいる
  • BLUEマスタはP1でクォーラムを獲得;ORANGEマスタはP2でクォーラムを獲得
  • 両方のマスタがコンフリクトを認識すると、2つの選択肢がある。(1)(1)トランザクションをロールバックするか(2)リージョナルリゾルバにエスカレートする
  • リージョン仲裁者がタイブレークの勝者を決める

マルチマスタにおけるクラッシュリカバリ

シングルマスタ

クラッシュが発生するとVCLより前の最新のCPLへ戻る

マルチマスタ

あるマスタでクラッシュが発生するとそのマスタが書き込んだデータではVCLより前の最新のCPLへ戻り、ホマのマスタが書き込んだデータは先へ進む。

マルチリージョンマルチマスタ

  • 書き込みはローカルで受け付ける
  • 楽観的同時実行制御 - 分散ロックマネージャなし、チャットロックマネージャプロトコルなし
  • 階層的に処理されるコンフリクト - ヘッドノード、ストレージノード、AZおよびリージョンレベルの仲裁人
  • 競合がないか、低いレベルにある場合、ほぼ直線的なパフォーマンスのスケーリング

Auroraパラレルクエリ

パラレルクエリ処理

Auroraストレージは数千のCPUを持っている
  • 押し下げる機会とストレージフリートを使用したパラレルクエリ処理を提供
  • 処理をデータの近くへ移動するとネットワークトラフィックとレイテンシが削減される
しかし重大な課題がある
  • ストレージノードに格納されているデータは、範囲が限定されない - フルスキャンが必要
  • データはイン・フライトであろう
  • 読み取りビューで最新データを表示できない場合がある
  • すべての機能をストレージノードに押し込めるすることはできない
ヘッドノードの処理
  • クエリオプティマイザはパラレルクエリプランを生成し、リーフページの検出に基づいてパラレルクエリコンテキストを作成する
  • パラレルクエリリクエストは、パラレルクエリコンテキストと共にストレージノードへ送信される
  • ストレージノードが生成
    • 処理された安定した行の部分的な結果ストリーム
    • 保留中のUNDOを持つ未処理の行のストリーム
  • ヘッドノードはこれらのデータストリームを集約して最終結果を生成する

ストレージノードの処理
  • 各ストレージノードは最大16個のパラレルクエリプロセスを実行し、それぞれパラレルクエリに関連付けられる
  • パラレルクエリプロセスはパラレルクエリコンテキストを受取り
    • スキャンするページのリスト
    • ビューとプロジェクションを読む
    • バイトコードの式評価
  • パラレルクエリプロセスはページリストを2回通過する
    • パス1:InnoDBでフォーマットされた生データのフィルター評価
    • パス2:MySQLフォーマットデータの式評価

パラレルクエリの例
  • ヘッドノードは、ハッシュジョインコンテキストを構成するストレージノードへ送信する
    • ページのリスト - ページIDとLSN
    • ジョイン式バイトコード
    • ビュー読み込み - どの行を含めるか
    • プロジェクション - どの列を選択するか
  • パラレルクエリプロセスは以下のステップを実行する
    • ページリストをスキャンする
    • 部分的ブルームフィルタを構築する; 統計情報の収集
    • 2つのストリームをヘッドノードに送信する
    • ハッシュに一致する行
    • 保留中のUNDOプロセスがある行
  • ヘッドノードは、異なるストレージノードからのデータストリームをマージした後に結合機能を実行する

パラレルクエリの性能

さいごに

KeynoteでAuroraマルチマスタとAurora Serverlessが発表されたため、とても期待の高いセッションでしたが、盛りだくさんのボリュームで大満足でした。

AuroraのDeep Diveは2015年、2016年、2017年と3回連続で参加しているのですが、例年に比べてAuroraの内部動作に迫る内容が多く難しいセッションでした(300台のレベルでしたが400を超えて500台と言えるくらい難しかった)。特に理解が難しいと感じたのが、「Auroraのクラッシュリカバリ」、Auroraマルチマスタの「分散台帳を使用したコンフリクト解決」と「階層的なコンフリクトの解決」でした。「Auroraのクラッシュリカバリ」は論文に記載されている内容であるため、なんとか内容の把握ができました。しかしAuroraマルチマスタに関する理論は、正直把握しきれていません。来年あたりにAuroraマルチマスタが論文化されることを期待します。


  1. http://allthingsdistributed.com/files/p1041-verbitski.pdf