APIをgRPCに移行することを決定した理由
Vendastaは8年前に、中小企業向けのソリューションプロバイダーとしてスタートしました。当初から、メディア企業や代理店と提携し、彼らが持つ多くの営業担当者と既存の顧客基盤を活用してソフトウェアを販売していました。米国だけでも3000万社以上の中小企業が存在すると推定されており、SaaSソリューションのスケーラビリティは当初から最重要事項の一つと考えられていました。それが、Google App EngineとDatastoreから始めた理由です。このソリューションは、システムが数百から数百万のエンドユーザーへとスケールするにつれて、私たちにとって非常にうまく機能しました。また、この間に、ポイントソリューションから複数の製品を持つプラットフォーム全体へと、そしてパートナーがそれらの製品の販売を管理するためのツールへと、提供範囲を拡大しました。
この道のりを経て、Python GAEは私たちのニーズを十分に満たしてくれました。パートナーがタスクを自動化し、他のシステムと製品やプラットフォームを統合するために、HTTP + JSON経由で多数のAPIを公開しました。しかし、2016年にVendasta Marketplaceを導入しました。これは、私たちの提供するサービスにおける大きな変化であり、サードパーティベンダーがAPIを使用して私たちのプラットフォームで独自の製品を提供するという、APIへの依存度が非常に高くなりました。これは大きな変化でした。なぜなら、私たちの公開APIはサードパーティアプリケーションの上限を定めるものであり、APIを「良い」だけでなく「素晴らしい」ものにする必要があると気付かされたからです。
最初に行った最適化は、Pythonよりも高いスループットと低いレイテンシーでエンドポイントを処理できるGoプログラミング言語を使用することでした。一部のAPIでは、これは驚異的な違いをもたらしました。50パーセンタイルの応答時間が1200msから4msに、さらに劇的には99パーセンタイルの応答時間が30,000msから12msに低下しました!他のAPIでは、それほど大きな違いではありませんでしたが、それでも有意な改善が見られました。
2番目の最適化は、Datastoreのデータの大部分をElasticSearchに複製することでした。ElasticSearchはDatastoreとは根本的に異なるストレージ技術であり、マネージドサービスではないため、私たちにとって大きな飛躍でした。しかし、この変更により、ほぼすべての深夜バッチ処理APIをリアルタイムAPIに移行することができました。BigQueryも試しましたが、クエリ処理時間がリアルタイムでの表示を不可能にしていました。Cloud SQLも試しましたが、データ量が多すぎて容易にスケールできませんでした。App Engine Search APIも試しましたが、10,000件を超える結果セットには制限がありました。代わりに、Google Container Engineを使用してElasticSearchクラスターをスケールアップしました。その強力な集計機能とファセット処理により、私たちのニーズは容易に満たされました。このように、最初の2つのソリューションにより、APIのパフォーマンスに意味のある変更を加えることができました。
最後に行った最適化は、APIをgRPCへ移行することでした。この変更は、クライアントにも影響を与えるため、他の変更よりもはるかに広範囲に及びました。ElasticSearchと同様に、これは根本的に異なるモデルであり、異なるパフォーマンス特性を持ちますが、ElasticSearchとは異なり、真のスーパーセットであることがわかりました。すべての利用シナリオが肯定的な影響を受けました。
gRPCから得られた最初のメリットは、APIを公開して開発者に統合を依頼するというモデルから、SDKをリリースして開発者に自分の言語で書かれたサンプルコードをコピー&ペーストしてもらうというモデルに移行できたことです。これは、私たちの製品と統合したい人々にとって非常に大きなメリットであり、パートナーやベンダーが使用する5つ以上の言語すべてでSDKを手作業で作成する必要がなくなりました。生成されたgRPC SDKの上に、パッケージマネージャーフレンドリーにするための軽いラッパーと、生成されたprotobuf構造体の上へのラッパーをまだ記述していることに注意することが重要です。
gRPCから得られた2番目のメリットは、HTTP + JSONによって必要とされるコールアンドレスポンスアーキテクチャから解放されたことです。gRPCはHTTP/2の上に構築されており、クライアントサイドおよび/またはサーバーサイドのストリーミングが可能です。私たちのユースケースでは、これにより、サーバーで準備ができた結果をストリーミングして、最初の表示までの時間を短縮できます(サーバーサイドストリーミング)。また、双方向ストリーミングでバルク取り込みを容易にサポートする非常に柔軟な作成エンドポイントを提供する可能性も調査しています。これにより、クライアントは非同期で結果をストリーミングでき、サーバーはステータスをストリーミングバックして、確認を待つことなくアップロード速度を低下させずにチェックポイント操作を容易にすることができます。HTTPでは不可能だった、クライアントとサーバー間のインタラクションのまったく新しいモデルを開くこの機能から、私たちはまだそのメリットの始まりを見ているにすぎないと感じています。
3番目のメリットは、JSONからプロトコルバッファへの切り替えであり、これはgRPCと非常によく連携します。これにより、シリアライゼーションとデシリアライゼーションの時間が改善されます。これは一部のAPIでは非常に重要ですが、すべてのAPIで評価されています。より重要なメリットは、プロトの明示的なフォーマット仕様から得られます。これにより、クライアントは自由形式のJSONではなく、型付けされたオブジェクトを受け取ることができます。このため、クライアントはIDEでのオートコンプリート、言語がサポートしている場合は型安全性、そして異なるバージョンのクライアントとサーバー間の互換性の強制といったメリットを享受できます。
gRPCの最後のメリットは、エンドポイントを迅速に仕様化できるようになったことです。データとサービス定義の両方に対するプロトフォーマットは、新しいエンドポイントの定義を大幅に簡略化し、エンドポイント契約の簡潔な定義を finally 実現します。これにより、開発チーム間でエンドポイント仕様をより効果的に伝達できるようになりました。gRPCにより、当社では初めて、APIのクライアント側とサーバー側の両方を同時に開発できるようになりました!これは、SDKを伴う新しいAPIの作成までのレイテンシーが劇的に低下したことを意味します。コード生成と組み合わせることで、クライアントとサーバーを真に並行して開発することが可能になります。
gRPCでの経験は肯定的でしたが、パートナーやベンダーにエンドポイントを提供することの難しさをなくしたり、パフォーマンスの問題すべてを解決したりするわけではありません。しかし、エンドポイントのパフォーマンス、それらとの統合、さらにはSDKの提供においても改善をもたらしました。