原文はこちら。
https://medium.com/fnproject/fn-hot-docker-functions-e02d15033392
理想的には、Fn functionは「ホット」(Cold Startが不要ですぐに動き出せる状態)であるべきです。
Fn Function Development Kits(FDKs)を使用している場合、hot functionは簡単です。 実際には、おそらくFDKを使用していて、あなたのfunctionがhotかどうかに考えが及んでいなかったかと思います。アプリケーションにFDKライブラリを含め、ハンドラfunction(またはメソッド)を書き、ハンドラをFDKに渡しました。 コンテナが生きている状態で、FDKが関数の呼び出しをリッスンするリクエスト・ループを提供しているという事実はですが、実のところそうなっています。
FDKを使っていない場合、functionをデフォルト(つまりhotではない)コンテナ・コントラクトで実行しています。デフォルトの場合、コンテナは各functionの呼び出しで開始され、入力を標準入力(stdin)でコンテナに渡し、レスポンスを標準出力(stdout)から読み取り、その後シャットダウンされます。動作しますが、hot functionの低レイテンシでのレスポンスは提供しません。
(注意)この例は説明目的にすぎません。実際には、最適なNode.jsのパフォーマンスのためにはFn Node FDKを使うべきです(訳注:2018/10/10現在Experimentalのようです)。
hotwrapを使うには、コンテナの
(注意)この例はマルチステージDocker buildを使ってDockerイメージから実行可能な
hotwrapを開発してくれたOwen Cliffeに感謝いたします。
https://medium.com/fnproject/fn-hot-docker-functions-e02d15033392
理想的には、Fn functionは「ホット」(Cold Startが不要ですぐに動き出せる状態)であるべきです。
Fn Projecthot functionであれば、関数コンテナの始動後生存し続けて、一連の関数呼び出しを処理しようとします。hot functionがすばらしいのは、コンテナ始動のコストが大きいからです。Fnサーバーは、イメージがローカルにキャッシュされていない場合はリポジトリからイメージをプルし、コンテナを起動し、通常はコンテナ内で言語ランタイムをブートしてから関数呼び出しの処理を開始します。hot functionを使用すると、これらの「コールドスタート」(プル/スタート/ブート)のコストは最初の起動時に支払うだけですみます。後続の呼び出しでのレイテンシは劇的に少なくなります。だから、自然とhot functionを常にデプロイすべきと考えますよね。残念ながら、functionとしてDockerコンテナをデプロイする場合はそれほど簡単ではありませんが、手はあります。
http://fnproject.io/
Fn Function Development Kits(FDKs)を使用している場合、hot functionは簡単です。 実際には、おそらくFDKを使用していて、あなたのfunctionがhotかどうかに考えが及んでいなかったかと思います。アプリケーションにFDKライブラリを含め、ハンドラfunction(またはメソッド)を書き、ハンドラをFDKに渡しました。 コンテナが生きている状態で、FDKが関数の呼び出しをリッスンするリクエスト・ループを提供しているという事実はですが、実のところそうなっています。
FDKを使っていない場合、functionをデフォルト(つまりhotではない)コンテナ・コントラクトで実行しています。デフォルトの場合、コンテナは各functionの呼び出しで開始され、入力を標準入力(stdin)でコンテナに渡し、レスポンスを標準出力(stdout)から読み取り、その後シャットダウンされます。動作しますが、hot functionの低レイテンシでのレスポンスは提供しません。
Hot Docker
FDKによる人気のある言語のサポートに加え、FnはfunctionとしてDockerコンテナのデプロイをサポートします。これは他の多くのFunction-as-a-Serviceプラットフォームと比較した場合の大きな差別化要因です。Fnでは、コンテナがサポートされているコンテナ・コントラクトのいずれかを実装している限り、functionとして任意のものをデプロイできます。幸いにも、デフォルトのstdin/stdoutコンテナ・コントラクトをカスタムのコンテナ化されたfunctionに簡単に組み入れることができます。たとえば、コンテナイメージとしてNode.jsプログラムをパッケージ化するDockerfileがあるとします。これをfunctionとしてFnにデプロイできます。(注意)この例は説明目的にすぎません。実際には、最適なNode.jsのパフォーマンスのためにはFn Node FDKを使うべきです(訳注:2018/10/10現在Experimentalのようです)。
Experimental FDK for Node.js
https://github.com/fnproject/fdk-node
func.jsname = "World";
fs = require('fs');
try {
input = fs.readFileSync('/dev/stdin').toString();
if (input) {
name = input;
}
} catch(e) {}
console.log("Hello", name, "from Node!");
Node.js default container contract DockerfileFROM node:8-alpine
WORKDIR /function
ADD func.js /function/func.js
ENTRYPOINT ["node", "./func.js"]
func.yaml
ファイルとfn build
で、このfunctionをビルドできますが、(コンテナ・コントラクト)format
はdefault
、runtime
はjava
やnode
といったFnでサポートされている言語ではなく、docker
を設定することに注意してください。default docker func.yamlこれらの3ファイルを使い、デフォルトのコンテナ・コントラクトのfunctionをデプロイできるのですが、このfunctionはhot functionの場合に比べてレイテンシが小さくなりません。というのも、各呼び出しで、コンテナとNode.jsランタイムの起動コストが必要だからです。ローカルのFnサーバーにデプロイしてこのfunctionをschema_version: 20180708
name: hello
version: 0.0.1
runtime: docker
format: default
time
コマンドを付けて起動すると、約1.3秒のレスポンス時間があることがわかります。かなり悪い結果ですが、MacBook上でDockerコンテナを起動しているので、これぐらいの時間がかかるのも無理はありません。“Hotwrap” Prototype
このコードをhot functionとして実行できれば、ずっといいですね。幸運なことに、FDKを使わないfunctionをhot functionとして簡単にデプロイするために、 コードネーム "hotwrap"というプロトタイプユーティリティを現在開発しています。hotwrap - Command wrapper that lets you run unix commands as functionsHotwrapはhot functionのコンテナ・コントラクトを実装し、functionが呼び出されるたびに標準入出力ベースのfunctionを実行します。Hotwrapを使用すればfunctionコンテナは生存し続けるので、コンテナの起動コストを回避できます。ただし、各呼び出しで実行可能なfunctionを起動するためのコストはかかります。
https://github.com/fnproject/hotwrap
hotwrapを使うには、コンテナの
ENTRYPOINT
としてhotwrap
を実行可能にして、実行可能なfunctionを起動するためにCMD
を設定するだけです。以下のDockerfileは、先述のNode.jsのサンプルコードに対してhotwrapを追加するために必要な変更を加えたものです。(注意)この例はマルチステージDocker buildを使ってDockerイメージから実行可能な
hotwrap
を取得していますが、このイメージはまだDocker Hubには公開されていません。このイメージをGitHubに上がっているソースからビルドできます。Dockerfile with hotwrapアップデートしたDockerファイルを使って、Node.jsのfunctionを再デプロイして、再度# Pull the hotwrap container as a build dependency
FROM fnproject/hotwrap:latest as hotwrap
# Start of your normal docker file
FROM node:8-alpine
WORKDIR /function
# Add function implementation
ADD func.js /function/func.js
CMD node ./func.js
# Install hotwrap binary in your container
COPY --from=hotwrap /hotwrap /hotwrap
ENTRYPOINT ["/hotwrap"]
time
コマンドを使って計測します。最初の呼び出しでは、functionの実行に0.775秒要しました。この時間には、コンテナとNode.jsの開始コストが含まれています。その後の呼び出しでは、約0.2秒と約0.5秒速くなりました。hotwrapのおかげで、Node.jsランタイムを起動しコードを実行するだけのコストで済みます。The future of Hotwrap
Hotwrapはプロトタイプなので、本番環境では使用しないでください!とはいえ、元々はfunctionとして作成されていなかったプログラムをパッケージ化し、そのランタイム・パフォーマンスを向上する、Fnで提供するしくみの実現可能性およびその価値をHotwrapは示しています。FnではfunctionとしてDockerコンテナのデプロイをサポートしてきましたが、これらのfunctionではデフォルトのコンテナ・コントラクトを使う関係上、レイテンシが大きくなりました。Hotwrapはこの差異をある程度解決するものです。近い将来の公式なhotwrapユーティリティ(たぶん名前は変わると思います)の登場をお待ちください。hotwrapを開発してくれたOwen Cliffeに感謝いたします。