2
1

More than 1 year has passed since last update.

OCIでfunctions,nosql,objectstorageを使ったサーバレスアーキテクチャ作成

Last updated at Posted at 2022-10-07

概要

OCIを使用して、大量データをストレージ&検索できるようなサーバレス環境を構築してみました。

構成

diagram_serverless.png
こちらが構成図です。

API Gatewayを使用することで簡単に公開WebAPIを作成することができます。
クライアント・アプリケーション側は、ブラウザやwebviewを使用したスマホアプリ等から簡単に使用できます(ノンプラグイン)

APIはサーバ内部でfunctionsをキックします。
今回は以下の3つのfunctionsを作成しました。

  • NoSQL Databaseからテーブルデータ取得
  • Object Storageからバイナリデータ取得
  • Object Storageにデータアップ後に自動でNoSQL Databaseに関連データ投入

実装

下記githubにOCI Java SDKを使用したサンプルを載せていますので参考にしてください。
https://github.com/masa-ishikawa/function_serverless_test

今回はeclipseを用いて開発しました。
環境構築として、まず下記2つのリポジトリからmasterをcloneします。
https://github.com/fnproject/fdk-java.git
https://github.com/oracle/oci-java-sdk.git

fdk-javaはapiプロジェクトのみ取り込み、
oci-java-sdkは開発に関連するプロジェクトを取り込みます、以下は私の取り込みプロジェクトです。
取り込み後は開発するfunctionsのプロジェクトに最新のfck,ociプロジェクトを参照させます。
image.png

その他メモ

Functionsのライフサイクルについて

functionsは下記にある通り、一定時間が過ぎるとコールドスタンバイとなり、次回コール時に時間がかかります。
https://docs.oracle.com/ja-jp/iaas/Content/Functions/Concepts/functionshowitworks.htm

ファンクションの実行が終了し、アイドル状態の期間が経過すると、Dockerコンテナは削除されます。コンテナが削除される前に、Oracle Functionsで同じファンクションに対する別のコールを受信すると、2番目のリクエストは同じ実行中のコンテナにルーティングされます。Oracle Functionsが、実行中のコンテナ内で現在実行中のファンクションに対するコールを受け取ると、Oracle Functionsは水平方向にスケーリングして、両方の着信リクエストを処理し、2番目のDockerコンテナが開始されます。

今回は、作成したwebapiをコンピュートインスタンスからcronで毎分curlすることで、functionsを常に待機状態とし、常に高速な呼び出しを可能にしています。
※OCIはfunctionsコール数に無料枠があります。functionsの料金体系は下記を参照

Functionsのデータ取得について

当初はfunctionsで実行するjavaクラスの戻り値をbyte[]にして直接apigatewayを通してhttpでバイト配列を返していました(zip化はもちろん可能したが..)

バイト生成
		byte[] bytes = new byte[] {};
		try (final InputStream fileStream = getResponse.getInputStream()) {
			bytes = fileStream.readAllBytes(); //javaヒープに全展開!
			log.info("bytes.length=" + bytes.length / 1024d + "kb");
		} // try-with-resources automatically closes fileStream
		client.close();

ただその場合、取り扱うデータがkb単位のものであれば問題ないですが、動画等の比較的大きいデータを扱う場合はバイト配列は難しいです:

このため今回はObjedctStorageの事前認証リクエストを使用しました。
oci sdkを使えば任意のタイミングで生成可能です。
APIコール後にfunctionsにて、オンデマンドで期限を限りなく短くした事前認証リクエストを払い出し、クライアント側に渡します。
そのためfunctionsのメモリは最小の128MBで問題なく動作します。

【おまけ】クライアント側でファイルとしてDLさせたい場合、例えば下記jsで可能です。

ファイル強制DL
      fetch(url)
        .then(function (response) {
          if (response.ok)
            return response.blob();
          throw new Error();
        })
        .then(blob => {
          var urlUtil = window.URL || window.webkitURL;
          var imgUrl = urlUtil.createObjectURL(blob);
          var link = document.createElement('a');
          link.href = imgUrl;
          link.download = fileName;
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link)
        })
        .catch((error) => {
          alert(error);
        });

おわりに

functions+OCI SDKを使用してデータをストレージ&検索できるサーバレスアーキテクチャを作成しました。
ObjectStorage+期限極短の事前認証リクエストを使用することで、データ配信サーバ(Functions)を低スペック・低負荷で実現可能です。

ObjectStorageにデータの実体、NoSQLに各ファイルに紐づく属性情報を格納しましたが、
NoSQLの代わりにMySQLやAutonomousを使用したり、またBIツール等を使用してより高度な分析も可能です。

2
1
1

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
2
1