LoginSignup
6
0

More than 1 year has passed since last update.

Oracle Functions の新機能 - Provisioned Concurrency について

Last updated at Posted at 2022-05-09

はじめに

Oracle Functions に限らず、FaaS と呼ばれる実行環境では、実行時に動的にリソースを割り当てる事で柔軟なリソース利用(主に、コストやスケール)を実現しています。一方で、初回の実行時には計算リソースや NW リソースの割り当てにある程度時間がかかるので、レスポンスが遅くなる Cold Start 問題は、FaaS を採用する上で避けては通れない問題です。従来では「Functions が再度 Cold Start を引かないような間隔で定期的にリクエストを送り続ける」という手法でこの問題を回避していましたが、今回の機能アップデートでもう少し素直に Cold Start 問題に対処できるようになりました。

Provisioned Concurrency とは?

関数の実行前に決められた数の Function の各種リソース割り当てを済ませておくことで初回実行時の性能を向上させるための機能です。すごくざっくりとしたイメージが以下のようになります。

image01.png

図中に出てきた PCUs という単位は、Provisioned Concurrency Units と呼ばれるもので、事前にどれくらいの数のリソース割り当てを完了させておきますか?という設定値になります。この数は、任意の数を設定できるというわけではなく Functions に割り当てられたメモリ量に応じて設定ができるようになっています。設定可能な PCUs は以下の通りです。(リージョン毎に 40GB まで割り当てることが可能)

Functions に割り当てられたメモリ量 PCUs
128 MB 40 x n
256 MB 20 x n
512 MB 10 x n
1024 MB 10 x n
2048 MB 10 x n

設定方法

前提

  • OCI の有償アカウントを有していること
  • Fn CLI/OCI CLI の最新版がインストール済みであること
    • 手元にない場合は、Cloud Shell を使うと良いです
  • Functions を使用するための初期設定が完了していること

設定手順

設定手順は非常に簡単です。まずは、適当な Function を Fn CLI で作成します。

fn init --runtime go provisioned-concurrency-test-func

実行結果

Creating function at: ./provisioned-concurrency-test-func
Function boilerplate generated.
func.yaml created.

今回は中身を特に変えずにこのままデプロイしたいと思います。まずは Function のビルドをします。

cd provisioned-concurrency-test-func; \
fn build

Function nrt.ocir.io/<namespace>/<repo>/provisioned-concurrency-test-func:0.0.1 built successfully. のようなメッセージが出力されればビルドは完了です。次に、OCIR へプッシュします。

fn push

Function nrt.ocir.io/<namespace>/<repo>/provisioned-concurrency-test-func:0.0.1 pushed successfully to Docker Hub. のように出力されれば OCIR へのプッシュは完了です。次に、Oracle Functions の論理単位であるアプリケーションを作成します。(<compartment-ocid>, <subnet-ocid>は、ご自身の環境に合わせて設定してください)

oci fn application create \
--compartment-id <compartment-ocid> \
--display-name provisioned-concurrency \
--subnet-ids '["<subnet-ocid>"]'

実行結果(一部マスクしています)

{
  "data": {
    "compartment-id": "<compartment-ocid>",
    "config": {},
    "defined-tags": {},
    "display-name": "provisioned-concurrency",
    "freeform-tags": {},
    "id": "<application-ocid>",
    "image-policy-config": null,
    "lifecycle-state": "ACTIVE",
    "network-security-group-ids": [],
    "subnet-ids": [
      "<subnet-ocid>"
    ],
    "syslog-url": "",
    "time-created": "2022-05-09T15:01:41.382000+00:00",
    "time-updated": "2022-05-09T15:01:41.382000+00:00",
    "trace-config": {
      "domain-id": "",
      "is-enabled": false
    }
  },
  "etag": "ad873df8dc37904858c7f6c2134276bd95f6e51775f43a786008bfb4b6cc6f64"
}

次に、作成したアプリケーションで管理する Function を作成します。

oci fn function create \
--application-id <application-ocid> \
--display-name provisioned-concurrency-test-func \
--image nrt.ocir.io/<namespace>/<repo>/provisioned-concurrency-test-func:0.0.1 \
--provisioned-concurrency "{\"strategy\": \"CONSTANT\", \"count\": 40}" \
--memory-in-mbs 128

実行結果(一部、マスクしています)

{
  "data": {
    "application-id": "<application-ocid>",
    "compartment-id": "<compartment-ocid>",
    "config": {},
    "defined-tags": {},
    "display-name": "provisioned-concurrency-test-func",
    "freeform-tags": {},
    "id": "<function-ocid>",
    "image": "nrt.ocir.io/<namespace>/<repo>/provisioned-concurrency-test-func:0.0.1",
    "image-digest": "sha256:5b53a7ac483dbe268c5f6b5e5de322b62cbf3449a084302d217c5a2a282ff176",
    "invoke-endpoint": "https://...ap-tokyo-1.functions.oci.oraclecloud.com",
    "lifecycle-state": "ACTIVE",
    "memory-in-mbs": 128,
    "provisioned-concurrency-config": {
      "count": 40,
      "strategy": "CONSTANT"
    },
    "time-created": "2022-05-09T15:08:49.352000+00:00",
    "time-updated": "2022-05-09T15:08:49.352000+00:00",
    "timeout-in-seconds": 30,
    "trace-config": {
      "is-enabled": false
    }
  },
  "etag": "ba0b922a36e9c5817ef790bd80f7e6f94b3546836267dcaa2bd45c25c764d078"
}

これで、アプリケーション、Function が作成されました。一応、確認しておきます。

アプリケーション

fn list apps | grep -i provisioned

実行結果

provisioned-concurrency <application-ocid>

Function

fn list functions provisioned-concurrency | grep -i provisioned

実行結果

provisioned-concurrency-test-func       nrt.ocir.io/<namespace>/<repo>/provisioned-concurrency-test-func:0.0.1       <function-ocid>

次に、作成した Function を実行してみます。

time fn invoke provisioned-concurrency provisioned-concurrency-test-func

実行結果

{"message":"Hello World"}

real    0m0.826s
user    0m0.126s
sys     0m0.020s

以上です。

ちなみに

Provisioned Concurrency の設定を抜いて実行してみます。

oci fn function update \
--function-id <function-ocid> \
--provisioned-concurrency "{\"strategy\": \"NONE\"}"

実行結果

{
  "data": {
    "application-id": "<application-ocid>",
    "compartment-id": "<compartment-ocid>",
    "config": {},
    "defined-tags": {},
    "display-name": "provisioned-concurrency-test-func",
    "freeform-tags": {},
    "id": "<function-ocid>",
    "image": "nrt.ocir.io/<namespace>/<repo>/provisioned-concurrency-test-func:0.0.1",
    "image-digest": "sha256:5b53a7ac483dbe268c5f6b5e5de322b62cbf3449a084302d217c5a2a282ff176",
    "invoke-endpoint": "https://...ap-tokyo-1.functions.oci.oraclecloud.com",
    "lifecycle-state": "ACTIVE",
    "memory-in-mbs": 128,
    "provisioned-concurrency-config": {
      "strategy": "NONE"
    },
    "time-created": "2022-05-09T15:08:49.352000+00:00",
    "time-updated": "2022-05-09T15:20:06.769000+00:00",
    "timeout-in-seconds": 30,
    "trace-config": {
      "is-enabled": false
    }
  },
  "etag": "44fa9d4d6584a48ea6a3bfb0b40f16eb304c9f8c389b8966c5d76674ef61d31b"
}

(ある程度時間を置き)再度、実行してみます。

time fn invoke provisioned-concurrency provisioned-concurrency-test-func

実行結果

{"message":"Hello World"}

real    0m1.548s
user    0m0.103s
sys     0m0.045s

確かに、Provisioned Concurrency の設定を入れた方が初回実行が早くなっていることが確認できました。

おわりに

ちょっとした設定で簡単に Cold Start 問題の対策ができるので是非試してみてください!

参考情報

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0