運用システムは停止を許されません。午前2時に取引を処理する金融プラットフォーム、タイムゾーンを超えて医療従事者にサービスを提供する医療記録システム、大陸をまたいで貨物を追跡する物流アプリケーションなど、これらのシステムにはリファクタリング作業を行うためのメンテナンスウィンドウは存在しません。しかし、これらのシステムはすべて技術的負債を蓄積し、以前の制約の下で行われたアーキテクチャ上の決定を引き継ぎ、最終的には保守性、拡張性、セキュリティを維持するために構造的な変更を必要とします。ゼロダウンタイムリファクタリングは、この矛盾を解決する手法です。つまり、稼働中のシステムを、提供するサービスを中断することなく進化させる手法です。
課題は技術的なものだけではありません。組織的、そしてアーキテクチャ的な側面も重要です。オフラインにできないシステムをリファクタリングするには、開発中のシステムをリファクタリングするのとは異なる思考モデルが必要です。つまり、すべての変更は互換性がなくなるまで後方互換性を維持し、すべての構造的移行は可逆的でなければならず、すべての検証は合成テストではなく実際のトラフィックに対して行われなければなりません。これを可能にする技術、例えばブルーグリーンデプロイメント、フィーチャートグル、ストランギュラーフィグパターン、拡張・縮小データベース移行、冪等性を持つイベント駆動型アーキテクチャなどは、それぞれ個別に詳細に文書化されています。しかし、これらの技術が連携して、プロセス全体を通してユーザーにサービスを提供しなければならないシステムにおいて、持続的かつ安全な構造変更を実現するための首尾一貫した戦略としてどのように機能するかについては、あまり議論されていません。
ダウンタイムゼロの変更を実現するためのアーキテクチャの必須条件
チームがゼロダウンタイム・リファクタリングに取り組む際に最もよく尋ねる質問は、アーキテクチャに関するものです。つまり、リファクタリングを開始する前に、システムの構築方法についてどのような変更が必要なのか、ということです。答えは単一のパターンではなく、ライブ・リファクタリングを安全に行うためにシステムが満たすべき一連の構造的特性です。これらの特性を理解することが、このガイドの他のすべての内容を理解するための前提条件となります。
最初の特性は、独立したデプロイ可能性です。リファクタリングされるすべてのコンポーネントは、依存関係のあるコンポーネントを同時にデプロイする必要なくデプロイできる必要があります。サービスAを変更する際に、サービスBとサービスCを同時に変更して不具合を防ぐ必要がある場合、Aのダウンタイムゼロのデプロイは構造的に不可能です。3つのサービスは、リポジトリの数に関係なく、実質的に単一のデプロイ単位となるためです。独立したデプロイ可能性を実現するには、後方互換性のあるインターフェース、バージョン管理された契約、およびサービス間の連携デプロイ要件の排除が必要です。
2つ目の特性は可逆性です。稼働中の動作を変更するデプロイメントはすべて、数時間ではなく数分以内に元に戻せる必要があります。可逆性とは、単に古いバイナリを保持しておくことだけではありません。データベースの状態、キャッシュの状態、セッションの状態、および新しいバージョンによって変更される外部システムの状態が、古いバージョンと互換性があることが求められます。新しいバージョンが古いバージョンでは読み取れない形式でデータを書き込む場合、デプロイメントは定義上不可逆となり、ロールバックすると必ずエラーが発生するため、ダウンタイムゼロは不可能です。
3つ目の特性は、状態遷移の可視性です。両方のパスで可視的なメトリクスがないまま、あるコードパスから別のコードパスに動作を移行するリファクタリング作業は、盲目的に行われていることになります。チームは、移行が成功しているのか失敗しているのかを知ることができず、回帰を早期に検出することもできず、移行を加速または停止するタイミングについてデータに基づいた意思決定を行うこともできません。可視性は、問題が発生した後に追加するのではなく、リファクタリングを開始する前に計測する必要があります。 段階的なリファクタリングと技術的負債コードが何をするのか、そして何がそれに依存しているのかという構造的な可視性は、本番環境で失敗が許されないあらゆる変更を計画するための基盤となる。
ブルーグリーン展開:基本パターン
ブルーグリーンデプロイメントは、ダウンタイムゼロのリリースを実現するための基本パターンです。2つの同一の運用環境が存在します。1つはライブトラフィックを処理するブルー環境、もう1つは新バージョンを受け入れるグリーン環境です。ブルー環境が中断なくユーザーへのサービスを継続している間、グリーン環境では新バージョンがデプロイ、テスト、検証されます。グリーン環境の検証が完了すると、トラフィックはアトミックに切り替えられます。ロールバックはその逆で、トラフィックをブルー環境に戻し、ブルー環境は引き続き利用可能です。
このパターンは一見単純に思えるが、難しさはデータベース層にある。両方の環境が同じデータベースへの読み書きを行う必要がある場合、データベーススキーマは両方のバージョンと同時に互換性を持たなければならない。列の削除、フィールド名の変更、データ型の変更といったマイグレーションは、実行された瞬間に古い環境を破壊してしまう。そのため、ブルーグリーンデプロイメントは、このガイドのデータベースセクションで説明されている拡張・縮小スキーママイグレーションパターンと切り離せない関係にある。
カナリアリリースと段階的展開手法
カナリアリリースは、すべてのトラフィックを一度に切り替えるのではなく、トラフィックの一部を新しいバージョンにルーティングすることで、ブルーグリーンモデルを拡張したものです。カナリア展開は、まずユーザーの1%から開始し、そのグループのエラー率、レイテンシ、およびビジネス指標を監視し、その後、5%、20%、50%、100%と段階的に割合を増やしていきます。各段階で、自動化されたゲートが主要な指標が定義されたしきい値を超えて悪化していないかを確認します。ゲートが失敗した場合、ロールアウトは停止し、カナリアの割合はゼロに戻されます。
段階的なロールアウト手法では、このプロセスにターゲティングロジックを追加します。トラフィックをパーセンテージだけでルーティングするのではなく、ユーザーグループ、地域、サブスクリプションティア、セッション特性などでセグメント化できます。これにより、新しいバージョンを最も負荷の高い特定のユーザー層に対して検証してから、そのユーザー層を完全に移行することができます。重要な要件は、ロードバランサー、APIゲートウェイ、サービスメッシュなど、ルーティングインフラストラクチャがロールアウトに必要なきめ細かなターゲティングをサポートしていることです。
カナリアゲートを制御する指標は、ロールアウト開始前に定義する必要があります。エラー率、p99レイテンシ、データベースクエリ時間、コンバージョン率や決済成功率などのビジネス固有の指標はすべて、有効なゲート基準となります。ゲートのしきい値は、理論上の目標値ではなく、同等の負荷がかかった既存バージョンで測定したベースラインに基づいて調整する必要があります。トラフィックが2%の時点でゲートを通過し、20%の時点で失敗するロールアウトは検証されていません。カナリアが小さすぎて代表性がないためです。適切な段階的ロールアウトでは、統計的に意味のある比較を行うために、各段階で十分なトラフィックにさらされる必要があります。
機能切り替えスイッチとキルスイッチ
フィーチャートグルは、コードのデプロイと動作の有効化を分離します。リファクタリングされたコードパスは非アクティブ状態でデプロイされ、どのユーザーまたはリクエストが新しいロジックを実行するかを決定するトグルによって制御されます。トグルは段階的に有効化したり、特定のグループを対象にしたり、再デプロイなしで即座に元に戻したりできます。これにより、フィーチャートグルは、ブルー/グリーン移行やカナリア移行の方が適しているインフラストラクチャの変更とは異なり、ビジネスロジックのダウンタイムゼロ移行のための主要なメカニズムとなります。
キルスイッチは、フィーチャートグルの防御的な対応物です。フィーチャートグルの目的は、新しい動作を有効にすることではなく、動作が誤作動した場合に即座に無効にすることです。リファクタリングされた課金計算、新しい認証フロー、またはデータアクセスレイヤーの置き換えにキルスイッチを設定することで、オンコールエンジニアは、デプロイ、データベースのロールバック、またはチーム間の調整を必要としない、ワンアクションで復旧できるパスを得ることができます。キルスイッチは、API呼び出し、フィーチャーフラグ管理コンソール、または自動アラート統合を介してトリガーできるシステムで構成する必要があります。これにより、トリガーの遅延時間を数分ではなく数秒に抑えることができます。
トグルの衛生管理は、実際の運用上の懸念事項です。クリーンアップされないトグルはコードベースに蓄積され、制御フローの理解を困難にし、トグル状態とデータ状態の間に暗黙的な依存関係を生み出します。すべてのトグルには、文書化された所有者、予定された有効期限、およびクリーンアップチケットが必要です。トグル負債は他のあらゆる技術的負債と同様に深刻な問題であり、トグルは通常、システムの中で最も頻繁に変更される部分を保護するため、その蓄積速度は速くなります。
ダウンタイムなしのデータベースリファクタリング
データベースの変更は、ダウンタイムゼロのリファクタリングにおいて最も難しい部分です。なぜなら、データベースはステートフルで共有されており、大規模な変更には時間がかかるからです。アプリケーションは数分でデプロイおよびロールバックできますが、数億行のテーブルを変更するデータベース移行には数時間かかる場合があり、一度コミットすると簡単に元に戻すことはできず、その間は読み取りと書き込みをブロックするロックが保持されます。データベースのリファクタリングを正しく行うには、アプリケーションコードのリファクタリングとは異なるアプローチが必要であり、ほとんどのチームは、トラフィック量の多い稼働中のテーブルでスキーマ変更を初めて試みたときに、このことに気づきます。
中心となる原則は、データベースの変更はすべて、以前のバージョンのアプリケーションがデプロイされなくなるまで、以前のバージョンとの後方互換性を維持しなければならないということです。これは当然のことのように聞こえますが、一見すると分かりにくい影響があります。列の名前を変更するには、古い名前を削除する前に、新しい名前をエイリアスまたは複製として追加する必要があります。列の型を変更するには、古い列を廃止する前に、新しい型のシャドウ列にデータを投入する必要があります。テーブルを削除するには、デプロイされたアプリケーションのどのバージョンもそのテーブルからデータを読み取っていないことを確認する必要があります。これらの操作はそれぞれ、一度だけ実行される単一の移行ではなく、複数のデプロイメントにまたがるマルチステッププロセスです。より広い文脈で議論されているように、 レガシーデータ構造全体にわたるCOBOLのリファクタリング複数のプログラムやシステム間で共有されているデータ構造を、調整された切り替えなしに進化させるという課題は、エンタープライズ規模のリファクタリングにおける決定的な難しさの1つである。
拡張・収縮パターン
拡張・縮小パターンは、スキーマ変更に対する複数ステップのアプローチを体系化したものです。拡張フェーズでは、新しいスキーマ要素が段階的に追加されます。つまり、既存の列の横に新しい列、既存のテーブル、既存のインデックスの横に新しいインデックスが追加されます。アプリケーションは、古い構造と新しい構造の両方に書き込むように更新されますが、読み取りは引き続き古い構造から行います。データが失われることも、既存のクエリが壊れることもなく、古いスキーマ要素が残っているため、古いバージョンのアプリケーションも引き続き機能します。
新バージョンが完全にデプロイされ検証された後に行われる、別のデプロイメントにおける統合フェーズでは、古いスキーマ要素が削除されます。この時点では、実行中のアプリケーションバージョンはいずれも古いスキーマ要素に依存していません。削除は計画段階で想定するのではなく、観測によって検証されているため、安全です。
拡張・縮小パターンでは、デプロイメントの順序付けに関する厳格な管理が求められます。新しい列を追加するデータベース移行は、その列に書き込むアプリケーションバージョンよりも前にデプロイする必要があります。古い列を削除するデータベース移行は、その列から読み取るすべてのアプリケーションバージョンが廃止された後にデプロイする必要があります。これらの順序付け要件は、移行が順不同で適用されないように、デプロイメントパイプラインに組み込む必要があります。
コードを書き換えることなくレガシーデータパイプラインをリファクタリングするためのツール
従来のデータパイプライン、特にバッチ処理フレームワーク、ETLツール、またはメインフレームベースのデータ移動に基づいて構築されたものは、特有の課題を抱えています。これらのパイプラインはデータを継続的に変換および移動し、移行期間中は停止できず、多くの場合、ドキュメントが不十分なため、何らかの問題が発生するまでその全容が把握できないことがあります。これらのパイプラインを完全に書き直すことなくリファクタリングするには、パイプラインの現在の動作を監視し、リファクタリング後のバージョンが同等の出力を生成することを検証し、移行を段階的に進めることができるツールが必要です。
変更データキャプチャ(CDC)は、稼働中のパイプラインのリファクタリングにおいて最も汎用性の高いツールです。CDCは、ソーステーブルへのすべての書き込み操作をイベントストリームとしてキャプチャするため、古いパイプラインと新しい代替パイプラインの両方に、同じソースからデータを供給することが可能です。古いパイプラインは引き続き実行され、新しいパイプラインは同じイベントストリームに対して並行して実行され、出力が比較されます。不一致が見つかった場合、正しく再実装されていない変換ロジックが特定されます。一致が確認されると、古いパイプラインは廃止されます。
LiquibaseやFlywayなどのスキーマ移行ツールは、バージョン管理された順序付き移行を提供し、拡張/縮小規律と組み合わせることで段階的に適用したりロールバックしたりできます。これらのツールは、各環境に適用された移行を追跡し、順不同の適用を防ぎます。メインフレームまたはVSAMベースのデータストアで実行されるレガシーパイプラインの場合、同等の機能は以下によって管理されます。 JCLの拡張とデータセットの管理 これは、移行中にプログラムがデータにアクセスする方法を制御し、古いプログラムも新しいプログラムも互換性のないデータセットレイアウトに対して実行されないようにするものです。
ダウンタイムなしでレガシーデータベースを最新化する方法
レガシーデータベースの近代化、メインフレームのDB2スキーマからクラウドホスト環境のリレーショナルデータベースへの移行、ファイルベースのVSAM構造からリレーショナルスキーマへの移行、または複数のレガシーデータベースを新しい統合ストアに統合するといった具体的な課題には、上記すべての手法を長期間にわたって順次適用する必要があります。
一貫して有効なアプローチは、まず読み取りパリティを確保し、次に書き込みパリティを達成し、次に読み取りを移行し、次に書き込みを移行し、最後にレガシー ストアを廃止することです。読み取りパリティとは、新しいストアが古いストアに含まれるすべてのデータを含み、アプリケーションが行うすべてのクエリに対応できることを意味します。書き込みパリティとは、アプリケーションが古いストアに対して行うすべての書き込みが、アプリケーション内の二重書き込みまたは CDC レプリケーションによって新しいストアにも適用されることを意味します。両方のパリティ条件が本番負荷で確認されたら、読み取りを新しいストアに移行し(出力を検証)、次に書き込みを移行し、最後にレガシー ストアを廃止できます。
この一連の処理において、サービスが中断されることはありません。どの段階においても、読み取りまたは書き込みを前のストアに戻すことで、以前の状態を復元できます。各段階の所要時間は、固定された日付ではなく、検証によって得られる信頼度によって決定されます。
コードを書き換えずにレガシーシステムをリファクタリングするためのツール
既存システムをゼロから書き直すことは、段階的にリファクタリングするよりも、ほとんどの場合、コストとリスクが高くなります。全面的な書き直しでは、既存システムを運用しながら、同等の機能を持つ代替システムを構築し、両者の機能のギャップを管理し、実質的にダウンタイムゼロで全く異なるシステムを導入する切り替え作業を同時に行う必要があります。全面的な書き直しを試みるほとんどの組織は、途中で、既存システムに文書化されておらず、代替システムではまだ再現されていない、ユーザーが依存している動作が含まれていることに気づきます。
適切なツールを用いた段階的なリファクタリングは、変更前に古いシステムを読みやすくすることで、この落とし穴を回避します。出発点は構造分析です。既存システムの各コンポーネントが何をするのか、何に依存しているのか、そして何に依存しているのかを理解することです。この分析は、ドキュメントを読むこと(レガシーシステムでは通常存在しないか不正確です)や、大規模なコードを手動で読むことでは実行できません。既存のコードを解析し、依存関係グラフを構築し、そのグラフをクエリ可能にする自動化ツールが必要です。 レガシーシステム統合の課題管理レガシーシステムの再構築プログラムにおける最初のステップは、人間が管理する成果物には存在しない構造的な可視性を確立することです。
モノリスのための絞め殺しイチジク模様
絞め殺しイチジクパターンは、モノリスを全面的に書き換えたり、切り替えイベントを実施したりすることなく、段階的に置き換えるための主要なアーキテクチャ戦略です。新しい機能は、モノリスと並行して独立したサービスとして構築されます。ルーティング層(通常はAPIゲートウェイまたはリバースプロキシ)が受信リクエストを傍受し、ルーティングルールに基づいてモノリスまたは新しいサービスにルーティングします。モノリスは、まだ移行されていないすべてのトラフィックを引き続き処理します。新しいサービスは、明示的にルーティングされたトラフィックのみを処理します。
時間の経過とともに、ルーティングルールが追加され、新しいサービスへのパスが増えていきます。モノリスが処理するトラフィックは徐々に減少し、最終的には何も処理しなくなり、廃止することができます。このプロセスにおいて、単一のデプロイメントが重大なリスクとなるほど大規模になることはありません。各ルーティングルールの変更は個別にテスト可能であり、個別に元に戻すことができます。この手法は、迅速な変革のためのテクニックではなく、対象となるシステムの複雑さに応じて、数週間、数か月、あるいは数年かけて安全に変革を進めるためのテクニックです。
絞め殺しイチジクパターンの実装における重要な要件は、ルーティング層がモノリスと新しいサービスの両方から分離されていることです。モノリスに組み込まれたルーティング層では、モノリスからトラフィックをルーティングすることはできません。プロキシは両方の前に配置され、モノリスまたは新しいサービスを変更することなく変更可能な設定に基づいて、トラフィックをどちらにも振り分けることができる必要があります。
ダウンタイムなしでレガシーAPIをクラウドネイティブサービスにリファクタリングする
レガシーAPIをクラウドネイティブな代替APIに移行することは、絞め殺しイチジクパターンの具体的な応用例であり、以下の制約が加わります。レガシーAPIには、同時に更新できないコンシューマーが存在する可能性があり、移行全体を通してAPI契約を維持する必要があり、クラウドネイティブな代替APIは、コンシューマーに予期せぬ影響を与える可能性のある異なるパフォーマンス特性を持つ可能性があります。
標準的なアプローチは、従来のAPIと同じAPI契約の背後にクラウドネイティブな代替サービスをデプロイし、カナリア方式を用いてトラフィックの一部を代替サービスにルーティングし、そのトラフィック割合における出力の同等性を検証し、ルーティングする割合を段階的に増やしていくことです。API契約は維持されるため、この移行期間中に利用者は何も変更する必要はありません。ルーティング層が移行を透過的に処理します。
コア統合からミドルウェアAPIへのダウンタイムゼロの切り替えは、この記事の検索コンソールデータで高い意図のクエリとして表示されていますが、まさにこのシナリオです。ルーティングレイヤーが更新され、トラフィックの100%が新しいシステムにルーティングされ、従来のAPIが廃止される瞬間です。この切り替えは、決して単一のアトミックなイベントであってはなりません。これは、新しいシステムが徐々に高いトラフィック割合で検証された段階的なロールアウトの最終ステップであるべきです。最終的な切り替えが行われる頃には、新しいシステムは既にトラフィックの全量を処理できるようになっているため、切り替えによって不要になったフォールバックパスが削除されるだけです。
リファクタリングされたシステムにおける冪等性、リトライ、およびフェイルオーバー
イベント駆動型アーキテクチャ、メッセージキュー、または分散サービス呼び出しを使用するシステムをリファクタリングすると、純粋にデプロイメントに焦点を当てたパターンでは対処できない一連の問題が発生します。サービスが旧バージョンから新バージョンに移行する際に、進行中の操作はどうなるのでしょうか?旧バージョンで発行されたイベントは、新バージョンを実行しているハンドラに到達する可能性があります。旧APIに対して開始されたリクエストは、既に新しい内部構造にリファクタリングされたハンドラに到達する可能性があります。旧ロジックで部分的に完了したトランザクションは、新ロジックで完了させるか、補償する必要があるかもしれません。
これらの問題すべてに対する答えは冪等性です。冪等性とは、すべての操作を、一度実行しても複数回実行しても同じ結果になるように設計することです。デプロイメントの移行中に重複したイベントを受け取った冪等ハンドラは、イベントをちょうど一度受け取ったハンドラと同じ出力を生成します。ロールバックの一部として再生される冪等な書き込み操作は、元の書き込みと同じデータベース状態を生成します。冪等性はリファクタリングだけの問題ではなく、回復力のある分散システムの一般的な特性です。しかし、リファクタリングの移行中に冪等性が欠如すると、最も顕著な障害が発生します。
大規模なリファクタリングなしでリトライ機能とプロバイダフェイルオーバー機能を追加する
この記事のSearch Consoleデータで最もよく寄せられる質問の一つは、大規模なリファクタリングを行わずに、既存のアプリケーション、特にRailsなどのフレームワークアプリケーションにリトライ機能とフェイルオーバー機能を追加する方法です。その答えは、個々のサービス実装を変更することなく、インフラストラクチャ層で横断的な関心事としてリトライ機能とフェイルオーバー機能を追加できるということです。
インフラストラクチャ層では、IstioやLinkerdなどのサービスメッシュを構成して、失敗したリクエストを、定義された再試行回数まで自動的に再試行するように設定できます。この際、指数バックオフとジッターを適用することで、集中的なリクエストの急増を防ぎます。再試行動作は、すべての受信および送信リクエストをインターセプトするサイドカープロキシで実装されるため、アプリケーションコードの変更は不要です。プロバイダのフェイルオーバーも同様に実装できます。プライマリプロバイダがしきい値を超えるエラーを返した場合、プライマリプロバイダが復旧するまで、メッシュは後続のリクエストをセカンダリプロバイダにルーティングします。
アプリケーション層では、ビジネス状態を認識する必要があるためインフラストラクチャレベルのリトライでは不十分な場合、アプリケーションの内部構造を変更することなく、アプリケーションと外部依存関係の境界に軽量のリトライライブラリまたはジョブキューを導入できます。重要なのは、リトライおよびフェイルオーバーロジックをビジネスロジック層全体に分散させるのではなく、統合境界に分離することです。これにより、コアアプリケーション構造に手を加えることなく、リトライ動作を可視化、テスト、構成できるようになります。 アジャイルリファクタリング手法ビジネスロジックのリファクタリングを行う前にインフラストラクチャレベルの信頼性パターンを導入することで、変更ごとに検証する必要のある範囲を縮小できます。
Redis Streamsを用いたイベント駆動型アーキテクチャにおける冪等性
Redis Streamsや同様の技術を使用する低遅延イベント駆動型アーキテクチャでは、リファクタリング時に特定の冪等性の課題に直面します。コンシューマーグループが異なる速度でイベントを処理する可能性があり、新しいバージョンでイベントを読み取るコンシューマーは、古いバージョンでは処理されていないイベントを既に処理している可能性があり、再生またはリカバリ操作によって、重複を処理するように設計されていないハンドラーに同じイベントが複数回配信される可能性があります。
標準的なアプローチは、イベント公開時に各イベントに一意の識別子を割り当て、処理済みのイベント識別子を永続ストレージで追跡することです。イベントを処理する前に、ハンドラは識別子が既に処理されているかどうかを確認します。既に処理されている場合は、イベントは確認応答され、再処理せずに破棄されます。未処理の場合は、イベントが処理され、識別子が記録されます。この重複排除ロジックはアトミックである必要があります。ハンドラがイベントを処理しても、識別子を記録する前に失敗した場合、イベントは次の配信時に再処理されます。処理操作の一部として識別子を記録するために、Redisのアトミック操作またはトランザクション書き込みを使用することで、この競合状態を防ぐことができます。
コンシューマーロジックが変更されるリファクタリング移行中に、冪等性識別子は追加の利点を提供します。新しいコンシューマーロジックに対してイベントストリームを再生し、その出力を古いコンシューマーロジックの記録された出力と比較することが可能になり、ユーザーに新しいロジックを開示することなく比較テストを実行できます。
CI/CDパイプラインにおけるリファクタリングの自動化
ダウンタイムゼロのリファクタリングという規律は、手動プロセスでは維持できません。ダウンタイムゼロのプログラムでは、すべてのデプロイメントに一連の検証が必要です。具体的には、新しいバージョンが現在のデータベースの状態と互換性があることを確認するデプロイメント前のチェック、トラフィックが増加するたびにカナリアゲート評価を実施し、古いコードパスと新しいコードパスの出力を自動的に比較し、デプロイメント後に主要なメトリクスが劣化していないことを確認する検証を行います。これらの手順をすべての変更に対して手動で行うことは、運用上持続可能ではなく、プロセスの最も重要なポイントで人為的なミスを引き起こす可能性があります。
ダウンタイムゼロのリファクタリングのための CI/CD パイプラインは、単なるビルドとデプロイのパイプラインではありません。それは検証パイプラインです。変更が次のデプロイメント段階に進む前に、すべて通過しなければならない一連の自動化されたゲートです。各ゲートは、具体的で測定可能な基準です。ゲートに失敗すると、パイプラインが停止し、アラートがトリガーされます。すべてのゲートを通過すると、デプロイメントは自動的に次の段階に進みます。より広範な議論で説明されているように、 メインフレームおよびエンタープライズ環境におけるCI/CDの実践根本的な要件は、パイプラインが変更の規模に関係なく、すべての変更に対して同じデプロイメント規律を強制すること、そしてその強制が個々のエンジニアの注意力に依存するのではなく、自動化されていることです。
ライブリファクタリングのためのパイプラインステージゲート
ステージゲートとは、デプロイメントが次の段階に進む前に通過しなければならない検証チェックポイントのことです。ダウンタイムゼロのリファクタリングパイプラインの場合、最小限必要なゲートのセットは以下のとおりです。
デプロイ前:スキーマ互換性チェックにより、データベース移行がアプリケーションの現在のバージョンと下位互換性があることが確認され、自動化された契約テストにより、新バージョンのAPI応答が以前のバージョンの契約と互換性があることが検証され、静的依存関係分析により、新バージョンが導入する依存関係が既存環境が必要とする依存関係と競合しないことが確認されます。
カナリア環境へのデプロイ後:カナリア環境とベースライン環境のトラフィック間のエラー率の比較、p50、p95、p99におけるレイテンシの比較、変更されたコードパスが影響を与えるすべてのメトリックに関するビジネスメトリックの比較、およびトラフィックの割合を増やす前にカナリア環境が安定している必要がある最小観測期間。
完全デプロイ後:本番エンドポイントに対する回帰テストスイートの実行、二重書き込みまたは拡張/縮小移行が整合性を維持していることを確認するデータベース整合性チェック、および以前のデプロイ成果物がロールバックのために利用可能であることを確認する。
コンプライアンス主導のリファクタリングと強制
コンプライアンス主導のリファクタリングでは、パイプラインゲートが強制しなければならない新たな制約が生じます。それは、すべての変更が適用される規制要件または組織方針要件に明確に合致している必要があるということです。規制対象業界では、これは、デプロイメントパイプラインが、変更内容、デプロイ日時、実行された検証内容、および承認者を示す監査証跡を生成する必要があることを意味します。入力状態、ゲート基準、合否判定結果など、自身の実行状況を記録する自動化されたパイプラインゲートは、手動での文書化作業なしにこの監査証跡を提供します。
この記事の検索コンソールデータにクエリとして表示される、チーム全体での強制機能を備えたスマートなリファクタリングプラットフォームは、コンプライアンス検証をリファクタリングワークフローに統合するツールです。これにより、リファクタリングパターンがチーム全体で一貫して適用されていること、非推奨のインターフェースが再導入されていないこと、構造変更が組織レベルで定義されたアーキテクチャ標準に準拠していることが強制されます。これらの機能は、変更されるコードの意味を理解する必要があるため、ビルドやテストの合格といった単純な検証にとどまりません。
ダウンタイムなしのメインフレームおよびCICSのリファクタリング
メインフレーム環境は、制約が構成可能ではなく構造的なものであるため、ダウンタイムゼロのリファクタリングにおいて最も厳しい要件を課します。CICSトランザクションプログラムは、新しいコンテナイメージをデプロイしてロードバランサーを切り替えるだけでは置き換えることができません。CICSでプログラムを置き換えるには、NEWCOPYコマンドまたはPHASEINコマンドを使用して、プログラムの新しいバージョンをメモリにロードする必要があります。NEWCOPYコマンドは古いバージョンを即座に置き換え、コマンド実行後に開始されるすべてのトランザクションに影響します。PHASEINコマンドは、古いバージョンを使用している現在アクティブなすべてのトランザクションが完了するまで待ってから置き換えるため、長時間実行されるトランザクションの移行がよりスムーズになります。
どちらのメカニズムも即時ロールバックは提供しません。プログラムの新しいバージョンに欠陥がある場合、古いバージョンに戻すには、以前のロードモジュールを使用してNEWCOPYまたはPHASEINを再発行する必要があります。そのためには、以前のロードモジュールをロードライブラリに保持し、ロールバック手順を文書化し、リハーサルを行い、元の開発者の協力を得なくてもオンコールチームが実行できるようにしておく必要があります。
共有VSAMファイルは、さらに制約を加えます。複数のCICSトランザクションおよびバッチプログラムが、同じVSAMファイルに同時にアクセスする可能性があります。レコードセグメントの追加や拡張など、ファイルのレイアウトに構造的な変更を加える場合、ファイルにアクセスするすべてのプログラムをレイアウト変更前または変更と同時に更新するか、移行期間中にファイルが複数のレコード形式をサポートする必要があります。これは、メインフレームにおける拡張・縮小パターンに相当します。つまり、移行期間中は新しいレイアウトが古いプログラムと互換性を持つ必要があり、古いレイアウトが廃止される前に古いプログラムを更新する必要があります。データセットレイアウトとプログラムアクセスパラメータの制御された拡張は、ファイルの置き換えなしにこのような互換性のある共存を可能にするメカニズムです。
バッチウィンドウ除去戦略
従来のメインフレームのバッチ処理では、バッチウィンドウの存在が前提とされています。バッチウィンドウとは、オンライン取引処理が一時停止され、バッチジョブが競合なく実行され、結果データが次のオンライン処理期間に備える期間のことです。真のゼロダウンタイム運用に不可欠なバッチウィンドウをなくすには、バッチ処理モデルを再設計し、バッチジョブが共有データを破損することなくオンライン取引と並行して実行できるようにする必要があります。
標準的なアプローチとしては、ファイルレベルではなくレコードレベルでのリソースレベルロック、大規模なワークロードを定期的に処理するのではなく小規模なワークロードを継続的に処理するイベント駆動型ミニバッチ処理、そしてオンライン・トランザクション処理と書き込みアクセスを競合することなくバッチ・レポート・ワークロードを処理するリード・レプリカ・データベースなどが挙げられます。これらのアプローチはいずれもプログラムとデータアクセスパターンの両方に変更が必要ですが、いずれも移行中にバッチウィンドウを維持する必要はありません。移行自体は、他の稼働中のシステム・リファクタリングで使用されるのと同じデュアルラン検証アプローチを用いて段階的に実施できます。
影響分析を用いたCOBOLプログラムのリファクタリング
COBOLプログラムを安全にリファクタリングするには、変更を加える前に、どのプログラムがそのプログラムを呼び出しているか、どのコピーブックを他のプログラムと共有しているか、どのデータセットを読み書きしているか、どの下流システムがそのプログラムが生成するデータに依存しているかを正確に把握しておく必要があります。このような構造的な知識がなければ、プログラムへの変更には未知のリスクが伴います。リファクタリングされたプログラムによって、特定されていない呼び出し元が動作しなくなったり、下流システムが解析できない形式で出力が生成されたり、同じコピーブックを使用する他のプログラムに影響を与えるような方法で共有データ構造が変更されたりする可能性があります。
自動化された影響分析は、リファクタリングを開始する前に COBOL プログラムの完全な依存関係グラフを構築することでこの問題を解決します。グラフには、すべての呼び出し元、すべての共有コピーブック、すべてのデータセット アクセス、およびすべてのダウンストリーム コンシューマーが、関係タイプと特定の参照場所ごとに整理されて表示されます。リファクタリング プランは、影響グラフから導き出されます。変更されたプログラムを呼び出すプログラムは新しいバージョンに対してテストする必要があり、変更されたコピーブックは、それらを含むすべてのプログラムに対して検証する必要があり、変更されたデータセット レイアウトは、同じデータセットにアクセスするすべてのプログラムに対して検証する必要があります。 影響分析ソリューション IN-COMが提供するこの機能こそが、展開後にその影響を発見するリファクタリングプログラムと、展開前にその影響を定量化するリファクタリングプログラムとの違いを生み出すのです。
検証、ロールバック、および可観測性
ダウンタイムゼロのリファクタリングでは、継続的な出力が生成されるため、継続的に監視する必要があります。この監視は、事後的にすべてが正常に動作したかどうかを確認するものではなく、デプロイメントプロセスの各段階におけるアクティブなゲートであり、ユーザーへの影響を未然に防ぐために問題を早期に検出する主要なメカニズムです。
ダウンタイムゼロのリファクタリングにおける検証モデルは、3つのレイヤーで構成されています。1つ目は合成監視です。これは、ユーザーの行動をシミュレートし、本番環境で継続的に実行されるスクリプト化されたトランザクションであり、主要なフローが正常に完了することを検証します。合成監視は、トラフィックの少ない期間には実際のユーザーが実行しない可能性のある特定のコードパスで発生する障害を検出し、カナリアリリースの結果と比較するためのベースラインとなる行動を提供します。
第2層は差分監視です。これは、エラー率、レイテンシ分布、ビジネス指標、リソース消費量など、カナリア展開とベースライン展開のメトリクスをリアルタイムで比較するものです。差分監視では絶対的な閾値は必要なく、相対的な比較が必要です。ベースラインよりもエラー率が2%高いカナリア展開は、絶対的なエラー率が個別に定義された閾値を超えているかどうかに関わらず、問題となります。
3 層目はデータ整合性の検証です。二重書き込み、スキーマ移行、または並列システム実行を伴うリファクタリングでは、旧表現と新表現間のデータ整合性を継続的に検証する必要があります。チェックサム比較、レコード数比較、および特定のフィールド値を期待される変換と照合するスポットチェッククエリはすべて、移行中にデータ層が正しく動作しているという確信につながります。 インパクト分析とは何か、そしてなぜそれが重要なのか?構造化されたリファクタリングが投機的な変更と異なる点は、変更の結果を定義された一連の期待値と照らし合わせて検証できる能力にある。
即時ロールバックメカニズム
実行に30分かかるロールバック計画は、ダウンタイムゼロのシステムのためのロールバック計画とは言えません。完了するまでに、ユーザーにはすでに30分間のサービス低下が発生しているからです。即時ロールバックを実現するには、問題が発生した後に後付けするのではなく、最初からすべてのデプロイメントを可逆性を考慮して設計する必要があります。
アプリケーションのデプロイメントにおいて、即時ロールバックとは、以前のデプロイメント成果物を、事前に準備された状態で、同じデータベース状態を指すように保持しておくことを意味します。ロードバランサーによるトラフィック切り替え、またはAPIゲートウェイのルール変更のみで、以前のバージョンに戻すことができます。これは、データベースの状態が以前のバージョンと下位互換性がある場合に実現可能であり、データベース移行レイヤーにおける拡張・縮小の規律によって保証されます。
データベース移行において、即時ロールバックを実現するには、拡張フェーズで適用されたすべての移行がデータ損失なしで元に戻せる必要があります。拡張フェーズで追加された列は、ロールバック時に削除できます。破壊的な方法で変更された列は、バックアップなしでは復元できません。そのため、列を削除したり、互換性のない方法で型を変更したり、精度を低下させたりする破壊的なスキーマ変更は、新しいバージョンが完全にデプロイおよび検証され、古いバージョンが完全に廃止されるまで適用すべきではありません。
認定条件 SMART TS XL ダウンタイムゼロのリファクタリングプログラムをサポートします。
SMART TS XL このプラットフォームは、ダウンタイムゼロのリファクタリング失敗の根本原因である構造的可視性の問題に対処します。つまり、稼働中のシステムをリファクタリングしようとするチームが、システムの内容、依存関係、そして計画された変更がもたらす影響を完全に把握していないという問題です。このプラットフォームは、COBOL、JCL、Java、.NET、Python、JavaScript、SQLなど、環境内のあらゆる言語とプラットフォームのソースコードを取り込み、システム全体の構造的関係を表す統一された相互参照モデルを構築します。
リファクタリング変更を行う前に、 SMART TS XLの影響分析機能は、変更対象のコンポーネントから、呼び出し元、共有データ構造、下流のコンシューマー、および変更の影響を受けるすべてのプログラムに至るまで、依存関係グラフをたどります。その結果、リスクの一般的な評価ではなく、深刻度とコンポーネントごとに整理された、具体的な影響のリストが作成されます。このリストによって、ダウンタイムゼロのリファクタリングシーケンスを正しく計画することが可能になります。つまり、変更されたコンポーネントをデプロイする前にどのコンシューマーを更新する必要があるか、どのデータベース移行をどのアプリケーションデプロイの前に実行する必要があるか、古いバージョンを廃止する前にどの下流システムを検証する必要があるかを把握できるのです。
SMART TS XLのコード可視化機能により、リファクタリング対象システムの各レイヤーに精通していないチームでも、依存関係グラフを容易に把握できます。アーキテクトは、接続構造を再設計する前に、コンポーネントがどのように接続されているかを確認できます。開発者は、関数のシグネチャを変更する前に、どの関数が呼び出されているかを確認できます。運用チームは、データセットのレイアウトを変更する前に、データセットが何によって使用されているかを確認できます。このような可視性は、ダウンタイムゼロの運用に必要な、構造化され、可逆的で、段階的に管理されるリファクタリングプログラムの前提条件となります。
継続的な実践としてのダウンタイムゼロのリファクタリング
このガイドで紹介する手法は、一度限りの介入ではありません。これらは、本番システムを定期的に置き換えるのではなく、継続的に進化させるものとして扱うことを決定した開発組織の運用用語です。ブルーグリーンデプロイメント、カナリアリリース、フィーチャートグル、拡張・縮小移行、ストラングルフィグ抽出、冪等イベント処理、パイプラインによるデプロイメントゲートなどは、緊急時の手順ではなく、構造的な変更を安全に高頻度でリリースするチームの標準的な運用手順なのです。
その状態を実現するには、個々のリファクタリング活動にとどまらず、ツール、インフラストラクチャ、組織的な実践への投資が必要です。ツールは、独立したデプロイ、状態遷移の可視化、即時ロールバックをサポートする必要があります。インフラストラクチャは、トラフィック分割、ブルーグリーン環境、CDCベースのデータ同期をサポートする必要があります。組織的な実践には、デプロイ前の影響分析、デプロイ後の差分監視、そして現実的な条件下でロールバックパスが機能することを確認するための定期的なロールバックリハーサルを含める必要があります。
この投資を行う組織は、プラクティスが成熟するにつれて変更あたりのコストが減少することに気づきます。サポートインフラストラクチャが既に整備されているため、リファクタリングは毎回前回よりもリスクが低くなります。どの変更にどのゲートしきい値が適切かという判断力がチームに備わっており、次のようなツールに蓄積された構造的知識があります。 SMART TS XL これにより、計画された変更はそれぞれ、前の変更よりも範囲がより明確になります。ゼロダウンタイムリファクタリングの目標は、単一の変更を安全に行うことではありません。ユーザーにメンテナンス期間の受け入れを求めることなく、すべての変更を安全かつ継続的に行うことです。