Google Cloud Pub/Sub: Google 規模のメッセージ サービス

概要

Google Cloud Pub/Sub は、信頼性とスケーラビリティに優れた非同期メッセージ サービスです。このサービスは、さまざまな Google サービスが 10 年以上にわたって基盤としてきた中核的な Google インフラストラクチャ コンポーネントをベースにしています。現在、Ads や検索、Gmail などの Google サービスは、Pub/Sub を使用して、1 秒あたり 1 億件以上のメッセージ、総計 300 GB/秒以上のデータを送信しています。ここでは、Google Cloud Pub/Sub がこの水準の規模の信頼性を実現するために備えている設計上の主な特長について説明します。

パブリッシュ / サブスクライブ サービスの基本

Google Cloud Pub/Sub は、パブリッシュ / サブスクライブ(Pub/Sub)サービスの一種です。Pub/Sub サービスとは、メッセージの送信者とメッセージの受信者を切り離す方式のメッセージング サービスのことを指します。Pub/Sub サービスの主要な基本概念は次のとおりです。

  • メッセージ: サービスを通って移動するデータ。

  • トピック: メッセージのフィードを示す名前付きエンティティ。

  • サブスクリプション: 特定のトピックに関するメッセージの受信に関心があることを示す名前付きエンティティ。

  • パブリッシャー(プロデューサー): 特定のトピックに関するメッセージを作成してメッセージ サービスに送信(パブリッシュ)します。

  • サブスクライバー(コンシューマー): 指定したサブスクリプションに関するメッセージを受信します。

Google Cloud Pub/Sub を通るメッセージの基本的なフローを次の図に示します。

このシナリオでは、1 つのトピックに関して 2 つのパブリッシャーがメッセージをパブリッシュしています。このトピックに対して 2 つのサブスクリプションがあり、1 つ目のサブスクリプションは 2 つのサブスクライバーがあり、2 つ目のサブスクリプションには 1 つのサブスクライバーがあります。太字はメッセージを示しています。メッセージ A は、パブリッシャー 1 からパブリッシュされた後、サブスクリプション 1 を経由してサブスクライバー 2 に送信され、サブスクリプション 2 を経由してサブスクライバー 3 に送信されます。メッセージ B は、パブリッシャー 2 からパブリッシュされた後、サブスクリプション 1 を経由してサブスクライバー 1 に送信され、サブスクリプション 2 を経由してサブスクライバー 3 に送信されます。

メッセージ サービスのパフォーマンスを判断する

Google Cloud Pub/Sub のようなメッセージ サービスでは、スケーラビリティ、可用性、レイテンシという 3 つの要素がパフォーマンスの判断基準となります。この 3 要素は互いに相いれないことが多く、2 つの要素を高めるために 1 つの要素を犠牲にしなければならないことがあります。

「スケーラビリティ」、「可用性」、「レイテンシ」という用語は、定義によってさまざまなシステム プロパティを指し示すことがあるため、以下のセクションで、各要素が Google Cloud Pub/Sub においてどのように定義されるのかについて説明します。

スケーラビリティ

スケーラブルなサービスは、レイテンシや可用性を大幅に損なうことなく、負荷の増大に対処できます。ここで言う「負荷」とは、次のような Google Cloud Pub/Sub の利用状況に関するさまざまな要素のことを指します。

  • トピックの数

  • パブリッシャーの数

  • サブスクリプションの数

  • サブスクライバーの数

  • メッセージの数

  • メッセージのサイズ

  • メッセージのパブリッシュ レートやコンシューム レート(スループット)

  • 指定したサブスクリプションのバックログのサイズ

可用性

分散システムでは、発生し得る問題の種類や深刻度に大きな幅があります。システムの可用性は、さまざまな種類の問題に対してどれくらい適切に対処できるか、エンドユーザーに気づかれないように適切にフェイルオーバーできるか、という観点で測定されます。障害は、ハードウェアで発生する場合もあり(ディスク ドライブの不調ネットワーク接続の問題など)、ソフトウェアで発生する場合もあり、負荷に起因して発生する場合もあります。負荷に起因する障害は、たとえば、サービス内(あるいは、同一ハードウェア上で動作しているソフトウェア コンポーネント内や、ソフトウェアの依存関係内)でトラフィックが突然増加し、リソースが足りなくなったときなどに発生します。また、人的エラーによって可用性が低下することもあります(ソフトウェアや設定のビルド時、デプロイ時のミスなど)。

レイテンシ

レイテンシは、時間の面からシステムのパフォーマンスを測る尺度です。一般的に、サービスでは可能な限りレイテンシを最小限に抑えることが望まれます。Google Cloud Pub/Sub の場合、最も重要なレイテンシ指標は次の 2 つです。

  1. パブリッシュされたメッセージの確認応答を返信するまでにかかる時間。

  2. パブリッシュされたメッセージをサブスクライバーに配信するまでにかかる時間。

Google Cloud Pub/Sub の基本アーキテクチャ

このセクションでは、Google Cloud Pub/Sub の設計について説明し、このサービスがいかにして可用性を維持しつつ、スケーラビリティと低レイテンシを実現しているのかを説明します。このサービスは、水平スケーリングに対応するよう設計されており、トピックの数やサブスクリプションの数、メッセージの数が増加したときには、稼働サーバーのインスタンスの数を増やすことで対処できるようになっています。

Google Cloud Pub/Sub のサーバーは、世界中に分散された複数の Google データセンター内で稼働しています。各データセンターには、1 つのクラスタのインスタンスが 1 つまたは複数含まれています。クラスタとは通常、1 つの障害ドメイン(共有ローカル ネットワークや共有電源)を共有するマシンの論理グループのことを指します。Google Cloud Pub/Sub は、グローバル サービスです。クライアントはサーバーやデータの物理的位置(データセンターのある場所)を認識せず、世界のどこからでも、世界のどこに対してでも、パブリッシュやサブスクライブを行うことができます。

Google Cloud Pub/Sub は、データプレーンとコントロール プレーンという 2 つの主要部分に分割されます。データプレーンは、パブリッシャーとサブスクライバーの間で移動するメッセージを処理します。コントロール プレーンは、データプレーン上のサーバーに対するパブリッシャーとサブスクライバーの割り当てを処理します。データプレーン内のサーバーは、「フォワーダー」と呼ばれ、コントロール プレーン内のサーバーは、「ルーター」と呼ばれます。パブリッシャーとサブスクライバーが、割り当てられたフォワーダーに接続すると、フォワーダーにアクセス可能な限り、ルーターからの情報は一切不要になります。そのため、すでに接続済みでメッセージの送信や受信を行っているクライアントに影響を与えることなく、Google Cloud Pub/Sub のコントロール プレーンをアップグレードできます。

コントロール プレーン

Google Cloud Pub/Sub コントロール プレーンは、すべてのクライアントを対象としてスケーラビリティ、可用性、低レイテンシを実現するように、クライアントをフォワーダーに分配します。フォワーダーは、クライアントにトピックやサブスクリプションのサービスを提供します。クライアントが Google Cloud Pub/Sub に接続すると、ルーターが、ネットワーク距離を最短にするようにクライアントの接続先データセンターを決定します。ネットワーク距離とは、2 点間の接続に関するレイテンシの尺度のことを指します。ルーターは、データセンター内で利用できるすべてのフォワーダーを横断して全体の負荷を分散するように試みます。この割り当てを行う際、ルーターは、(a)負荷の均一性(各フォワーダーの負荷が均一になるのが理想)、(b)割り当ての安定性(負荷や利用可能なフォワーダーに変動があっても、できる限り既存の割り当てを変更しないようにするのが理想)という 2 つの目標の間でバランスを取る必要があります。ルーターは、Google Research によって開発されたコンシステント ハッシュ法のバリエーションを使用して、整合性と均一性の間に調整可能なバランスを実現します。ルーターは、クライアントに対して、接続先として可能性のあるフォワーダーの順序付きリストを提供します。この順序付きリストは、利用できるフォワーダーの状況やクライアントからの負荷の状態に応じて変化する場合があります。

クライアントは、このフォワーダー リストを受け取り、1 つまたは複数のフォワーダーに接続します。クライアントは、ルーターが提示した順序に基づいてフォワーダーに接続しようとしますが、障害が発生した場合は、その点を考慮に入れます。たとえば、最も近いフォワーダーに接続しようとして何度か失敗した場合、別のデータセンター内にあるフォワーダーを試すことがあります。Google Cloud Pub/Sub クライアントをこのような細かい実装処理から切り離すため、クライアントとフォワーダーの間にサービス プロキシがあり、クライアントに代わって、この接続の最適化を実行します。

データプレーン - メッセージの一生

データプレーンは、クライアントからメッセージを受け取り、クライアントにメッセージを送信します。Google Cloud Pub/Sub のデータプレーンを理解する方法としては、サービスがメッセージを受け取った瞬間から、メッセージがサービス内でもう存在しなくなる瞬間までの、メッセージの「一生」を知るのがおそらく最適です。メッセージ処理のステップについて順を追って理解しましょう。このセクションの説明上、メッセージをパブリッシュするトピックには、少なくとも 1 つのサブスクリプションが属するものとします。一般的に、メッセージは次のステップを通ります。

  1. パブリッシャーがメッセージを送信します。

  2. メッセージがストレージに書き込まれます。

  3. Google Cloud Pub/Sub が、メッセージを受信したことを示す確認応答をパブリッシャーに返信し、トピックに属するすべてのサブスクリプションに配信することを保証します。

  4. メッセージをストレージに書き込むと同時に、Google Cloud Pub/Sub は、サブスクライバーにメッセージを配信します。

  5. サブスクライバーは、メッセージを処理したことを示す確認応答を Google Cloud Pub/Sub に返信します。

  6. 各サブスクリプションの少なくとも 1 つのサブスクライバーがメッセージ受信の確認応答を返信すると、Google Cloud Pub/Sub は、ストレージからメッセージを削除します。

まず、パブリッシャーがトピックに関するメッセージを Google Cloud Pub/Sub に送信します。メッセージは、プロキシレイヤによって暗号化され、パブリッシング フォワーダー(パブリッシャーが接続しているフォワーダー)に送信されます。確実に配信するため、メッセージはすぐにストレージに書き込まれます。フォワーダーは、最初にメッセージを N 個のクラスタ(N は奇数)に書き込みます。少なくとも ⌈N÷2⌉ 個のクラスタに書き込まれたときに、メッセージが永続したものとみなされます。メッセージが永続すると、パブリッシング フォワーダーは、メッセージ受信の確認応答をパブリッシャーに返信します。この段階で、Google Cloud Pub/Sub は、トピックに属するすべてのサブスクリプションにメッセージを配信することを保証します。バックグラウンド プロセスが N 個のクラスタすべてにメッセージがあるか定期的に確認し、メッセージのないクラスタがあった場合、そのクラスタにメッセージを書き込みます。

各クラスタ内で、M 個のディスク(M は奇数)にメッセージが書き込まれます。データが ⌈M÷2⌉ 個のディスクに書き込まれたときに、そのクラスタ内で永続したものとみなされます。総計で、パブリッシュされたメッセージは、少なくとも ⌈N÷2⌉ 個のクラスタの ⌈M÷2⌉ 個のディスクに書き込まれたときに永続したものとみなされ、最終的に N×M 個のディスクにレプリケーションされます。

パブリッシング フォワーダーは、トピックに属するすべてのサブスクリプションのリストを持っています。パブリッシング フォワーダーは、パブリッシュされたメッセージと、各サブスクリプションによってどのメッセージの確認応答が返信されたのかを説明するメタデータの両方を永続させる責任を持ちます。特定のトピックを対象にパブリッシング フォワーダーによって受信と保存が行われたメッセージ セットは、この確認応答済みメッセージのトラッキング情報と合わせて、「パブリッシュ メッセージ ソース」と呼ばれます。トピックのスループット要件によっては、単一のパブリッシャーが複数のパブリッシング フォワーダーにメッセージを送信し、複数のパブリッシュ メッセージ ソースにメッセージを保存することがあります。また、同一トピックを対象に、複数のパブリッシャーがそれぞれ異なるパブリッシング フォワーダーにメッセージを送信する場合もあります。Google Cloud Pub/Sub は、特定のトピックのメッセージを受信するパブリッシング フォワーダーの数を、スループットの変化に応じて動的に調整します。

サブスクライバーは、サブスクライビング フォワーダー(パブリッシャーからサブスクライバーまでメッセージが移動する際に通過するフォワーダー)に接続することで、メッセージを受信します。pull サブスクライバーの場合の「接続」とは、pull リクエストを発行することを意味します。push サブスクライバーの場合の「接続」とは、push エンドポイントを Google Cloud Pub/Sub に登録することを意味します。サブスクリプションが作成されると、そのポイント以降にパブリッシュされたすべてのメッセージがそのサブスクリプションに配信されることが保証されます。この仕組みは、同期ポイント保証と呼ばれます。

各サブスクライビング フォワーダーは、対象トピックのパブリッシュ メッセージ ソースを持っているパブリッシング フォワーダーのメッセージをリクエストする必要があります。パブリッシャーと同様、サブスクライバーも、複数のサブスクライビング フォワーダーに接続してメッセージを受信することがあります。このようにすることで、必ずしもすべてのサブスクライビング フォワーダーが各パブリッシュ メッセージ ソースのメッセージを認識したり、受信したりする必要がなくなります。これは、Google Cloud Pub/Sub が水平スケーリングを行うための重要な特性です。サブスクライバーに配信されるメッセージのスループットに基づいて、Google Cloud Pub/Sub は、特定のトピックのメッセージをサブスクライバーが受信するためのサブスクライビング フォワーダーの数を、スループットの変化に応じて動的に調整します。

サブスクライビング フォワーダーは、対象トピックのパブリッシュ メッセージ ソースを持っている 1 つまたは複数のパブリッシング フォワーダーに対して、必要なメッセージを送信するようにリクエストします。パブリッシング フォワーダーは、確認応答済みではないメッセージをサブスクライビング フォワーダーに送信します。サブスクライビング フォワーダーは、そのメッセージをサブスクライバーにリレーします。

サブスクライバーは、メッセージを処理すると、サブスクライビング フォワーダーに確認応答を返信します。サブスクライビング フォワーダーは、この確認応答をパブリッシング フォワーダーにリレーします。パブリッシング フォワーダーは、確認応答をパブリッシュ メッセージ ソースに保存します。対象トピックのすべてのサブスクリプションがメッセージ受信の確認応答を返信すると、そのメッセージはパブリッシュ メッセージ ソースとストレージから非同期的に削除されます。

パブリッシャーからサブスクライバーにメッセージを送信する際にさまざまな接続が関係するため、メッセージの一生は複雑なものとなります。パブリッシャー、サブスクライバー、フォワーダーの間のさまざまな接続を通るメッセージのフローは次のようになります。

Google Cloud Pub/Sub を継続稼働させる

Google Cloud Pub/Sub のような分散システムが継続的に稼働し、すべてのお客様に対して効果的にサービスを提供するには、システムの包括的な可視化と制御が必要となります。サービスのメンテナンスは、Google のサイト信頼性エンジニア(SRE)が責任を持ちます。Google Cloud Pub/Sub 担当の SRE は、世界中のさまざまな拠点において 24 時間年中無休でサポートを提供しています。

環境

Google Cloud Pub/Sub のようなシステムのメンテナンスでは、まず、お客様が使用する前にソフトウェアをテストできることが重要です。そのため、Google Cloud Pub/Sub では、テスト環境、ステージング環境、本番環境という 3 つの環境が用意されています。テスト環境やステージング環境には、お客様のトラフィックは一切含まれません。Google が用意した継続稼働テストとモニタリングだけが含まれており、リリース時に問題を発見できるようになっています。テスト環境とステージング環境では、本番稼働の前にソフトウェアの新規リリースを適用できます。テスト環境とステージング環境の違いは、ステージング環境が、ソフトウェア バージョンやコマンドライン フラグを含めて、現在またはごく近い将来の本番環境の正確なレプリカだという点です。テスト環境は、その時点でデベロッパーの作業対象となっている機能や将来リリース予定の機能などが有効になっています。

ロールアウト

Google Cloud Pub/Sub のロールアウトとテストの手順は、発生し得る影響を最小限に抑えるように設計されています。新バージョンの Google Cloud Pub/Sub をロールアウトする際の標準的な手順は次のとおりです。

  1. すべてのユニットテストと統合テストに合格したことを確認します。

  2. すべてのサーバーの新バージョンをビルドします。

  3. テスト環境とステージング環境に新サーバーをデプロイします。

  4. テスト環境とステージング環境でサーバーを数日間稼働します。

  5. 既知の問題が発生しなかった場合、サーバーをカナリアにリリースします。カナリアとは、お客様のトラフィックを少量備えた本番環境のサブセットのことを指します。

  6. カナリアで問題が検知されなかった場合、徐々に範囲を広げながら数日間かけてサーバーを本番環境にロールアウトしていき、最終的に全体にリリースします。

Google Cloud Pub/Sub は、コントロール プレーンとデータプレーンの分離などを通じて、障害に対する優れた復元力を備えており、新バージョンのサーバーのロールアウトはお客様にとってシームレスに行われ、パフォーマンスへの影響をお客様が感じることはありません。

モニタリング

Google Cloud Pub/Sub を継続稼働する鍵は、問題が生じた場合でも、お客様が認識する前に自動的に検知し、影響を抑えることにあります。このためには、システムの広範なモニタリングが必要となります。SRE は、システムの振る舞いを説明するために明確に定義された指標である、各種のサービスレベル インジケーターSLI)を幅広く整備しています。指標の例としては、「CreateSubscription リクエストを完了するまでにかかる時間」や「Publish リクエストによって生成されたエラーの頻度」などがあります。各指標はさまざまな方法で測定されます。一部の指標は、Google のフォワーダーやルーターの内部のみを対象としています。たとえば、「メッセージをディスクに書き込むのにかかる時間」などが該当します。総計で 10 種の SLI と数百種の追加指標を使用して、Google Cloud Pub/Sub の正常性をモニタリングしています。

すべての指標を考慮して、内部のサービスレベル目標SLO)が定義されます。SLO とは SLI の具体的な目標のことで、たとえば、「CreateSubscription リクエストは完了するまでに 5 秒を超えてはならない」といったものです。SLO 違反があった場合、SRE に警告が通知されます。SRE は通知を受けた後、5 分以内に対応することが求められます。

サービスレベル契約SLA)には、SLO がリスト表示されており、お客様に対して Google が保証するパフォーマンスの水準と、その水準を満たさなかった場合の措置について定義されています。Google Cloud Pub/Sub の SLA をご確認ください。

Google では、クライアントとして機能し、想定どおりにパブリッシュやサブスクライブを行うタスクのセットを整備しています。このタスクは「プローバー」と呼ばれます。プローバーには、データプレーン用とコントロール プレーン用があります。10 種のプローバーはそれぞれ、お客様が行うのと同じ具体的な操作を実行し、その操作にかかった時間を測定します。たとえば、新規サブスクリプションを作成してメッセージをパブリッシュし、そのサブスクリプションの作成とメッセージの受信にかかった時間を測定するプローバーなどがあります。30 の指標のいずれか 1 つでも想定どおりではないとプローバーが判断した場合、SRE に警告が通知されます。

さまざまな内部ダッシュボードにサーバーとプローバーの指標の概要が表示され、SRE が問題を診断する際に最初に目に入るように設計されています。各ページでは、下図のようなサービス全体の統計データやグラフを簡単に表示できます。トピック別やデータセンター別、タスク別のデータも表示できます。

サービスのユーザーにとって重要な指標は、Google Cloud Monitoring を通じてエクスポーズされます。Google 自身のプローバーについても、次のようなグラフを利用できます。

現時点のグラフは次のリンクから表示できます。

制御機能

Google Cloud Pub/Sub のパフォーマンスを調整するために、さまざまな制御機能が用意されています。データセンターやマシンの停止に対処するための制御機能もあります。トピックの一部またはすべてにルーティング制約を設定することもできます。ルーティング制約は、フォワーダー セットに接続できるクライアント セットや接続できないクライアント セットを指定するルールです。ルーティング制約を使用することで、想定どおりに機能していない個々のフォワーダー タスクやデータセンター全体からトラフィックを切り離すことができます。

他に Google が調整可能な機能として、フロー制御があります。この機能により、スループットを最大化しつつ、サービス内の過負荷状態を防ぐことができます。フロー制御はトラフィック シェーピングの一形態であり、予期せぬ形で負荷が突然急増した場合でも時間をかけて平坦化することが可能なため、サービスの安定性を高めることができます。フロー制御は、システム規模でも、トピック単位でも、サブスクライバー単位でも実行可能です。また、転送されるメッセージ数やバイト数を制限する方式や、未処理のメッセージ数やバイト数を制限する方式を選ぶことができます。この場合の「未処理」とは、クライアントに配信されたが確認応答が返信されていない、ということを意味します。フロー制御とルーティング制約により、お客様は細かいことを気にすることなく、Google Cloud Pub/Sub のパフォーマンスを最適化できます。

まとめ

Google Cloud Pub/Sub のようなサービスが提供する、スケーラビリティ、可用性、レイテンシという 3 つの利点は、マネージド クラウド サービスへの移行をお考えのお客様にとって価値のあるメリットであると言えます。非同期メッセージ サービスは、このような特長を念頭にビルドする必要があります。Google Cloud Pub/Sub チームは、10 年以上にわたって信頼性に優れたメッセージ配信を大量かつ迅速に実現してきた経験を投入し、Google の基本的サービスのニーズの変化に柔軟に対応できるサービスをビルドし、メンテナンスを行ってきました。その同じサービスが、今、メッセージを世界中に送信したいと希望するすべての外部のお客様にご利用いただけるようになりました。現行の自社メッセージ システムの負荷の 2 倍、10 倍、あるいは 100 倍の負荷にも心配する必要はもうありません。

用語集

用語 説明
クラスタ 通常、1 つの障害ドメイン(共有ローカル ネットワークや共有電源)を共有するマシンの論理グループ。
コントロール プレーン データプレーン上のサーバーに対するパブリッシャーとサブスクライバーの割り当てを処理する Google Cloud Pub/Sub のレイヤ。
データプレーン パブリッシャーとサブスクライバーの間で移動するメッセージを処理する Google Cloud Pub/Sub のレイヤ。
フォワーダー データプレーン内のサーバー。
グローバル サービス クライアントがサービスを使用する際に接続先のリージョン(またはデータセンター)を認識したり、指定したりする必要のないサービス。
水平スケーリング 負荷の増大に対して、サービスのコンポーネントのインスタンス数を増やすことでシームレスに処理できるサービスの機能。
メッセージ Google Cloud Pub/Sub を通って移動するデータ。
ネットワーク距離 2 点間の接続に関するレイテンシの尺度。
プローバー クライアントとして機能し、Google Cloud Pub/Sub サーバー上で 1 つまたは複数の操作を想定どおりに実行するタスク。
パブリッシュ メッセージ ソース パブリッシング フォワーダーによって受信と保存が行われたメッセージ セットと、トピックに属するすべてのサブスクリプションによって確認応答が返信されたメッセージの ID のセット。
パブリッシュ / サブスクライブ(Pub/Sub)サービス メッセージの送信者とメッセージの受信者を切り離す方式のメッセージ サービス。
パブリッシャー 特定のトピックに関するメッセージを作成して送信(パブリッシュ)する Google Cloud Pub/Sub のクライアント。
ルーター コントロール プレーン内のサーバー。
ルーティング制約 可能性のある接続先のエンドポイントとして、ルーターによってクライアントに送信されるフォワーダーと送信されないフォワーダーを示すルールのリスト。
サービスレベル契約(SLA) お客様に対して Google が保証するパフォーマンスの水準と、その水準を満たさなかった場合の措置について定義する SLO のリスト。
サービスレベル インジケーター(SLI) システムの振る舞いを説明するための明確に定義された指標。
サービスレベル目標(SLO) サービスレベル インジケーターの具体的な目標。
サブスクライバー 指定したサブスクリプションに関するメッセージを受信する Google Cloud Pub/Sub のクライアント。
サブスクリプション 特定のトピックに関するメッセージの受信に関心があることを示す名前付きエンティティ。
同期ポイント保証 サブスクライバーが作成されると、その時点以降にパブリッシュされたすべてのメッセージがそのサブスクライバーに配信されること。
トピック メッセージのフィードを示す名前付きエンティティ。

外出先でもリソースをモニタリング

Google Cloud Console アプリを入手して、プロジェクトの管理にお役立てください。

フィードバックを送信...