Amazon Web Services ブログ
Heroku が 30 TB のセルフマネージドデータベースを EC2 から Amazon DynamoDB にマイグレーションし作業オーバーヘッドを削減した方法
Herokuは、開発者が AWS 上でアプリケーションをデプロイ、運用、スケーリングできるようにする完全にマネージドされたプラットフォームサービス( PaaS )ソリューションです。2007 年に設立され、2010 年からは Salesforceの一部となっています。Heroku は、小規模スタートアップから大企業の大規模デプロイメントまで、数百万件のアプリケーションで選ばれているプラットフォームです。これらのアプリケーションをスムーズに運営するには、AWS が提供するビルディングブロックを使って、プラットフォームの基盤となるインフラストラクチャに継続的な投資が必要不可欠です。
このブログ記事では、Heroku が 2023 年に完了した、アプリケーションメトリクスとアラート機能のストレージバックエンドを自社管理の Apache Cassandra クラスターから Amazon DynamoDB に移行するインフラアップグレードについて説明します。 Heroku は、この移行を顧客への影響なしに完了することができました。Amazon DynamoDB への移行により、プラットフォームの信頼性が向上すると同時に、運用コストも削減されました。本記事では、システムアーキテクチャ、DynamoDB へ移行した理由、移行の実施方法、そして移行完了後の成果について詳しく説明します。
(本記事は 2024/05/09 に投稿されたHow Heroku reduced their operational overhead by migrating their 30 TB self-managed database from Amazon EC2 to Amazon DynamoDBを翻訳した記事です。)
サービスとしてのメトリクス( MetaaS )
Heroku のアプリケーションメトリクスは、内部のサービスである MetaaS( Metrics as a Service )によって提供されています。MetaaS は、Heroku で稼働しているアプリケーションから様々な観測値を収集します。例えば、特定の HTTP リクエストを処理するのにかかる時間などです。集計された生データに対し、アプリケーション単位、分単位の統計値(中央値、最大値、99 % 応答時間など)が計算されます。この時系列メトリクスデータは、Heroku ダッシュボードに表示されたり、アラートやオートスケーリングの機能に活用されます。
MetaaS の中核は、高スケールでマルチテナントな時系列データ処理プラットフォームです。毎秒数十万件の観測値が最初に Heroku 上の Apache Kafkaに取り込まれます。ストリーム処理ジョブのコレクションが Kafka からこれらの観測値を消費し、Heroku が各顧客アプリケーションについて追跡しているさまざまなメトリクスを計算します。そして、最終的には長期保存とクエリのためデータベース(元々は Amazon EC2 上の Apache Cassandra )に書き込みます。MetaaS の時系列データベースには数 TB ものデータが保存されており、ピーク時には毎秒数万件の新しいデータポイントが作成され、最大秒間に数千件のリードクエリが行われます。
下記の図は従来のアーキテクチャを示しています。
DynamoDB を選択した理由
Cassandra によって構成された MetaaS は、長年 Heroku に良いサービスを提供してきました。しかし 2022 年末頃、Heroku のエンジニアチームはバックエンドストレージを構成する他の方法を探り始めました。MetaaS が使用している Kafka クラスターは、Kafka 運用の経験が豊富なチームによって提供されていますが、Cassandra クラスターは MetaaS 固有のものでした。
Heroku は、データベースインフラを監視するエンジニアチームは非常に小さいため、Kafka クラスターと同様に専門家チームが運用・保守するマネージドサービスに移行することが重要だと考えていました。そこで、大量のデータを高スケールで分散システムに格納しつつ、あらゆるスケールでの高速な書き込みパフォーマンスを維持できる AWS のマネージドデータベースを探しました。結果的に、Heroku の他のチームがデータストレージおよび処理に使用している DynamoDB が、一貫性とパフォーマンスの要件に合っていたため、MetaaS のワークロードにも適していると判断されました。
慎重なマイグレーション
計画を立て、コードを書き換えた後、既存の顧客に影響を与えずに、高スケールで高スループットの分散システムのバックエンドストレージを入れ替えるという作業が残されていました。既存 MetaaS アーキテクチャは Heroku の移行に有利でした。Kafka から時系列データを Cassandra に書き込むためのストリーム処理ジョブがすでに用意されていたので、同じデータを DynamoDB に書き込むための並行したジョブを立ち上げるのが簡単でした。これが移行の最初のステップで、システムの他の部分には何の影響もありませんでした。
Heroku の顧客にとって運用メトリクスは非常に重要です。DynamoDB へのデータ書き込みが正常に行われていることを確認するため、チームは従来の単体テストや統合テストに加えて、既存単体テスト及び統合テストを規範としたテストを実施しました。まずは Cassandra と DynamoDB の両方からデータを読み出すクエリを少量実行し、データの整合性を確認しました。2 つのコードパスで結果が異なるクエリはすべてログに記録されました。プリプロダクションでのテスト後、徐々にクエリの割合を増やし、最終的には 100 % のクエリが両方のコードパスを経由するようになりました。この変更によって、お客様は Cassandra のコードパスでクエリ結果をもらい、あまり影響がありませんでしたが、従来の単体テストや統合テストでは見つからなかった微妙なエッジケースを特定し修正することができました。
スムーズな移行
DynamoDB が Cassandra と同じ結果を一貫して返していることを検証実験で確認できたため、本番稼働の準備が整いました。MetaaS はデータを 30 日以内しか保持しておらず、それ以降は削除されます( DynamoDB では便利な TTL 機能を使用)。つまり、Cassandra から過去のデータを移行する必要がありませんでした。両方のデータベースに同じデータが書き込まれていることを確認した後は、2 つのデータベースが同期されるのを待つだけでよかったのです。
テスト環境から始め、徐々に DynamoDB からのみ読み出すクエリに切り替えていきました。見落とされていた可能性のある問題のある動作に関する顧客からの報告がないかを慎重に確認しながら進めました。そのような報告はなく、2023 年 5 月以降、MetaaS へのすべてのクエリが DynamoDB から提供されるようになりました。Heroku は、変更を戻す必要がないことを確認するため、数週間待ちました。
以下の図は、更新されたアーキテクチャを示しています。
結果
1 年以上の運用経験を経て、Heroku はマネージドデータベースサービスの採用を正しい判断であったと確信しました。DynamoDB は信頼性と拡張性に優れています。Heroku は、データベースサーバーのパッチ適用とチューニングに必要な運用負荷を 90% 削減し、当初の目標を達成できました。また、DynamoDB はこれまでの Amazon EC2 上の自社運用 Cassandra クラスターよりも高速かつ低コストであることがわかりました。具体的には、クエリの最大レイテンシーを 75% 削減し、コストを約 50% 削減できました。
例えば、以下のグラフに示されているように、18 時までは Cassandra をクエリしていたため、p99 レイテンシーにかなりの変動が見られましたが、18 時以降は DynamoDB をクエリしているため、そのような変動は見られなくなりました。
教訓
Heroku のサービスは VPC エンドポイントを通じて DynamoDB にアクセスしています。AWS Identity and Access Management ( IAM )ポリシーを設定し、DynamoDB へのトラフィックが VPC エンドポイントを経由するよう要求することで、VPC 内のアプリケーションがインターネットに露出することなく DynamoDB にアクセスできるようになっています。
Heroku は、Heroku ダッシュボードで顧客がメトリクスを見る頻度によってトラフィックが週の中で変動するため、DynamoDB Auto Scaling を使って MetaaS テーブルのプロビジョンド読み取りキャパシティを管理しています。一方、書き込みパターンはより予測可能なため、自動スケーリングの最大利用率目標の 90 % を上回るようにテーブルの書き込みキャパシティを手動で設定しています。 ピークがある場合は自動スケーリングが費用削減に効果的ですが、予測可能なワークロードの場合は必要なキャパシティを正確に設定することで、コストを節約できます。
DynamoDB への書き込みは常に最低 1 つの書き込みキャパシティユニット( WCU )を消費しますが、書き込むレコードのサイズに応じて、それ以上の WCU を消費する可能性があります( 1 KB 当たり 1 WCU、最大 400 KB まで)。MetaaS が保存するレコードのほとんどは非常に小さいものの、わずかに 400 KB 制限を超えるものがあることがわかりました。Heroku は、これらの大きなレコードを DynamoDB に書き込む前に gzip で圧縮することで、この問題を解決(また、コストも節約)できました。MetaaS データはそれほど頻繁には照会されないため、圧縮と解凍の CPU 時間コストは、WCU の削減と柔軟なスキーマ変更の利便性に比べて無視できます。
最後に、テスト初期の段階で、DynamoDB への書き込みに予期せぬパフォーマンスボトルネックが発生していました。原因は、DynamoDB SDK で使用されている HTTP クライアントの設定不足でした。高スケールのワークロードの場合、デフォルト設定ではなく、チューニングを行うことが重要です。Heroku は、DynamoDB への同時接続数を増やし、再利用のために維持するアイドル接続数を調整し、デフォルトよりも積極的なタイムアウトとリトライ設定を行うことで、大幅な改善を達成しました。
まとめ
このブログ記事では、Heroku がセルフマネージドの Cassandra クラスターから DynamoDB へのインフラストラクチャ移行させた方法について説明しました。Heroku はこの移行を顧客への影響なしに完了し、プラットフォームの信頼性を向上させると同時にコストを削減できました。Heroku は、 EC2 上のセルフマネージド Cassandra から DynamoDB に移行したことで、クラウドインフラストラクチャコストを最大 50 % 削減しました。また、パフォーマンスの改善は、DynamoDB のクエリパフォーマンスがはるかに予測可能になったためです。Cassandra では、ピーク時にレイテンシースパイクが最大約 80 ms に達していましたが、DynamoDB では一貫して 20 ms 未満でクエリが実行されるようになり、顧客へのメトリクス提供遅延が大幅に改善されました。
DynamoDB を使ったハイスケールなワークロードの運用について、他にもヒントや質問はありますか? コメントでお知らせください。DynamoDB の使用を始めるには、開発者ガイドとAWS DynamoDB コンソールをご覧ください。
このブログ記事は、Heroku と AWS の共同作成で、Herokuブログともにクロスポストされています。
元作者情報
Rielah De JesusはAmazon Web Service のプリンシパルソリューションアーキテクトであり、ワシントンDC、メリーランド、バージニアの多くのエンタープライズ級のお客様のクラウド移行を支援し、成功させてきました。現在のロールではカスタマーアドボケイトおよびテクニカルアドバイザーとして、Salesforceを始めとする複数の組織のAWSプラットフォームでの成功の支援をしています。また、Women in ITの熱心な支持者でもあり、テクノロジーとデータを創造的に活用して日常的な課題を解決する方法を見つけることに情熱を注いでいます。
David Murrayは、Salesforceのソフトウェアアーキテクトで、現在Herokulのバックエンド全般を担当しています。過去には、ネットワーク、データベース、セキュリティ、テクニカルライティングなどの分野を経験してきたほか、愛猫Sammyについてaws reinventで講演を行いました。コンピューターのことを考えていないときは、ボートこぎ、自転車乗り、ボードゲームなどを楽しんでいます。