Cloud Dataflow の FlexTemplate は何者か
先月、さらりと Cloud Dataflow に FlexTemplate という新機能のベータ版がリリースされました。
残念ながらまだあまりドキュメントがなく、これを用いるとなにが嬉しいのかが掴みにくいところです。 本記事では FlexTemplate 周りを軽く試してどのような機能で何が嬉しいのか探ってゆきます。
従来のテンプレート
Cloud Dataflow はジョブの一部パラメータを実行時に置き換え可能にしたビルド済みのテンプレートを作ることができます。 また Google はこの機能を用いた公式テンプレートを何種類か用意してくれており、 GCP 上のリソースに対してコーディングなく ETL 処理をすることが可能になっています。
ちなみにこのテンプレートの機能なのですが、 FlexTemplate の登場の都合からかドキュメント上で "従来のテンプレート" という見出しになってしまったようです。。。
実行時にパラメータを置き換え可能にするには、その値を ValueProvider
でラップしてあげる必要があります。
ValueProvider
の実装としてテンプレートのステージング時に静的に値が決まる StaticValueProvider
と実行時に決まる RuntimeValueProvider
が存在しており、これによりパラメータを渡すタイミングを柔軟に選べます。
また Apache Beam の SDK 内の IO 関連ビルダークラスには ValueProvider
を受け取って振る舞いを変えてくれるものが多々あります。
逆に言うとこの ValueProvider
で賄えないような性質のパラメータは実行時に指定可能なパラメータとして扱えません。
これは分かりやすい部分で言うと Beam の SDK のインタフェース的に ValueProvider
を受け取ってくれないような部分、もっと複雑な例で言うと内容によってパイプラインのグラフが変わるようなパラメータは扱えません(あるいは扱うのが困難)
FlexTemplate
FlexTemplate は、おそらくなのですが、与えられるパラメータに柔軟性を与えるものです。
ドキュメントだけでは正体が定かにはならないですが、 gcr.io/dataflow-templates-base/java11-template-launcher-base
をベースとした Docker image を用いて Dataflow ジョブを実行するようになります。
テンプレートジョブの構築手順は「従来のテンプレート」に似ており FlexTemplate によるテンプレートの作成と、実行の 2 つのフェーズがあります。
前者では前述の Docker image を GCR に push して、かつその Docker image で解釈可能なパラメータを示した metadata.json
を GCS に upload します。 Docker image の build & push は従来のテンプレートでは存在しなかった手順ですね。
後者では実際にパラメータを与えてジョブを実行します。
このジョブの実行時に興味深いことに、ジョブの launch 用に GCE インスタンスが開始され先程作成した Docker image が実行されることが見て取れます。 この Docker コンテナの動作がよくわからないところですが、内部的にはこのタイミングから Dataflow ジョブのステージングと実行を開始してくれるものと考えられます。
#cloud-configs ... ExecStart=/usr/bin/docker run -v /var/log/dataflow/template_launcher:/var/log/dataflow/template_launcher gcr.io/xxx/samples/dataflow/streaming-beam-sql --template-container-args='{"consoleLogsLocation":"gs://xxx/staging/template_launches/xxx/console_logs","environment":{"region":"us-central1","serviceAccountEmail":"xxx","stagingLocation":"gs://xxx/staging","tempLocation":"gs://xxx/tmp"},"jobId":"xxx","jobName":"streaming-beam-sql-20200512-004931","jobObjectLocation":"gs://xxx/staging/template_launches/xxx/job_object","operationResultLocation":"gs://xxx/staging/template_launches/xxx/operaton_result","parameters":{"inputSubscription":"test","outputTable":"foo:bar.baz","stagingLocation":"gs://xxx/staging","tempLocation":"gs://xxx/tmp"},"projectId":"xxx"}' ...
さてこの FlexTemplate で何が嬉しいのかというと、大きな差異として実行時パラメータを ValueProvider
で包む必要が無くなった点があります。
FlexTemplate を利用したジョブのサンプルがいくつか公開されているのですが、この内の PipelineOptions の getInputSubscription()
など、実行時に指定可能なパラメータでありつつも ValueProvider
型で扱われていないことが見てとれます。
これにより、従来のテンプレートでは課題になっていた ValueProvider
を受け取ってくれないような値を実行時に変更したいだとか、パイプラインの構造が変わるようなパラメータを渡したいような部分に効果を発揮するものと思われます。
とは言ってもデメリットもあり、ジョブが Queue に入ってから Running の状態になるまで数分待たされる(ステージングのタイミングが遅延したのなら妥当に思えるが)だとか、今のところ Streaming Engine や FlexRS のサポートがないとか課題が存在します。
終わりに
軽く触れてみた限り FlexTemplate はシンプルな仕組みながら Dataflow のテンプレートに相当な柔軟性を持たせることができそうです。 FlexTemplate にどこまでを期待して、どのように従来のテンプレートと棲み分けすべきかのか(上位互換の位置付けなのか?)、今後のサポート具合など気になるところですね。