発明のための再発明

Webプログラマーが、プログラムの内部動作を通してプログラムを作る時の参考になるような情報を書くブログ(サーバーサイドやDevOpsメイン)

稼働システムのマイグレーションの痛みを和らげる技法

はじめに

サービスを長く継続すると避けられないのが「マイグレーション」です。
しかし、マイグレーションには多くの手間がかかる上に致命的なバグも出やすく、難しい作業です。
そんなマイグレーションを実践し、詳細を公開している企業があります。
それを参考にどのような工夫ができるのかを見ていきます。

紹介するのは以下の企業です。

各事例には元記事へのリンクを書いているので、興味があればリンク先も覗いてみてください。

食べログ: Railsからマイクロサービスへの移行

元スライド: 食べログのマイクロサービス化PJについて

まずは、食べログのマイクロサービス移行についてです。
移行に際しては、共有しているDBをいきなり物理的に分けるのではなく、はじめに論理的に分割する方法を取ったようです。

※ 2018年9月末時点で進行中なので、現在も進行していると思われます。

移行理由

既存のシステムでは、

  • メインのデータベースが一つ
  • modelやlibをアプリケーション間で共有している
  • デプロイは全アプリケーション同時に行う

というアーキテクチャをもっているため、共有されたデータ構造を変更する際に影響範囲が広く対応が大変だそうです。
そのため、マイクロサービスへと移行し始めたそうです。

移行方法

移行の手順をまとめると、

  • 始めからサービスを細かく分解することを諦める
  • まずは境界が明確な2つのサービス(下図)へと分割し、境界の横断にはAPIを使うように修正する
  • 全サービスがAPIを使用するようにできたら、DBを分割する(予定)

このように、DBの共有を止めたいけれど、ビッグバンリリースでは大変なので、まずは、ソースコードの修正によって論理的にDBを分割します。
その後に、物理的にDBを分けるという戦略です。

The Guardian: MongoDBからPostgreSQLへの移行

元記事: Bye bye Mongo, Hello Postgres

次は、イギリスの新聞社である「The Guardian」がMongoDBを捨てて、PostgreSQLへ移行した方法についてです。
旧コードを本格稼働させつつ新コードにも同内容を実行することで、新旧コードが同じ結果になることを確かめながら移行したようです。

移行理由

The Guardianには記事の管理に使用している内製CMSツールがあり、MongoDBとマネジメントツールであるOpsManagerを使用していたのですが、

  • AWS上に自分たちでMongoDBとOpsManagerを建てて、管理する必要がある (マネージドサービスが使えなかった)
  • 障害時にMongoDBもOpsManagerも助けにならなかった
  • OpsManagerを入れれば管理が楽になると思ったが、そうでもなかった
  • 価格が高い

という要因が合わさり、移行先を探し始めてPostgreSQLへ決めたそうです。
ちなみに、移行時にスキーマを作り直すことはせず、JSONB型の列を用意してMongoDBの内容をそのまま持っていったようです。

移行方法

移行は下の手順で行ったそうです。

  1. 新DB(PostgreSQL)への書き込みAPIを用意する
  2. 前段にプロキシを用意して、新旧両方のAPIに同一のリクエストが流れるようにする(プライマリは旧API)
  3. 新DBへデータを移行
  4. 新旧APIのレスポンスが同一であることをチェック (別の結果が返ってきたら、新DBのデータを巻き戻してやり直し)
  5. APIをプライマリにする
  6. 旧DB(MongoDB)を削除

f:id:mrasu:20190115011442p:plain

プロキシを用意して変更の有無を確認することで、ユーザーに影響を与えずに新APIのエラー検出が出来るようになっています。
また、APIはelasticsearchなどとも連携しているので、APIが間違ったデータを返してしまうと影響が大きかったことからも、慎重に確認したかったようです。

Dropbox: 複数RPCからgRPCへの統合

元記事: Courier: Dropbox migration to gRPC

最後は、Dropboxが行ったRPCの統合についてです。
かつてDropboxは自作プロトコルでのRPCや、ApacheThrift、http1.1でのRPCを使用していたのを、CourierというgRPCを使うための新フレームワークへ移行したそうです。

移行理由

旧RPCフレームワークに変わり、Courierという新フレームワークを作成することで以下のことを可能にしたそうです。

  • サーバー・クライアントを認証・認可するためのDropbox内部にある機構との統合
  • ログや統計などの情報の統合・可視化
  • タイムアウト・サーキットブレーカー設定の強制

移行方法

移行に際しては、旧フレームワークからの移行を開発者が簡単に出来るように注意しつつ、以下のステップを踏んだそうです。

  1. 旧RPCフレームワークのコードのフリーズ
  2. Courierと旧フレームワーク双方を使用できる共通インターフェースの作成
  3. 共通インターフェースを使用するようにコードを変更 (稼働させるのは旧RPC)
  4. 旧RPCサーバーとCourierサーバーを同時稼働
  5. クライアントをCourierへ切り替え
  6. 旧コードの削除

フレームワークへの機能追加を止めることで開発者たちへ移行のインセンティブを与えたことと、新旧フレームワークを同時に使えるようにして順次切り替えを行い「移行」に対するリスクを抑えたという、工夫が見れます。

まとめ

以上、各企業がマイグレーションをした方法とその理由を掲載している記事を紹介しました。

このブログでは、この記事のようにプログラムを作る時の参考になることを書き続けるつもりです。
もし興味があれば、twitterやブログのフォローしていただけると嬉しいです。