DevOps 技術: データベースのチェンジ マネジメント

多くの場合、データベースの変更はデプロイ時のリスクと遅延の主要な原因となります。DevOps Research and Assessment(DORA)では、継続的デリバリーの実装プロセス中にどのデータベース関連のプラクティスが役に立っているかを調べることで、ソフトウェア配信のパフォーマンスと可用性の両方を向上させました。

DORA の研究では、データベース作業をソフトウェア配信プロセスに統合することにより、継続的デリバリーを改善できることがわかりました。しかし、継続的デリバリーの実装の一部として、データベースの配信はどのように改善できるでしょうか。パフォーマンスの結果を予測するいくつかの手法があります。

DORA において、優れたコミュニケーションと包括的な構成管理がデータベースの課題に関連することを見いだしました。継続的デリバリーで成果を上げているチームは、データベースの変更をバージョン管理のスクリプトとして保存することで、本番環境のアプリケーションの変更と同じ方法で管理しています。さらに、アプリケーションの変更でデータベースの変更が必要な場合は、本番環境のデータベースを担当しているグループと協議し、エンジニアリング チームが保留中のデータベースの変更の進行状況について把握できるようにしています。

チームがこれらのプラクティスを実行すると、データベースの変更によってスローダウンが生じたり、コードのデプロイ時に問題が発生したりすることはありません。

データベースのチェンジ マネジメントの実装方法

効果的なデータベースのチェンジ マネジメントを実現するには、文化的な側面と技術的な側面の 2 つがあります。このセクションでは、両方の点について説明します。

データベース変更の効果的なコミュニケーションを確立する

調査によると、チームは本番環境のデータベースを管理するスタッフと変更について話し合う際、また、メンバー全員に保留中のデータベース変更の処理が可視化されている際に、最も良い成果を上げることがわかっています。

いくつかの理由で、本番環境のデータベース管理者(DBA)と提案された変更について検討することは非常に重要です。まず、これらのエキスパートからは、結果を得るための最適な方法のアドバイスや、パフォーマンスの問題などの潜在的な問題の指摘を得られます(多くのオペレーションにおいて、本番環境におけるパフォーマンス特性は、デベロッパー ワークステーションと比較して大きく異なります)。また、この協議により、DBA は、上流プロセスで起こっていることについての情報を得ることができ、将来の変更による影響に備えることができます。

変更の進捗状況を全員に可視化することはとても重要です。それにより、DBA を含む全チームが、今後の変更、そのテスト結果、さまざまな本番環境と非本番環境の共有データベースに対して影響を与えるスキーマ変更について把握できます。次の方法で可視化できます。

  • すべてのデータベース スキーマの変更を、スキーマが属するアプリケーション コードとともに、バージョン管理に保持する。
  • どの変更がどの環境で実行され、どのような結果であったかを記録するツールを使用する。

これらのプラクティスでは、すべての変更が正当な情報源であることが保証され、監査目的のために変更履歴を簡単に確認できるようにします。

すべてのデータベース スキーマの変更を移行として扱う

データベース変更のバージョニングに広く使用されているパターンは、次の図に示すように、すべての変更をバージョン管理において保持されている移行スクリプトとしてキャプチャすることです。各移行スクリプトには、固有のシーケンス番号があるため、移行へ適用する順序がわかります。

図は、固有のシーケンス番号を持つ移行スクリプトとして、データベースに対する変更をすべてキャプチャする方法を示しています。

次に、すべてのデータベース インスタンスに、特定のインスタンスに対してどの移行が実行されたかを記録したテーブルがあることを確認します。このようにデータベース スキーマをバージョン管理することで、移行スクリプトを適用するツールを使用して、データベースを目的のスキーマ バージョンに移行させることができます。ツールの例は次のとおりです。

移行を使用して、開発とテスト用に空のデータベース スキーマを作成することもできます。

次の図に示すように、すべてのデータベース インスタンスには、そのインスタンスに対して実行した移行を記録するテーブルがあります。その後、データベース インスタンスに対してまだ適用されていない移行を実行するツールまたはスクリプトを使用して自動的に更新を実行し、各更新が正常に完了した後に移行テーブルを更新できます。

インスタンスへの移行を記録するテーブルの例。

データベースの変更を管理する場合は、アプリケーションの変更を管理するプロセスと同様に、バージョン管理を信頼できる情報源として使用する自動化されたプロセスを使用します。

ダウンタイムが発生しないデータベースの変更

多くの組織は、データベース スキーマの変更時にサービスのダウンタイムのスケジュールを立てています。これは、アプリケーションのデプロイとの調整や、このような変更の実行中にデータベース テーブルのロックをする必要があるためです。継続的デリバリーでは、デプロイのダウンタイムの排除が目標となっています。次に、ダウンタイムなしにデータベース スキーマを変更する戦略をいくつか紹介します。

  • gh-ostpt-online-schema-change などのオンライン スキーマ移行フレームワークを使用する。ここれらのツールでは、変更する各テーブルの「ゴースト」コピーを作成し、空のコピーを移行してから、移行中に発生する更新を含むデータを元のテーブルから段階的にコピーします。この処理が完了すると、元のテーブルはゴーストに置き換えられます。Cloud Spanner などの一部のデータベースでは、ダウンタイムなしでスキーマ更新を実行できます。
  • 並列変更パターンを使用して、データベースの変更とアプリケーションの変更を分離する。このパターンでは、既存のデータベース オブジェクトが変更されることはありません。代わりに、古い構造に併せて新しい構造を追加します。たとえば、「address」列を「address_1」と「address_2」という 2 つの列に変更することを検討します。

    古い列を削除して新しい列を追加してアプリケーションの新しいバージョンを同時にロールアウトするのではなく、新しい列を追加して古い列を残します。これは、アプリケーションのデプロイの前に行えます。次に、アプリケーションの新しいバージョンは新しい列を探し、null ではなく新しい列が存在する場合にはそこから読み取り、存在しない場合は古い列から読み取ります。アプリケーションはその後、古い列と新しい列の両方に書き込み、データを必要に応じて移行します。また、データベースのロールバックを行わずにアプリケーションをロールバックすることもできます。

    このようにして、アプリケーションのデプロイはデータベースの変更から切り離すことができます。これは、通常はデータの移行は伴わないため、ダウンタイムを発生させずに実施できます。デプロイの問題を軽減するために、アプリケーションをさらに複雑しないようにしました。または、データベース トリガーを使用して、新しい列と古い列でのデータの同期を保つこととができます。

  • データのパーティショニングとアーカイブ戦略を設計して実装する。移行に時間がかかる主な原因としては、多数の行を含むデータベース テーブルが挙げられます。データが大きくなりすぎないように、アプリケーションがデータのパーティショニングとアーカイブを行えるように設計されていることを確認してください。たとえば、四半期ごとにテーブルの複数のインスタンスを作成する場合などです。たとえば、survey_answers テーブルの代わりに、survey_answers_2020Q1survey_answers_2020Q2 がある場合などです。アプリケーションの設計とアーキテクチャのレビューで、アプリケーションのデータ パーティショニングとアーカイブ戦略の検証が行われるようにします。

  • イベント ソーシング アーキテクチャを使用するイベント ソーシング アーキテクチャでは、アプリケーションの現在の状態を保存しているデータベースを使用するのではなく、代わりに、コマンドと呼ばれるイベントのログの形式で、その状態への変更を保存します。したがって、顧客の住所が変更された際には、顧客情報を使用してテーブルを更新するのではなく、アプリケーションによりデータベースに格納されている住所変更コマンドが発行されます。これが、データベース トランザクション ログとバージョン管理の仕組みであり、分散システムにおける一般的なパターンです。イベントソース アーキテクチャでは、イベントをキューに追加して、イベントのキューの実行中にデータベースの移行を行うことができます。移行が完了したら、キュー内のイベントをデータベースにフラッシュできます。一部のデータベースでは、スキーマの移行の実行中にクエリをキューに入れることができます。これは、移行が短時間で完了する場合に効果的です。

  • NoSQL ソリューションを使用するFirestoreCloud Bigtable などの一部の NoSQL データベースは、スキーマ変更によって作成されたダウンタイムの問題の影響を受けません。Firestore などのドキュメント データベースには暗黙のスキーマがあります。つまり、スキーマはデータベース レイヤではなくアプリケーション レイヤで管理されます。ただし、NoSQL データベースの使用に関してはトレードオフがあり、すべてのアプリケーションに最適とは限りません。

計画的なダウンタイムを排除するだけでなく、スケジュール外のダウンタイムも回避する必要があります。本番環境に似たデータセット(すべての個人情報や機密情報がスクラブされた状態)に対するすべてのスキーマ変更をテストし、アプリケーションが移行中と移行後に想定通りに動作していることを確認します。一部の組織では、この目的での使用のために、本番環境データベースのスクラブされたバージョンを毎日作成しています。本番環境に複数のノードを持つデータベース管理システムを使用している場合は、少なくとも 2 つのノードを持つインスタンスでテストし、分散システムの問題を解消してください。

データベースのチェンジ マネジメントを実装する際のよくある問題

以下で説明する主要な方法を実装する場合に注意すべき点がいくつかあります。

まず、多くの組織ではかなりのサイロ化が生じています。多くの場合、DBA は独自の個別のチームとして動いており、変更の管理のために独自のプロセスを使用しています。ソフトウェア デリバリー チームが DBA チームに相談せずにデータベースの変更を管理する新しいプロセスを実装した場合、DBA チームは管理しているデータベースを変更するためにその新しいプロセスを利用することに抵抗があるかもしれません。これにより、新しいプロセスに移行するメリットが大幅に減少する可能性があります。

最初にするべきことは、この記事で示したように目的を達成するための方法を両チームで協議することです。提案したプロセスや技術変更について同意を得ることが重要です。最善の方法は、どのような問題に直面しているかを尋ね、この記事で紹介しているアイデアがそうした問題に対処できるかを確認し、解決を手助けすることです。デリバリー チームと DBA が相互に許容できるソリューションを見つけることが理想的です。

この障害は、多くの場合、別の問題により悪化します。複数のアプリケーションが同じデータベース スキーマを共有しているという一般的な状況です。つまり、あるアプリケーションを使用しているチームは、他のアプリケーションに影響を与えることなくスキーマを変更できません。そのため、データベース スキーマを共有するすべてのアプリケーション用のデータベース変更を管理する単一のソリューションが必要になります。このような状況でデータベースの変更をデプロイするために、バージョン管理されたセルフサービス メカニズムを実装することは、正に可能で、間違いなく有益なことです。ただし、入念な計画とロールアウトが必要です。

最後に、移行ベースのデータベースのチェンジ マネジメントとゼロ ダウンタイム デプロイの両方を実装すると、かなりのアーキテクチャ上の変更が必要になります。これらの手法の実装に必要な作業を見積もる際は、この点を考慮してください。

データベースのチェンジ マネジメントを測定する方法

効果的なデータベース チェンジ マネジメント システムの目的は、データベースの変更によるデプロイの遅延や問題の発生を防ぐことです。データベースの変更が原因となった変更のうち、失敗した変更の割合と、データベースの変更に関連した作業がバージョン管理からリリースまでの全体的なリードタイムにどの程度寄与しているかを測定することは意味があることです。

データベースの変更でスケジュール設定されたダウンタイムが必要な場合は、この点も重要です。計画的ダウンタイムによる経済的影響を測定するには、ダウンタイムによって生じる可能性のある収益の損失と、デプロイを実行するための時間外勤務の労務費を考慮します。営業時間外でのデプロイは、チームが疲弊する原因にもなります。これらの影響は、このドキュメントで説明しているゼロ ダウンタイム デプロイのためのソリューションの実装に必要な作業について説明するために使用できます。

自動化のレベルの検討に際しては、完全に自動化されたプロセスを使用するプッシュボタン方式で行われるデータベース変更の割合を考慮します。目標は、100% のデータベース変更をこの方法で行うことです。

次のステップ