こんにちは! App EngineのスタンダードランタイムにRubyが追加されて喜んでいるバックエンドエンジニアのりほやん(高木)と、オレンジ色のチンアナゴは実はニシキアナゴという別種だったことに驚きを禁じ得ない塩ちゃん(塩崎)です。
4/9, 10, 11の期間で開催されたGoogle Cloud Next '19にZOZOテクノロジーズから高木と塩崎が参加しました! GCPの新しい機能や活用についての事例が多く紹介されました。 その中でも2人がカンファレンスで気になった技術を紹介します。
- Cloud Run
- BigQuery Storage API
- Cloud Data Fusion
- 興味深かったセッション
- まとめ
- 最後に
- おまけ
Cloud Run
Google Cloud Next '19ではServerlessについての発表が多くありました。 その中で新しく発表されたCloud Runをピックアップして、どのようなサービスなのか他のサービスとどう違うのかについてまとめてみます!
Cloud Runとは
Cloud RunはHTTPリクエストを介して呼び出すことができるステートレスコンテナを実行できるようにするマネージドコンピューティングプラットフォームです。 複雑な設定なくサーバーレスなコンテナを作成できます。 サーバーレスな環境でコンテナを立ち上げたい!でも最初からKubernetesを構築するのはハードルが高い!という人にぴったりそうなサービスです。
4/12日現在はBeta版で使用できます。
Cloud Runの特徴
Cloud Runの特徴として下記の点が挙げられます。
- コンテナイメージをあげることによって数十秒でHTTPで叩けるURLが発行される
- 裏側でKnativeを使用している
- Cloud RunとCloud Run on GKEがある
- 素のCloud RunはKubernetesの設定をしなくてもよい
- Cloud Run on GKEを使うと自分でKubernetesを構築できる
- Cloud RunからCloud Run on GKE、またはCloud Run on GKEからCloud Runに切り替えられる
- 使用したリソースに対してのみ課金される
実際に使ってみる
簡単なチュートリアルに沿ってRubyのSinatraアプリケーションをCloud Runで立ち上げてみます。 チュートリアルはこちらから試すことができます。 今回はコンテナをビルドするところから始めてみます。 GCP上にプロジェクトがあり、Cloud SDKがインストールされた環境であることを前提とします。
1. アプリケーションの準備
アプリケーションとDockerfileを作成します。 アプリケーションのサンプルコードはチュートリアルにも掲載されていますが、下記のリポジトリにも上がっており、そのまま使うこともできます。 helloworld-ruby
2. コンテナイメージをビルドする
アプリケーションとDockerfileが用意できたらCloud Buildを使ってコンテナイメージをビルドします。
% gcloud builds submit --tag gcr.io/[PROJECT-ID]/helloworld
これでコンテナイメージがGCPにアップロードされました。
3. Cloud Runにサービスを作成する
Cloud Run上にアプリケーションをのせるサービスを作成します。 今回はわかりやすくするためGUI上からサービスを作成しますが、CLIからサービスの作成&デプロイを行うこともできます。
3-1. 『CREATE SERVICE』をクリック
3-2. コンテナイメージの選択で先ほどビルドしたコンテナイメージを選択します。 latestタグがついたイメージを使います。
Cloud Run on GKEの場合は、事前にCloud Runを有効にしたクラスタを作成するとここでクラスタの選択が行えます。
3-3. サービス名を入力しロケーションを選択します。 現在は『us-central1』ロケーションしか選択できません。
3-4. 今回はpublicアクセスをできるようにするため、認証の『未認証の呼び出しを許可』のチェックボックスをオンにします。
これだけです! 『作成』ボタンを押すとサービスが作成されます。 ちなみにオプションの選択ができますが下記のようになっています。
数十秒ほどでサービス作成は完了し、URLが発行されます。 アクセスすると無事にHello Worldが表示され、アプリケーションが立ち上がっていると確認できました。
サービスの詳細画面からはログの確認や、裏で構築されているKubernetesのYAMLファイルを見ることができます。
App Engineとの違い
Cloud Runに似たサービスとしてApp Engineがあります。 App Engine, Cloud Runがどのように違うのかを比べてみました。 下記のセッションがApp Engine, Cloud RunだけでなくCloud Function, Kubernetes Engine, Compute Engineとも比較しそれぞれのサービスをわかりやすく説明してくれているので、詳しく知りたい方はこちらをご覧ください。
サービスの比較
各サービスの概要・ユーザーが考えないといけないこと・チームの3つの軸で比べてみたいと思います。
各サービスの概要
App Engine
開発者がアプリケーション開発に集中できるようにすることが目的のサービス。 サポートされているランタイムが決まっています。 サポートされていない場合でもFlexible Environmentを用いればアプリケーションを立ち上げることができます。 コンテナは基本的に不要ですが、コンテナを使用して構築することもできます。
Cloud Run
HTTPポートの空いたコンテナイメージがあればアプリケーションを作成できるサービスです。 よりフレキシブルに自分たちで制御したい場合は、Kubernetesを自分で用意することもできます。 コンテナを必ず使う必要があります。
ユーザーが考えないといけないこと
App Engine
GCPにはCloud Runに似たサービスとしてApp Engineがあります。 App Engine, Cloud Runのがどのように違うのかを比べてみました。 下記のセッションがわかりやすく説明してくれているので、詳しく知りたい方はこちらをご覧ください。
Cloud Run
- コンテナイメージ内のコード
- コンテナイメージのビルド
チーム
App Engine
インフラ構築より、開発に注力したいチームが適しています。
Cloud Run
開発に注力しながらも、自分たちのチームでコンテナビルドツールやデプロイ設計も行いたいチームに適してます。
サービスの使い分け
セッションでも話されていましたが、どのサービスを使うかはケースバイケースだと思います。 App Engineでサポートされているランタイムを使いたい、インフラを気にせず開発に注力したい場合はApp Engine、 開発に注力したいけどコンテナを使用したい、自分たちでコンテナをビルドしたりデプロイすることができる場合はCloud Runを使うのが良さそうです。 App EngineのFlexible Environmentでカスタムコンテナイメージを使用することもできますが、やはり本質的にはApp Engineはソースコードに注力したい人向けなのかなと思います。 コンテナを使用したい場合は、今後Cloud Runの方に寄っていくことになるのではないのかなと思います。
Cloud Runのまとめ
実際にCloud Runを使ってみて、5分ほどでスケーラブルなアプリケーションの作成・デプロイ・URLの発行までできてKubernetesの複雑さを意識することなく簡単にWebアプリケーションが立ち上がるのは開発体験としてよかったです。 最初はCloud Runを使って手早くアプリケーションを立ち上げて、必要になったタイミングでCloud Run on GKEに切り替えるという使い方ができれば、サービスの規模に合わせてインフラの選択肢が柔軟に変えられてとても良さそうだと思いました。 Beta版のため、制約も多く検証が必要そうですが、発表でもCloud Runの名前が多く登場していたのでこれからに期待したいです。
BigQuery Storage API
BigQueryからデータを取り出すための新しいAPIです。 BigQueryのストレージ層に対してgRPCでクエリを投げることによって、従来のAPIと比較して高速かつリアルタイムにデータを取得できることが大きな特徴です。
従来のAPI
従来のBigQueryからのデータ取り出しは主に以下の2つの方法で行われていました。
jobs.getQueryResult APIを利用したデータ取り出し
この方法は取得したいデータをSQLを使って表現し、そのSQLの結果をHTTPで取得するものです。 REST APIを直に使ったことのある方は少ないと思いますが、BigQueryのweb UIやCloud SDK経由でほとんどの方が利用していると思います。 少量のデータを出力するときにはこの方法が適していますが、大量のデータを取り出す時にはスピードの遅さが目立つようになります。
extract jobを利用したデータ取り出し
この方法はBigQueryに保存されているテーブルの内容をGoogleCloudStorage(GCS)にCSV、JSON、AVROなどの形式でバルク出力するものです。 getQueryResultと比較して大量のデータを出力できる一方で、バッチ処理でGCSに出力されるため最初の1行目を取得するまでの時間が長いという欠点があります。
BigQuery Storage APIの特徴
Storage APIは上記2つのデータ取り出し方法とは異なる第3のデータ取り出し方法です。 BigQueryのストレージ層に対して直にgRPCでクエリを投げることによって上記2つのAPIの欠点を解消できます。
従来のAPIにはなかった素敵な機能がいくつもあるのでそれを紹介いたします。
Multiple Streams
同一セッション内で複数個のストリームを持たせることができ、それぞれのストリーム間でのデータは重複しないことが保証されています。 この機能は分散環境で複数のマシンからデータを読む時に特にパワーを発揮しそうですね。
Dynamic Sharding
Streamを複数個作った時に各Streamに対するデータの割り当てをBigQuery側が自動的に行なってくれます。 例えばデータ処理速度の違うクライアントがあった時には、処理の遅いクライアントが担当しているStreamへのEnqueueは自動的に減らされるそうです。 そのため、それぞれのクライアントが自分の処理したい速度でデータを処理すればよく、クライアント側に負荷分散のロジックを入れる必要がないそうです。
Column Projection
データを取得する時に必要なカラムだけを取得できます。 それによって、テーブル全体を取得する場合と比較して高速にデータの読み取りを行うことができます。
Column Filtering
シンプルな条件式(SQLのWHERE句)であればデータ取り出しのタイミングでフィルタリングできます。 こちらの機能もデータ転送量を抑えることでデータの読み取りの高速化に寄与しています。
Snapshot Consistency
セッションを作った瞬間のテーブルのスナップショットが保持されるもので、そのスナップショットはセッションを通して有効です。 そのため、複数のクライアントがあったとしても同一セッションを使っていれば整合性のある読み取りを行うことができます。 また、スナップショットの日時はデフォルトではセッションが作られたタイミングですが、過去の日時にすることも可能なようです。 そのため、1時間前の状態のテーブルからデータ取得をするといったこともできます。
各言語のサポート
現時点ではJava、Python、Goのみでサポートされています。 現状は機能を提供したてなので、これらの言語のみに注力しているようです。 ですが、将来的には対応言語が増える可能性もあるそうです。 また、Apache BeamやそのマネージドサービスであるCloud DataflowからBigQueryIOコネクターを使うことでAPIを使用することもできます。
BigQuery Storage API - Libraries and Samples
欠点
さて、ここまででBigQuery Storage APIの良いところばかりを書いてきましたが、欠点もあります。 主に以下の2点が欠点と感じました。
対応言語の少なさ CloudSDKが対応している言語(Java, Python, NodeJS, Ruby, Go, .NET, PHP)の半分程度の言語でしか、BigQuery Storage APIを使うことができません。 この欠点については将来的に対応言語が増える可能性もあるようですので、これからに期待です。
Column Filteringの柔軟度
Column Filteringを利用することによってSQLのWHERE句に相当する絞り込みができますが、WHERE句ほどの柔軟度はないようです。 以下のPythonライブラリのドキュメントによると、1つの条件式しか使用できず、また条件式の引数の片側は定数にする必要があるそうです。
Python Client for BigQuery Storage API
OKな例:
int_field > 10
data_field = CAST('2014-9-27' as DATE)
NGな例:
int_field1 > 10 AND int_field2 > 20
int_field1 > int_field2
クエリの柔軟性という観点から見た場合は従来のAPIのほうが優れているので、自分たちのワークロードが従来のAPIの性能限界に達していない状況での拙速な移行は避けるべきかとも思います。
BigQuery Storage APIのまとめ
BigQuery Storage APIという新しいAPIの登場によってBigQueryの利用シーンが増えそうな予感がします。 このAPIは初期の段階からApache Beam/Cloud Dataflowサポートが行われています。 そのため、いままでBigQueryが苦手としてきた大量データのリアルタイムストリーミング処理用が主な利用用途と思います。
Cloud Data Fusion
2日目のkeynoteでも発表されていたフルマネージドなデータインテグレーションサービスです。 ETL/ELTデータパイプラインを作成でき、その実行はマネージされたインスタンスで実行されます。
このサービスは昨年にGoogleが買収したCDAPというサービスをベースにしているそうです。 CDAPは100% オープンソースなプロジェクトでオンプレ・クラウド両方のETLを作成できます。
パイプラインの作成
データ転送のためのパイプラインは以下の図に示すようにGUIから作成でき、またパイプラインの実行状況の確認もGUIから行えます。
作成したパイプラインは手動で実行させられますし、スケジューリング実行もできるようです。 さらにCloud Composerと連携し、Cloud ComposerからData Fusionのワークフローの実行を行うこともできるようになる予定です。
現時点ではETL処理はCloud Dataproc上で行われるそうですが、将来的にはCloud Dataflow上でも行うことができるようになるらしいです。
データのプレビュー機能
さらにETLワークフローを書く前にデータソース中身をプレビューし、その場で変換関数の結果もプレビューできるようです。 その場で変換関数の結果を見ることができるので、トライアンドエラーを高速に行うことができそうです。
コンポーネント
ETLワークフローを実現するために以下のコンポーネントが標準で付属しています。
コネクター
データソースとの接続のためのコンポーネントです。 これはEmbulkでいうところのinput-pluginやoutput-pluginに相当するものです。 以下に示すような標準的なGCPサービスには対応しています。 Google Cloud Storage(GCS), BigQuery, CloudSQL, Cloud Pub/Sub, Cloud Spanner, Cloud BigTable, Cloud Datastore
さらに非GCPなクラウドサービスやオンプレに構築されたデータソースにも対応しています。
aws S3, aws Athena, ファイルシステム, MySQL, Netteza, etc.
変換関数
データの変換を行うためのコンポーネントです。 Embulkでいうところのfilter-pluginやparser-pluginに相当します。 データをコピーしたり、JSONをパースしたりできるようです。 また、既存の変換関数に不十分な部分があった場合は自分でJavaScriptの関数を追加することもできます。
エラー検知
エラーが発生した時にそれを他のコンポーネントに流し込むことができるようです。 発生したエラーを他のコンポーネントで処理することで柔軟なエラー処理を行うことができそうです。
Cloud Data Fusionのまとめ
Cloud Data Fusionを使うことでETLワークフローを作成することができそうです。 GUIベースでワークフローを作成することができるため、プログラミングをすることができない人でもパイプラインの開発が可能になったのは大きなメリットかと思います。 扱うデータの規模が小さく、専任のデータエンジニアがいないようなチームではCloud Data Fusionを使うと幸せになれる予感がします。 一方でワークフローの規模がある程度大きくなるとGUIではなく、GitHubなどを用いたコードベースでの管理が欲しくなります。 Cloud Data Fusionがそのような使い方をできるようになるかどうか、今後も注目していきたいです。
興味深かったセッション
Google Cloud Next '19では約600セッションととても多くのセッションがありました。 その中で面白かったセッションを紹介します。
Serverless関連
Migrating from a Monolith to Microservices
モノリスなアプリケーションをマイクロサービスに移行する際のGCPをつかったベストプラクティスを紹介しています。
Serverless on Google Cloud
GCP上にサーバーレスなアプリケーションどうやって構築するかについて紹介しています。 Cloud Runを使って実際にPDFを生成するアプリケーションを構築するデモもあります。
CI/CD in a Multi-Environment, Serverless World
GCPのサーバーレスサービスのCI/CD戦略についてのセッションです。
Design Pattern Evolutions for a Scalable Future
GCPのサーバーレスなサービスを使う際のデザインパターンを紹介しています。
Building a WorldWeb App with Ruby, App Engine, Serverless Container, and Spanner
Rubyを使ってサーバーレスにアプリケーションを立ち上げた話。 Spannerも使ってみたようですが結局相性が悪そうでした。
BigQuery系の興味深かったセッション
Plaid's Journey to Global Large-Scale Real-Time Analytics With Google BigQuery
YouTubeにまだ動画が上がっていないので、上がり次第埋め込みリンクにします。
KARTEというサービスを提供しているPLAIDさんの発表です。 BigQueryでReal-Time処理をするときのアーキテクチャパターンを紹介しています。
Kohls and Datametica Share EDW Workload Migration Tips
Kohls(アメリカやカナダで展開しているホームセンター)の分析基盤をオンプレからBigQueryに移行したという話です。 オンプレ時代の辛みから始まり、どういう戦略で移行を行ったのか、移行した結果どういう良いことが起こったのかを紹介しています。 まだ一部のシステムはオンプレにあるため、「俺達の戦いはこれからだぜ!」という終わり方をしています。 同じく分析基盤移行をしている身としては応援したくなるような場面が数多くありました。 来年のGoogle Cloud Nextではさらなる進化を遂げた分析基盤を見せてもらいたい気持ちでいっぱいです。
Data Warehousing With BigQuery: Best Practices
個人的に一番の神セッションです。 BigQueryの運用中にハマりがちな罠に対する転ばぬ先の杖が数多く紹介されていました。 特にslotに関する知見が深まったのは大きな収穫でした。 後半のteadsさんの事例紹介もCloud Dataflowを使ってラムダアーキテクチャをカッパアーキテクチャにするお手本のような内容でした。
Best Practices for Storage Classes, Reliability, Performance, and Scalability
YouTubeにまだ動画が上がっていないので、上がり次第埋め込みリンクにします。
Google Cloud StorageのStorage Classが増えたという内容です。 どういう時にどのStorage Classを使うと信頼性やコストやパフォーマンスが良いのかがまとまっています。
まとめ
Google Cloud Next '19はGCP関連の新機能が多く発表されました。 セッションは約600あり、それ以外にもスポンサーブースもあったりGCPのエキスパートの方とお話しする機会をいただいたりとても刺激を受けました。 SREについてGoogleのCREの方にお話しいただいたり勉強になりました。 この経験を普段のプロダクト開発に生かしていきたいと思います。
最後に
カンファレンス参加に関わる渡航費・宿泊費などは全て会社に負担してもらいました! 自分から希望すれば参加する機会をいただけて本当に感謝です! ZOZOテクノロジーズでは、最新技術に対する感度が高く、最新技術をプロダクトに取り入れたい人を募集しています。 こちらからご応募ください。
おまけ
おまけとして、Google Cloud Next '19に参加した際にとった写真を載せておきます。 楽しかったことが伝われば幸いです!
会場はMoscone Centerという会場でした。
お昼ご飯が提供される公園では桜が咲いていて天気も良く気持ちよかったです。
近くのフードコートがすべて貸し切られランチが提供されていました。
美味しいという話を聞いたSuper Duper Burgerを公園で食べている写真です。
肉肉しくて美味しかったです!
スポンサーブースにあったCloud BuildとCloud Runのデモ。 とにかく規模が大きい。
想像していたのと違ったゴールデンゲートブリッジ。 真ん中が霧で見えない…ガイドブックで見たのは全部見れていたのにな…
コンピュータ歴史博物館にも行ってきました。 世界初のコンピュータから自分が今使っているコンピュータまでの歴史が知れてとても面白かったです。