© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. DevOps with Database on AWS アマゾン ウェブ サービス ジャパン株式会社 技術統括本部 2018年11月1日
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 自己紹介 山内 晃 (やまうち あきら) アマゾン ウェブ サービス ジャパン株式会社 ストラテジックアカウント本部 ソリューションアーキテクト 好きなAWSサービス • Amazon Relational Database Service (RDS) • Amazon Simple Storage Service (S3)
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. このセッションについて こんな方にオススメです • 開発サイクルの短縮や開発プロセスへの集中といった効果を狙って DevOpsに取り組まれているアプリケーション開発者 • 従来どおりの安定運用に加えて変化への対応スピードが求められて いるデータベース管理者 こんなことをお話しします • DevOps with Database はなぜ難しいのか? • “銀の弾丸がない” この課題にアプリケーション、データベースの 観点からどうアプローチできるか?
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Agenda • 前半(山内) • DevOps with Database はなぜ難しいのか • スキーマ変更にかかる時間を短縮するには • 後半(大村) • スキーマ変更のバージョンを適切に管理するには • 停止時間を最小化するリリース方法の例
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. DevOpsとは DevOps = 開発者 顧客 releasetestbuild plan monitor デリバリのパイプライン フィードバックループ 無駄やボトルネックを取り除くことで、 ライフサイクルを効率化し、高速化すること ソフトウェア開発のライフサイクル
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. DevOps with Database は なぜ難しいのか
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 変更対象 が異なる アプリケーション ソースコード スキーマ定義とデータ データベース
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 所要時間 が異なる アプリケーション 秒 〜 分 秒〜日 (操作やサイズ等に依存) データベース
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 担当者 が異なる アプリケーション Developer DBA データベース public class HelloWorld{ public static void main(String[] args){ System.out.println("Hello World!!"); } } CREATE TABLE t1 ( year_col INT, some_data INT ) PARTITION BY RANGE (year_col) ( PARTITION p0 VALUES LESS THAN (2017), PARTITION p1 VALUES LESS THAN (2018), PARTITION p2 VALUES LESS THAN MAXVALUE );
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 変更管理 が異なる アプリケーション バージョン管理ツール プロジェクト独自 データベース
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. DevOps with Database はなぜ難しい? 1. スキーマ変更に時間がかかる 2. バージョン管理が難しい 3. スキーマ変更はアプリケーションの停止を伴う
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. DevOps with Database を実現するには? 1. スキーマ変更に時間がかかる → 短時間でスキーマを変更するには? 2. バージョン管理が難しい → 安全にバージョン管理するには? 3. スキーマ変更はアプリケーションの停止を伴う → リリース方法を工夫して停止時間を短縮するには? この3つの課題にフォーカスして考えてみましょう
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. スキーマ変更にかかる時間を 短縮するには
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. データベースのスキーマ変更とは • テーブル の作成、削除、名前変更、最適化、圧縮、文字コード指定 • カラム の追加、削除、名前変更、並び替え、データ型変更 • キー(プライマリキー、外部キー)の追加、削除、削除&追加 • インデックス の追加、削除、名前変更、タイプ変更 • パーティション の作成、追加、削除 • ビュー の作成、変更、削除 etc... データ定義言語(DDL)によるオブジェクト定義の変更
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. スキーマ変更のパターン • メタデータだけを変更するDDL カラム名変更、インデックス削除、ビュー作成 など • 既存データのコピーを伴うDDL カラム追加・削除、インデックス追加、プライマリキー追加 など → 通常、瞬時に終了するのであまり気にすることはない → データ量に依存して時間がかかる (アプリケーションへの影響が懸念)
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 既存データのコピーを伴うDDL ② 新しい定義で空の一時表を作る ③ 元テーブルの データをコピー TBL ④ リネームして テーブルを入れ替え ① 元テーブルをロック (参照は許可、更新はブロック) 更新 × 参照 ○ 参照 ○ ⑤ ブロックしていた更新を リダイレクトして反映 更新 TBL (例)MySQL5.7でのカラム追加
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. スキーマ変更を手堅くやるには • アプリケーション(更新もしくは全体)を停止 • スナップショットを取得 • DDLを実行 • (問題が発生したらスナップショットから復旧) • アプリケーションを再開 → この方法だとDevOpsパイプラインに含めることは困難 (実行時間やアプリケーション影響が読めず自動化しづらい) → オンラインで(更新をブロックせずに)スキーマ変更したい
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. オンラインでのスキーマ変更(MySQL) • オンラインDDL(MySQL 5.6以降) DDLの例(MySQL 5.7) テーブル再構築 同時DML • テーブル名変更、カラム名変更 • 外部キー制約追加、削除 • インデックス削除 不要 可能 • カラム追加、削除、並び替え • プライマリキー追加、削除&追加 • インデックス追加(*1) 必要 可能 • カラムデータ型変更 • プライマリキー削除 • パーティション作成、追加、削除 (*2) 必要 不可 *1 再構築ではないが、データ量依存で時間がかかる *2 パーティションのタイプや操作に依存(例:レンジ、リストのパーティション追加、削除はコピー不要など) ALTER TABLE item ADD COLUMN price INT, ALGORITHM=INPLACE, LOCK=NONE;
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. オンラインでのスキーマ変更(Oracle Database) • オンライン・データ再定義(Enterprise Edition) • DBMS_REDEFINITIONパッケージを利用 • スキーマ変更中にDMLを実行できる • カラムの追加、削除、名前変更、表領域の移動、 圧縮属性の変更など様々な操作に対応 • カラム追加時のデフォルト値の最適化 • 既存レコードがすべて更新される(10gR2以前) • デフォルト値をメタデータだけに格納 • NOT NULL制約が必要(11g)/ 不要(12c) -- 元テーブル(original)を作成 CREATE TABLE original (col1 NUMBER PRIMARY KEY, col2 VARCHAR2(100)) TABLESPACE users; -- 仮テーブル(interim)を作成 CREATE TABLE interim (col1 NUMBER PRIMARY KEY, col2 VARCHAR2(100), col3 VARCHAR2(100)) TABLESPACE users; -- オンライン再定義を開始 BEGIN DBMS_REDEFINITION.START_REDEF_TABLE( uname => 'master', orig_table => 'original', int_table => 'interim', col_mapping => 'col1 col1, col2 col2', options_flag => DBMS_REDEFINITION.CONS_USE_PK); END; / -- オンライン再定義を終了 exec DBMS_REDEFINITION.FINISH_REDEF_TABLE('master', 'original','interim'); 【実行例】テーブル(original)にカラム(col3)を追加
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. オンラインでのスキーマ変更(SQL Server) • ONLINE ALTER COLUMN(Enterprise Edition) • SQL Server 2016以降のTransact-SQLでオンラインでの列変更をサポート • 制限事項についてはドキュメントで要確認 (*) • 複数列を同時に変更することはできない • チェック制約で参照されている列は変更できない • 変更される既存の列には2倍の領域割り当てが必要 etc.. * ALTER TABLE (Transact-SQL) https://docs.microsoft.com/ja-jp/sql/t-sql/statements/alter-table-transact-sql ALTER TABLE item ADD price INT WITH (ONLINE = ON);
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 新テーブルにカラム追加して結合する 参照 参照 参照 ③ 参照はビューを見せる TBL ① 追加カラムを持つ 新テーブルを作成 TBL_1 TBL_N ・・・ ② 新旧テーブルを結合して ビューを作成(変更)VIEW 更新 ④ 更新はテーブルに行う How? • カラム追加をテーブル作成とビュー作成(変更)に置き換える PROS CONS • 停止時間を短縮できる (更新を長時間ブロックしない) • キー値のコピーが必要(テーブル作成時) • 結合ビューは複数テーブルを更新できない • 繰り返すと結合が多くなる
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 予備カラムを定義する title pages更新 参照 参照 ③ 参照、更新共に ビュー経由で行う yobi1 yobi2 ② ビューを作成(変更)し、 カラム名を変更 VIEW ① 予備カラムを定義して テーブルを作成 TBL How? • カラム追加をビュー変更で置き換える PROS CONS • 停止時間を短縮できる (更新を長時間ブロックしない) • 必要数分の予備カラムを予め定義 • データ型、キー、制約、インデックスの変更に は対応できない(ALTER TABLEが必要)
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. JSON型を使う -- JSON型のカラムを定義してテーブル作成 CREATE TABLE item (id INT, name VARCHAR(20), tags JSON); -- 異なる属性を持つJSON型のデータを挿入 INSERT INTO item (id, name, tags) VALUES (1, 'Book', JSON_OBJECT(‘title', ‘The Four', 'pages', '245')); INSERT INTO item (id, name, tags) VALUES (2, 'PC', JSON_OBJECT(‘type’, ‘laptop', 'weight', '1.37')); -- 属性を指定してJSON型のデータを検索 SELECT id, name FROM item WHERE JSON_EXTRACT(tags, "$.weight") = "1.37"; How? • JSON型のカラムを定義して、単一のカラムで属性が異なる複数の値を格納する PROS CONS • RDBMSの特性を残したまま、NoSQLの柔軟性 (スキーマレス)を使える • 検索が遅い(インデックスが使えない) • 検索や更新の実装が複雑になる • 値の妥当性検証(データ型)や参照整合性 (外部キー制約)の担保が困難になる
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 前半のまとめ (DevOps with Database を実現するには?) 1. スキーマ変更に時間がかかる → 短時間でスキーマを変更するには? • オンラインでのスキーマ変更 • 新テーブルにカラム追加して結合する • 予備カラムを定義する • JSON型を使う 2. バージョン管理が難しい → 安全にバージョン管理するには? 3. スキーマ変更はアプリケーションの停止を伴う → リリース方法を工夫して停止時間を短縮するには?
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 自己紹介 大村 幸敬 (おおむら ゆきたか) アマゾン ウェブ サービス ジャパン株式会社 インダストリソリューション部 ソリューションアーキテクト 好きなAWSサービス • AWS CLI (Command Line Interface)
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Evolutionally Database Design アジャイル開発でデータベースの Continuous Integration と リファクタリングを行うための 11のプラクティスを紹介 https://www.martinfowler.com/articles/evodb.html by Martin Fowler & Pramod Sadalage (2016) 1. DBAとデベロッパがコラボレートする 2. DB成果物をアプリとともにバージョン管理する 3. 全てのDB変更はマイグレーションで管理する 4. 全ての開発者に自分のDBを提供する 5. 開発者はDBの変更を継続的に統合する 6. DBはスキーマとデータで構成される 7. 全てのDBの変更はリファクタリングである • DBの移行中フェーズの扱い 8. リファクタリングを自動化する 9. 開発者が自分のDBをOnDemandで更新できる 10. DBへのアクセスコードを明確に分離する 11. 頻繁にリリースする
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. DevOps with Database を実現するには? 1. スキーマ変更に時間がかかる → 短時間でスキーマを変更するには? 2. バージョン管理が難しい → 安全にバージョン管理するには? 3. スキーマ変更はアプリケーションの停止を伴う → リリース方法を工夫して停止時間を短縮するには?
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. スキーマ変更のバージョンを 適切に管理するには
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. アプリ開発に伴うDBの変更 スキーマ定義 (DDL) マスタデータ 変更後データ (DML)
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. DBの変更作業 DBへの変更要求をコード変更に合わせて適用するには? コード DB変更要求 開発者 Production DB コード DB変更要求 Integration DBDBA Staging DB Dev DB開発者 v1 v1 v2 v2
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 全てのDB変更をマイグレーションで管理 • ツールによるマイグレーションの管理と自動化 • スキーマの変更をDDL/DMLのセットで定義 • 適用時およびロールバック時の処理をコードで記述 Integration DB Staging DB Production DB DBA v1 v2 v3 v4 v5 v6 v7 Dev DB Dev DB Dev DB Dev DB v7 v6 v5
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. マイグレーションの実装例 Ruby on Rails の Active Records • マイグレーションファイル • DBスキーマをDSLで定義 • ver up/down時の処理を記述 • 任意のSQL記述も可能 • マイグレーションファイル構成 • db/migrate ディレクトリに配置 • ファイル名形式は YYYYMMDDHHMMSS_add_products.rb
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. マイグレーションの実行例 指定したバージョンのマイグレーションまでを実行 ロールバックしてひとつ前のバージョンに戻る $ rails db:setup $ rails db:rollback $ rails db:migrate VERSION=20181101120000 DBの初期化 特定バージョンのマイグレーション処理のみを実行 $ rails db:migrate:up VERSION=20181101120000 異なる環境のマイグレーションを実行 $ rails db:migrate RAILS_ENV=dev v0 v2 v5 ProductionDev v1 v2 v3 v4 v5 v5 v5
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. さまざまなDBマイグレーションツール フレームワークに付属 • Ruby on Rails (Ruby) • Laravel (PHP) • Entity Framework (.NET) • Django (Python) • etc... 専用ツール • Flyway • Liquibase • MyBatis • Phinx • sql-migrate • etc...
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. DevOps with Database を実現するには? 1. スキーマ変更に時間がかかる → 短時間でスキーマを変更するには? 2. バージョン管理が難しい → 安全にバージョン管理するには? 3. スキーマ変更はアプリケーションの停止を伴う → リリース方法を工夫して停止時間を短縮するには?
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 停止時間を最小化する リリース方法の例
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. DevOpsと無停止リリース • 外部調停なくリリースできることはDevOpsに必須 • リリースに伴う停止時間がなければ外部調停不要 • 無停止リリースの課題: 移行フェーズ • アプリ変更、DBスキーマ変更に伴う停止時間 • 新旧アプリと新旧スキーマの組み合わせのハンドリング Database refactorings, being applied to legacy database and the phases it needs to take before being implemented from Evolutionally Database Design
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. リリースへの影響:ステートレスとステートフル • ステートレスなアプリケーションの変更 • 複数のサーバやコンテナ • 順に停止&起動することで無停止入れ替え可能 • ステートフルなデータストアの変更 • 多くは単一のデータストアを共有 • 単純に更新すると停止時間が発生 • 構造化データストアはスキーマ変更が課題 • 非構造化データストアはスキーマ変更不要 v1 v1 v1 v2 v2 Stateless Stateful
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 無停止リリースのパターン A: DBを共有 DBとアプリの変更を個別に実施 • DBとアプリケーションが疎結合であること • 新旧アプリでDBを共有 • 一般的にはこの方法を推奨 リリースのパターン 1. DBスキーマ変更→アプリ変更 2. アプリ変更→DBスキーマ変更 Change schema Start app deployment Finish app deployment Start app deployment Finish app deployment Change schema
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. パターンA-1: DBスキーマ変更を先行 旧アプリが新スキーマで稼働できる場合 (カラム追加など) • 例)新アプリで不要なカラムが残る可能性があるが無視 • 例)旧アプリが追加したデータをTriggerで新スキーマへ投入 v1 v1 v1 v1 v1 v1 v1 v2 v2 v2 v1 v2 v2 v2 v2 v2 • 旧アプリ • 新スキーマ • 新旧アプリ混在 • 新スキーマ スキーマ変更に 伴う処理停止の 最小化 アプリデプロイに伴う 処理停止の最小化 (Draining) 移行フェーズ
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. パターンA-2: アプリリリースを先行 新アプリが旧スキーマで稼働できる場合(カラム削除など) • 例)リリース完了後は旧アプリを稼働できない • 例)削除されたカラムへの依存が新アプリに残っているとエラーが発生(要テスト) v1 v1 v1 v1 v2 v2 v1 v2 v2 v2 v2 • 新旧アプリ混在 • 旧スキーマ • 新アプリ • 旧スキーマ スキーマ変更に 伴う処理停止の 最小化 アプリデプロイに伴う 処理停止の最小化 (Draining) v1 v1 v2 v2 v2 移行フェーズ
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 閑話休題:アプリバージョンの混在 新機能はいつから有効か? • デプロイされ次第 • フィーチャーフラグが変更され次第 フィーチャーフラグはどこに配置するか? 1. アプリサーバ上のファイル • CodeDeploy や SSM* RunCommandで設定 2. 設定格納用のデータストア • SSM* ParameterStoreに格納 3. データと同じDB • マイグレーションで管理 機能A: ◯ 機能B: × SSM Parameter Store *SSM = AWS Systems Manager SSM RunCommand DB v2 v2 v1
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. 無停止リリースのパターン B: 異なるDBの使用 DB自体を切り替える • 変更が大きくスキーマ変更処理やデータコピー による停止が許容できない場合 • アプリとDBが密結合で個別リリースできない場合 課題:新旧DBのデータを一致させること • 基本的に難しい問題 リリースのパターン 1. 主系DBのデータをレプリケーション 2. 新旧両方のDBをDouble Writeで更新
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. パターンB-1: レプリケーション Pros: トランザクション管理の複雑さを回避可能(DBが管理) Cons:切替え時にデータ同期完了まで待つ必要がある RDBMSにより異スキーマ間のレプリ可否が異なる W R R W R W R 事前にGreen環境の スキーマを変更 新旧スキーマ間でレプリ 書き込み停止 レプリ完了待ち 読み込みは可能 アクセス先 切り替え 書き込み再開 切り戻しに備えた逆レプリ (または別DBへのレプリ) 移行フェーズ
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. パターンB-2: Double Write Pros: DBによらずアプリケーションの制御で無停止切り替え、切り戻しが可能 Cons: データ整合性をアプリケーションで管理する必要がある 書き込み速度の低下(2-phase-commitの実施など) W R R W R W R 両系DBに 書き込み開始 アクセス先 切り替え 切り替えの完了 移行フェーズ W 新スキーマで準備
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. まとめ - DevOps with Database を実現するには? 1. スキーマ変更に時間がかかる → 短時間でスキーマを変更するには? 2. バージョン管理が難しい → 安全にバージョン管理するには? • DBマイグレーションツールの使用 3. スキーマ変更はアプリケーションの停止を伴う → リリース方法を工夫して停止時間を短縮するには? • 銀の弾丸はない • A: DBを共有: スキーマ変更とアプリ変更の組み合わせ • B: 異なるDBを使用: レプリケーションやDoubleWrite
© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Thank you!

DevOps with Database on AWS

  • 1.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. DevOps with Database on AWS アマゾン ウェブ サービス ジャパン株式会社 技術統括本部 2018年11月1日
  • 2.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 自己紹介 山内 晃 (やまうち あきら) アマゾン ウェブ サービス ジャパン株式会社 ストラテジックアカウント本部 ソリューションアーキテクト 好きなAWSサービス • Amazon Relational Database Service (RDS) • Amazon Simple Storage Service (S3)
  • 3.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. このセッションについて こんな方にオススメです • 開発サイクルの短縮や開発プロセスへの集中といった効果を狙って DevOpsに取り組まれているアプリケーション開発者 • 従来どおりの安定運用に加えて変化への対応スピードが求められて いるデータベース管理者 こんなことをお話しします • DevOps with Database はなぜ難しいのか? • “銀の弾丸がない” この課題にアプリケーション、データベースの 観点からどうアプローチできるか?
  • 4.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. Agenda • 前半(山内) • DevOps with Database はなぜ難しいのか • スキーマ変更にかかる時間を短縮するには • 後半(大村) • スキーマ変更のバージョンを適切に管理するには • 停止時間を最小化するリリース方法の例
  • 5.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. DevOpsとは DevOps = 開発者 顧客 releasetestbuild plan monitor デリバリのパイプライン フィードバックループ 無駄やボトルネックを取り除くことで、 ライフサイクルを効率化し、高速化すること ソフトウェア開発のライフサイクル
  • 6.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. DevOps with Database は なぜ難しいのか
  • 7.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 変更対象 が異なる アプリケーション ソースコード スキーマ定義とデータ データベース
  • 8.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 所要時間 が異なる アプリケーション 秒 〜 分 秒〜日 (操作やサイズ等に依存) データベース
  • 9.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 担当者 が異なる アプリケーション Developer DBA データベース public class HelloWorld{ public static void main(String[] args){ System.out.println("Hello World!!"); } } CREATE TABLE t1 ( year_col INT, some_data INT ) PARTITION BY RANGE (year_col) ( PARTITION p0 VALUES LESS THAN (2017), PARTITION p1 VALUES LESS THAN (2018), PARTITION p2 VALUES LESS THAN MAXVALUE );
  • 10.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 変更管理 が異なる アプリケーション バージョン管理ツール プロジェクト独自 データベース
  • 11.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. DevOps with Database はなぜ難しい? 1. スキーマ変更に時間がかかる 2. バージョン管理が難しい 3. スキーマ変更はアプリケーションの停止を伴う
  • 12.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. DevOps with Database を実現するには? 1. スキーマ変更に時間がかかる → 短時間でスキーマを変更するには? 2. バージョン管理が難しい → 安全にバージョン管理するには? 3. スキーマ変更はアプリケーションの停止を伴う → リリース方法を工夫して停止時間を短縮するには? この3つの課題にフォーカスして考えてみましょう
  • 13.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. スキーマ変更にかかる時間を 短縮するには
  • 14.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. データベースのスキーマ変更とは • テーブル の作成、削除、名前変更、最適化、圧縮、文字コード指定 • カラム の追加、削除、名前変更、並び替え、データ型変更 • キー(プライマリキー、外部キー)の追加、削除、削除&追加 • インデックス の追加、削除、名前変更、タイプ変更 • パーティション の作成、追加、削除 • ビュー の作成、変更、削除 etc... データ定義言語(DDL)によるオブジェクト定義の変更
  • 15.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. スキーマ変更のパターン • メタデータだけを変更するDDL カラム名変更、インデックス削除、ビュー作成 など • 既存データのコピーを伴うDDL カラム追加・削除、インデックス追加、プライマリキー追加 など → 通常、瞬時に終了するのであまり気にすることはない → データ量に依存して時間がかかる (アプリケーションへの影響が懸念)
  • 16.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 既存データのコピーを伴うDDL ② 新しい定義で空の一時表を作る ③ 元テーブルの データをコピー TBL ④ リネームして テーブルを入れ替え ① 元テーブルをロック (参照は許可、更新はブロック) 更新 × 参照 ○ 参照 ○ ⑤ ブロックしていた更新を リダイレクトして反映 更新 TBL (例)MySQL5.7でのカラム追加
  • 17.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. スキーマ変更を手堅くやるには • アプリケーション(更新もしくは全体)を停止 • スナップショットを取得 • DDLを実行 • (問題が発生したらスナップショットから復旧) • アプリケーションを再開 → この方法だとDevOpsパイプラインに含めることは困難 (実行時間やアプリケーション影響が読めず自動化しづらい) → オンラインで(更新をブロックせずに)スキーマ変更したい
  • 18.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. オンラインでのスキーマ変更(MySQL) • オンラインDDL(MySQL 5.6以降) DDLの例(MySQL 5.7) テーブル再構築 同時DML • テーブル名変更、カラム名変更 • 外部キー制約追加、削除 • インデックス削除 不要 可能 • カラム追加、削除、並び替え • プライマリキー追加、削除&追加 • インデックス追加(*1) 必要 可能 • カラムデータ型変更 • プライマリキー削除 • パーティション作成、追加、削除 (*2) 必要 不可 *1 再構築ではないが、データ量依存で時間がかかる *2 パーティションのタイプや操作に依存(例:レンジ、リストのパーティション追加、削除はコピー不要など) ALTER TABLE item ADD COLUMN price INT, ALGORITHM=INPLACE, LOCK=NONE;
  • 19.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. オンラインでのスキーマ変更(Oracle Database) • オンライン・データ再定義(Enterprise Edition) • DBMS_REDEFINITIONパッケージを利用 • スキーマ変更中にDMLを実行できる • カラムの追加、削除、名前変更、表領域の移動、 圧縮属性の変更など様々な操作に対応 • カラム追加時のデフォルト値の最適化 • 既存レコードがすべて更新される(10gR2以前) • デフォルト値をメタデータだけに格納 • NOT NULL制約が必要(11g)/ 不要(12c) -- 元テーブル(original)を作成 CREATE TABLE original (col1 NUMBER PRIMARY KEY, col2 VARCHAR2(100)) TABLESPACE users; -- 仮テーブル(interim)を作成 CREATE TABLE interim (col1 NUMBER PRIMARY KEY, col2 VARCHAR2(100), col3 VARCHAR2(100)) TABLESPACE users; -- オンライン再定義を開始 BEGIN DBMS_REDEFINITION.START_REDEF_TABLE( uname => 'master', orig_table => 'original', int_table => 'interim', col_mapping => 'col1 col1, col2 col2', options_flag => DBMS_REDEFINITION.CONS_USE_PK); END; / -- オンライン再定義を終了 exec DBMS_REDEFINITION.FINISH_REDEF_TABLE('master', 'original','interim'); 【実行例】テーブル(original)にカラム(col3)を追加
  • 20.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. オンラインでのスキーマ変更(SQL Server) • ONLINE ALTER COLUMN(Enterprise Edition) • SQL Server 2016以降のTransact-SQLでオンラインでの列変更をサポート • 制限事項についてはドキュメントで要確認 (*) • 複数列を同時に変更することはできない • チェック制約で参照されている列は変更できない • 変更される既存の列には2倍の領域割り当てが必要 etc.. * ALTER TABLE (Transact-SQL) https://docs.microsoft.com/ja-jp/sql/t-sql/statements/alter-table-transact-sql ALTER TABLE item ADD price INT WITH (ONLINE = ON);
  • 21.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 新テーブルにカラム追加して結合する 参照 参照 参照 ③ 参照はビューを見せる TBL ① 追加カラムを持つ 新テーブルを作成 TBL_1 TBL_N ・・・ ② 新旧テーブルを結合して ビューを作成(変更)VIEW 更新 ④ 更新はテーブルに行う How? • カラム追加をテーブル作成とビュー作成(変更)に置き換える PROS CONS • 停止時間を短縮できる (更新を長時間ブロックしない) • キー値のコピーが必要(テーブル作成時) • 結合ビューは複数テーブルを更新できない • 繰り返すと結合が多くなる
  • 22.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 予備カラムを定義する title pages更新 参照 参照 ③ 参照、更新共に ビュー経由で行う yobi1 yobi2 ② ビューを作成(変更)し、 カラム名を変更 VIEW ① 予備カラムを定義して テーブルを作成 TBL How? • カラム追加をビュー変更で置き換える PROS CONS • 停止時間を短縮できる (更新を長時間ブロックしない) • 必要数分の予備カラムを予め定義 • データ型、キー、制約、インデックスの変更に は対応できない(ALTER TABLEが必要)
  • 23.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. JSON型を使う -- JSON型のカラムを定義してテーブル作成 CREATE TABLE item (id INT, name VARCHAR(20), tags JSON); -- 異なる属性を持つJSON型のデータを挿入 INSERT INTO item (id, name, tags) VALUES (1, 'Book', JSON_OBJECT(‘title', ‘The Four', 'pages', '245')); INSERT INTO item (id, name, tags) VALUES (2, 'PC', JSON_OBJECT(‘type’, ‘laptop', 'weight', '1.37')); -- 属性を指定してJSON型のデータを検索 SELECT id, name FROM item WHERE JSON_EXTRACT(tags, "$.weight") = "1.37"; How? • JSON型のカラムを定義して、単一のカラムで属性が異なる複数の値を格納する PROS CONS • RDBMSの特性を残したまま、NoSQLの柔軟性 (スキーマレス)を使える • 検索が遅い(インデックスが使えない) • 検索や更新の実装が複雑になる • 値の妥当性検証(データ型)や参照整合性 (外部キー制約)の担保が困難になる
  • 24.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 前半のまとめ (DevOps with Database を実現するには?) 1. スキーマ変更に時間がかかる → 短時間でスキーマを変更するには? • オンラインでのスキーマ変更 • 新テーブルにカラム追加して結合する • 予備カラムを定義する • JSON型を使う 2. バージョン管理が難しい → 安全にバージョン管理するには? 3. スキーマ変更はアプリケーションの停止を伴う → リリース方法を工夫して停止時間を短縮するには?
  • 25.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 自己紹介 大村 幸敬 (おおむら ゆきたか) アマゾン ウェブ サービス ジャパン株式会社 インダストリソリューション部 ソリューションアーキテクト 好きなAWSサービス • AWS CLI (Command Line Interface)
  • 26.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. Evolutionally Database Design アジャイル開発でデータベースの Continuous Integration と リファクタリングを行うための 11のプラクティスを紹介 https://www.martinfowler.com/articles/evodb.html by Martin Fowler & Pramod Sadalage (2016) 1. DBAとデベロッパがコラボレートする 2. DB成果物をアプリとともにバージョン管理する 3. 全てのDB変更はマイグレーションで管理する 4. 全ての開発者に自分のDBを提供する 5. 開発者はDBの変更を継続的に統合する 6. DBはスキーマとデータで構成される 7. 全てのDBの変更はリファクタリングである • DBの移行中フェーズの扱い 8. リファクタリングを自動化する 9. 開発者が自分のDBをOnDemandで更新できる 10. DBへのアクセスコードを明確に分離する 11. 頻繁にリリースする
  • 27.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. DevOps with Database を実現するには? 1. スキーマ変更に時間がかかる → 短時間でスキーマを変更するには? 2. バージョン管理が難しい → 安全にバージョン管理するには? 3. スキーマ変更はアプリケーションの停止を伴う → リリース方法を工夫して停止時間を短縮するには?
  • 28.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. スキーマ変更のバージョンを 適切に管理するには
  • 29.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. アプリ開発に伴うDBの変更 スキーマ定義 (DDL) マスタデータ 変更後データ (DML)
  • 30.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. DBの変更作業 DBへの変更要求をコード変更に合わせて適用するには? コード DB変更要求 開発者 Production DB コード DB変更要求 Integration DBDBA Staging DB Dev DB開発者 v1 v1 v2 v2
  • 31.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 全てのDB変更をマイグレーションで管理 • ツールによるマイグレーションの管理と自動化 • スキーマの変更をDDL/DMLのセットで定義 • 適用時およびロールバック時の処理をコードで記述 Integration DB Staging DB Production DB DBA v1 v2 v3 v4 v5 v6 v7 Dev DB Dev DB Dev DB Dev DB v7 v6 v5
  • 32.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. マイグレーションの実装例 Ruby on Rails の Active Records • マイグレーションファイル • DBスキーマをDSLで定義 • ver up/down時の処理を記述 • 任意のSQL記述も可能 • マイグレーションファイル構成 • db/migrate ディレクトリに配置 • ファイル名形式は YYYYMMDDHHMMSS_add_products.rb
  • 33.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. マイグレーションの実行例 指定したバージョンのマイグレーションまでを実行 ロールバックしてひとつ前のバージョンに戻る $ rails db:setup $ rails db:rollback $ rails db:migrate VERSION=20181101120000 DBの初期化 特定バージョンのマイグレーション処理のみを実行 $ rails db:migrate:up VERSION=20181101120000 異なる環境のマイグレーションを実行 $ rails db:migrate RAILS_ENV=dev v0 v2 v5 ProductionDev v1 v2 v3 v4 v5 v5 v5
  • 34.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. さまざまなDBマイグレーションツール フレームワークに付属 • Ruby on Rails (Ruby) • Laravel (PHP) • Entity Framework (.NET) • Django (Python) • etc... 専用ツール • Flyway • Liquibase • MyBatis • Phinx • sql-migrate • etc...
  • 35.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. DevOps with Database を実現するには? 1. スキーマ変更に時間がかかる → 短時間でスキーマを変更するには? 2. バージョン管理が難しい → 安全にバージョン管理するには? 3. スキーマ変更はアプリケーションの停止を伴う → リリース方法を工夫して停止時間を短縮するには?
  • 36.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 停止時間を最小化する リリース方法の例
  • 37.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. DevOpsと無停止リリース • 外部調停なくリリースできることはDevOpsに必須 • リリースに伴う停止時間がなければ外部調停不要 • 無停止リリースの課題: 移行フェーズ • アプリ変更、DBスキーマ変更に伴う停止時間 • 新旧アプリと新旧スキーマの組み合わせのハンドリング Database refactorings, being applied to legacy database and the phases it needs to take before being implemented from Evolutionally Database Design
  • 38.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. リリースへの影響:ステートレスとステートフル • ステートレスなアプリケーションの変更 • 複数のサーバやコンテナ • 順に停止&起動することで無停止入れ替え可能 • ステートフルなデータストアの変更 • 多くは単一のデータストアを共有 • 単純に更新すると停止時間が発生 • 構造化データストアはスキーマ変更が課題 • 非構造化データストアはスキーマ変更不要 v1 v1 v1 v2 v2 Stateless Stateful
  • 39.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 無停止リリースのパターン A: DBを共有 DBとアプリの変更を個別に実施 • DBとアプリケーションが疎結合であること • 新旧アプリでDBを共有 • 一般的にはこの方法を推奨 リリースのパターン 1. DBスキーマ変更→アプリ変更 2. アプリ変更→DBスキーマ変更 Change schema Start app deployment Finish app deployment Start app deployment Finish app deployment Change schema
  • 40.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. パターンA-1: DBスキーマ変更を先行 旧アプリが新スキーマで稼働できる場合 (カラム追加など) • 例)新アプリで不要なカラムが残る可能性があるが無視 • 例)旧アプリが追加したデータをTriggerで新スキーマへ投入 v1 v1 v1 v1 v1 v1 v1 v2 v2 v2 v1 v2 v2 v2 v2 v2 • 旧アプリ • 新スキーマ • 新旧アプリ混在 • 新スキーマ スキーマ変更に 伴う処理停止の 最小化 アプリデプロイに伴う 処理停止の最小化 (Draining) 移行フェーズ
  • 41.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. パターンA-2: アプリリリースを先行 新アプリが旧スキーマで稼働できる場合(カラム削除など) • 例)リリース完了後は旧アプリを稼働できない • 例)削除されたカラムへの依存が新アプリに残っているとエラーが発生(要テスト) v1 v1 v1 v1 v2 v2 v1 v2 v2 v2 v2 • 新旧アプリ混在 • 旧スキーマ • 新アプリ • 旧スキーマ スキーマ変更に 伴う処理停止の 最小化 アプリデプロイに伴う 処理停止の最小化 (Draining) v1 v1 v2 v2 v2 移行フェーズ
  • 42.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 閑話休題:アプリバージョンの混在 新機能はいつから有効か? • デプロイされ次第 • フィーチャーフラグが変更され次第 フィーチャーフラグはどこに配置するか? 1. アプリサーバ上のファイル • CodeDeploy や SSM* RunCommandで設定 2. 設定格納用のデータストア • SSM* ParameterStoreに格納 3. データと同じDB • マイグレーションで管理 機能A: ◯ 機能B: × SSM Parameter Store *SSM = AWS Systems Manager SSM RunCommand DB v2 v2 v1
  • 43.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. 無停止リリースのパターン B: 異なるDBの使用 DB自体を切り替える • 変更が大きくスキーマ変更処理やデータコピー による停止が許容できない場合 • アプリとDBが密結合で個別リリースできない場合 課題:新旧DBのデータを一致させること • 基本的に難しい問題 リリースのパターン 1. 主系DBのデータをレプリケーション 2. 新旧両方のDBをDouble Writeで更新
  • 44.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. パターンB-1: レプリケーション Pros: トランザクション管理の複雑さを回避可能(DBが管理) Cons:切替え時にデータ同期完了まで待つ必要がある RDBMSにより異スキーマ間のレプリ可否が異なる W R R W R W R 事前にGreen環境の スキーマを変更 新旧スキーマ間でレプリ 書き込み停止 レプリ完了待ち 読み込みは可能 アクセス先 切り替え 書き込み再開 切り戻しに備えた逆レプリ (または別DBへのレプリ) 移行フェーズ
  • 45.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. パターンB-2: Double Write Pros: DBによらずアプリケーションの制御で無停止切り替え、切り戻しが可能 Cons: データ整合性をアプリケーションで管理する必要がある 書き込み速度の低下(2-phase-commitの実施など) W R R W R W R 両系DBに 書き込み開始 アクセス先 切り替え 切り替えの完了 移行フェーズ W 新スキーマで準備
  • 46.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. まとめ - DevOps with Database を実現するには? 1. スキーマ変更に時間がかかる → 短時間でスキーマを変更するには? 2. バージョン管理が難しい → 安全にバージョン管理するには? • DBマイグレーションツールの使用 3. スキーマ変更はアプリケーションの停止を伴う → リリース方法を工夫して停止時間を短縮するには? • 銀の弾丸はない • A: DBを共有: スキーマ変更とアプリ変更の組み合わせ • B: 異なるDBを使用: レプリケーションやDoubleWrite
  • 47.
    © 2018, AmazonWeb Services, Inc. or its Affiliates. All rights reserved. Thank you!