自己紹介とアジェンダ

堤浩玄氏(以下、堤):では『Cloud Run導入事例のご紹介 ~最速マネタイズを目指す~』というタイトルでお話しします。GMOアドマーケティング開発部の堤です。よろしくお願いします。

一応、自己紹介です。私はGMOアドマーケティングにて、Webアプリケーションのエンジニアをやっています。ふだんは弊社の「AkaNe byGMO」というサービスの画面周りや、今回紹介する新規の媒体事業の開発運用を担当しています。

では、今回のアジェンダです。まずはCloud Runの導入事例についてお話しします。Cloud Runはどういったサービスかを少しだけ説明するのと、あとは、今回導入した新規事業のシステム構成についてお話しします。

また、今回はクラウドネイティブというテーマなので、クラウドネイティブにどれくらい当てはまっているのかも見ていきたいと思っています。

その次に、Cloud Runのチューニングについて見ていきたいと思っています。自分がやって比較的重要だと思ったところと、今は取り入れていないものの、今後検討したいことなどに分けて説明します。最後にまとめ、所感で終わらせられたらと思っています。

Cloud Runのオプションと特徴

まずCloud Runとは。ほぼグーグルのドキュメントから持ってきた言葉になりますが、「ステートレスコンテナを実行するマネージドコンピューティングプラットフォーム」というサービスです。

“ステートレス”は状態を持たないことで、“マネージド”はGoogle側でコントロールしてくれるということです。そのため、状態を持たないコンテナを、負荷によって自動で増減してくれるサービスになっています。

今回紹介する事業では、Webリクエストに対するサーバーとして使っています。

Cloud Runは2つのオプションがあり、Knative上で動いているフルマネージド版と、GKE上で動いているCloud Run for Anthos。今回導入したのはフルマネージド版です。

フルマネージド版は本当にシンプルで、コンテナサービスを立ち上げるだけです。導入を検討されている方で、もうちょっと複雑な構成でサービスメッシュの管理など、もっといろいろやりたい場合は、ちょっとこちらは向かないかもしれないです。

次に特徴をいくつか挙げます。まずサーバーレスであることです。あとは0 to Nスケール。こちらはリクエストを受け付けないで一定時間経つと、最終的にコンテナのインスタンス数が0になるので、0からNまでスケールをすることになります。

ほかには、言語の制約は「なし」になっているので、自由な言語を使えます。ただ、パフォーマンスをしっかり意識するという部分では、のちほど説明するチューニングのところで、ちょっと選ぶ必要があります。

あとは使った分だけの課金になっているので、安心して使えます。コンテナなのでポータビリティ性があり、ほかサービスへの移行なども、必要であれば簡単にできる特徴があります。

もう1つの特徴で、Cloud Runはサービスをデプロイするたびにバージョンの履歴のようにリビションができます。これに対して、リクエストの割り振りを好きにできます。例えば、デプロイ後に最新のリビジョンで障害などが起こって、ロールバックしたい場合は、(スライドにある)オレンジで100パーセントになっているトラフィックを、戻したいリビジョンへ100パーセント移すなどをすれば、ロールバックも簡単にできます。

担当事業のシステム構成

では、自分の担当しているシステムの構成を紹介します。事業としては媒体の配信事業になっています。真ん中に媒体を配信するためのdeliverというコンテナと、その上に配信するコンテンツを管理するために、簡易的なCMSを載せたadminというコンテナをCloud Runで動かしています。

adminはRubyのRailsが載っていて、deliverはGo言語で動いています。コンテンツ用のデータベースはCloud SQLを使っていて、そのほかログ蓄積用にBigQueryを使っています。あと細かいところで言うと、監視にはSentryを使っていて、連携させて異常があった際は、SentryからSlack通信が送られるようになっています。

デプロイはCircleCIを使っていて、GitHubからプッシュしたソースコードをビルドしてデプロイする流れになっています。また、関係する外部APIからデータを取ってきてコンテンツに流し込むようなこともやっていて、Cloud Schedulerでadminの中のジョブを叩くかたちにしています。以上、構成はこんな感じです。

マルバツ表で見るクラウドネイティブの実現度

こんな構成で、どれくらいクラウドネイティブが実現できているか、簡単なマルバツ表を作ってみました。上から見ていくと、コンテナはコンテナを使っているので、○です。

サービスメッシュは、サービス間の通信などがまだ規模感的にもぜんぜん必要がないのと、フルマネージド版のCloud Runだとちょっと機能的に難しいというか、できないので。こちらは×と思っています。

マイクロサービスにおける、機能をサービス化して切り離して作っていくところも、今のところは規模感が小さいので、今後機能がどんどん増えていけば、こういった概念を取り込んでやっていきたいと思っています。そのため、△くらいというところですね。

あとはイミュータブルインフラストラクチャ。こちらはコードとしてのインフラなので、今回は○と思っています。最後に宣言型API。こちらは細かな設定はできませんが、Cloud Runでインスタンス数は設定できるので、最小インスタンス数とか最大インスタンス数を維持できているという意味では△というところです。

○×△○△になりました。こんな感じかと思います。

Cloud Runのチューニング

続いて、Cloud Runのチューニングについてお話しします。チューニングの目的は3つあると思っていて、1つは処理時間を短縮すること。もう1つはインスタンスの起動時間を短縮させること。

最後にコールドスタートを減らす、というのがあります。コールドスタートを減らすのは、Cloud Runを使ううえで、少し肝になる気がしています。

一応コールドスタートの説明をしておくと、起動インスタンス数が0の状態からスタートした場合を、コールドスタートと呼んでいて。そうすると、サービスが始まるまでに、レスポンス遅延が起こってしまうと思っています。

チューニングを具体的に見ていきます。比較的重要だと思っているところからですが、コンテナの最適化の中で必要なのは、コンテナの中で一次ファイルを持たないことです。

一時ファイルを持つとメモリをどんどん食ってしまい、クラッシュしてコールドスタートが発生したりします。そうなると、一時ファイルの削除が必要になります。

エラーをハンドリングするところも、似たような意味合いだと思います。エラーになってインスタンスがクラッシュしてしまうと、それもコールドスタートを発生させる原因になるので、エラーはすべて例外処理する必要があります。

先ほどちょっと言語の話をしましたが、動的言語を使わず、静的言語を使ったほうがいいです。理由としては、動的言語を使うとインスタンス立ち上げにいろいろ読み込みなどが発生します。立ち上げに時間がかかるのを防ぐ必要があります。

あとはCPU、メモリの最適化です。フルマネージドといえども、どんなパフォーマンスでもいいのかと言うと、そうではないと思うので。普通の一般サーバーと同じように負荷試験をして、CPUやメモリの使用状況を見て、適切に設定する必要があると思っています。

最後、赤字でスライドに書いている重要なところ、concurrencyの設定です。こちらはコンテナ、インスタンスが受けられるリクエスト数を設定できます。Googleのサービスだと、App Engineとかです。こういうのは、1つしか受けられないなどの特徴があると思います。

GoogleのCloud Runだと、1つのインスタンスにつき最大250リクエストまで受けつける設定ができるので、ある程度負荷状況に鑑みて、最適化する必要があると思います。ある程度数字を持たせてあげることで、DBへの接続数も減らせられるので、こちらも最適な値に設定するとよいと思います。

ここまでが重要なところです。検討したいほかのところは、Memorystoreの導入、最小インスタンス数。こちらもコールドスタートを防ぐうえで有効だと思うので、検討したいと思っています。

Cloud Runの利用で開発に集中できるように

まとめです。新規開発でCloud Runを使って見た結果、もちろん開発プロセスが速くなりました。あと、インフラの管理コストも少ないです。結果、開発に集中できた。

新規事業の場合だと、売り上げが立っていないなどの状況で、限られたリソース、コスト、時間の中でやらなければならないので、こういうサービスを導入して、かなり便利だったと思っています。

以上です。ご清聴ありがとうございました。