Cloudflare for application 入門

CloudFlare for application 入門

はじめまして、キャディでバックエンドエンジニアをやっている矢野です。

CloudFlareについて、2022年5月24日に開催された社内勉強会で発表させていただきました。

CDNで有名なCloudFlareですが、CDN以外のサービスの展開が最近活発です。 先日サーバレス向けのデータベースD1のプレスリリースが出ていたりと、その背景を含めて最近のCloudFlareの動向についてキャッチアップしました。


[toc]


CloudFlareとは

CloudFlareのHPによると、以下のように記載されています。

 CloudFlareは、インターネット上で運営されている最大のネットワークの1つです。ユーザーは、Webサイトやサービスのセキュリティとパフォーマンスを向上させる目的でCloudFlareサービスを利用しています。

CloudFlareの特徴

大まかな特徴は以下のようになります。 このうち「CDNサーバによるエッジコンピューティング」を中心に解説していきます。

  • セキュリティ
  • 信頼性
    • ゼロトラスト
    • DNS
    • DDoS攻撃対策
  • CDNネットワーク
    • CDNサーバによるエッジコンピューティング ←★今回はココを中心
    • サーバレス
  • 安価に始められる

エッジコンピューティング(Edge Computing)とは

「Edge」とはコンピューティングモデルの1つで、Device Locally、Edge Server、IoTなどユーザーの身近なものにアクセスするイメージです。 反対に、Cloud や Origin Server など物理的に遠い場合は「Edge」とは呼びません。

「Edge」と聞いたら「ユーザーに近い」イメージ

About edge

CDN Edge server とは

Device Locally、Edge Server、IoTなどユーザーの身近にあるものからつながっているルータやISPに位置しているCDNのことを「Edge Server」と呼んでいます。

CDN Edge server

CloudFlare services の変遷

下の画像は、CloudFlareの管理画面のサイドバーにある機能とローンチされた年度の一覧です。 結構ここ数年で次々と新たなサービスが開発されているのがわかります。

CloudFlare service

CloudFlare workers

CloudFlare workersとは

エッジサーバで実行されるサーバレス実行環境(FaaS)です。 無料枠では、リクエストあたりのCPU時間に制限があります。

CloudFlare workersの特徴

  • エッジサーバで実行されるためスケールする
  • Service Worker APIに似たAPIで記述
  • JS(TS), Rust, C, C++ etc...が使える
  • ローカル開発環境が充実
  • Cacheが利用可能
  • WorkersとPagesの料金設定 | CloudFlare

キャッシュ

CloudFlare workersで使えるキャッシュは大きく分けて以下の3つがあります。 それぞれ特徴が分かれているので、おさえておきましょう。 後で紹介するデモでは「Workers KV」を使います。

Workers KV

  • 読み取り頻度が高い場合向け
  • 書き込みに関しては、すべてのエッジサーバに伝搬するのに最大で60sかかる
  • アトミックな操作はできない

Durable Objects

  • 遅延が少なく、強整合性を持つKV
  • リアルタイム性を要求するアプリケーションでも利用可能(e.g. WebSocket)
  • 有料($5~)

Cache API

  • それぞれのエッジサーバのローカルに保存される
  • ブラウザのCache APIと同じインタフェース
  • Cacheが有効なのはサイトの配下のみ(ワーカのAPIそのものには効かない)

CloudFlare R2 Storage

Object Storageのことで、データ転送量(下り)が無料という特徴があります。

「R2」という名前のとおり「S3」と対抗している雰囲気があり、R2の特徴は以下になります。

  • S3のAPIと完全互換性がある
    • Really Requesテーブル(真にリクエスト可能な)
    • Repositioning Records(レコードを再配置する)
    • Ridiculously Reliable(途方もなく信頼できる)
    • Radically Reprogrammable(根本的に再プログラム可能な)
参照:CloudFlare R2ストレージの発表 - 高速で信頼できるオブジェクトストレージ、エグレス料金なし

Tools for developer

今回使った開発ツールを紹介します。

Wrangler v2

hono

ローカル開発はwranglerで完結

実際のコマンドは以下にあるものでほぼすべてになります、非常にシンプルです。

$ yarn add global wrangler
$ wrangler login
$ wrangler kv:namespace create "SAMPLE_KV"
$ wrangler r2 bucket create images
$ npx wrangler init XXX
$ npm install hono
$ wrangler dev
# Coding...
$ wrangler publish

簡易アプリ作成

やっていることは以下のとおりで、URLを押下するとかわいい猫が見られます。

  1. R2に保存された画像データを取得
  2. R2から一覧を取得して表示
  3. Workers KVでキャッシュ

Get R2 object

R2でやっているオブジェクトの取得コードは以下になります。

import { Hono } from "hono";
const app = new Hono();

app.get("/image/:id", async (c) => {
  const key = c.req.param("id");
  const object = await BUCKET.get(key);
  if (!object) {
    return c.text("Image Not Found", 404);
  }
  const body = await object?.arrayBuffer();
  c.header("Content-Type", object.httpMetadata.contentType!);
  return c.body(body);
});

app.fire();

R2やWorkers KVの設定

このうちBUCKET .getには下準備が必要です。

1つ目の準備は、型定義です。

xxx.d.ts

declare global {
  const BUCKET: R2Bucket;
  const SAMPLE_KV: KVNamespace;
}

型定義のあとwrangler.tomlに設定を書きます。

wrangler.toml

name = "cloudflare-worker-demo"
main = "src/index.ts"
compatibility_date = "2022-05-23"

kv_namespaces = [
  { binding = "SAMPLE_KV", id = "xx", preview_id = "yy" }
]

[[r2_buckets]]
binding = 'BUCKET'
bucket_name = 'images'
preview_bucket_name = 'images'

List view

結果の猫一覧は以下のように書いています。

const imageTag = (img_path: string) => {
  return `<img src="${img_path}" />`;
};

app.get("/", async (c) => {
  const list = await BUCKET.list();
  const keys = list.objects.map((headResult) => headResult.key);
  return c.html(keys.map((k) => imageTag(`/image/${k}`)).join(""));
});

Workers KV キャッシュ

キャッシュはこのようになります。

 // check cache
  const kv_cache = await SAMPLE_KV.getWithMetadata<Metadata>(key, {
    type: "arrayBuffer",
  });

  if (kv_cache.value && kv_cache.metadata) {
    const body = kv_cache.value;
    const contentType = kv_cache.metadata.contentType;
    c.header("Content-Type", contentType);
    return c.body(body);
  }

  const object = await BUCKET.get(key);
  // ...

  // save cache
  c.event.waitUntil(
    SAMPLE_KV.put(key, body, { metadata: { contentType } })
  );

初回キャッシュ時とそれ以降とではずいぶん落ち着いていることが確認できます。

result

終わりに

CloudFlareを使うと、手軽にAPIやサーバを立てられることを体感できました。

CloudFlareでは、今回使用したWorkers KVしか提供していませんでしたが、最近「CloudFlare D1」分散RDBを出してきました。

競合はSpannerやCockroach DB等と考えられるのですが、サーバレスかつエッジネットワーク上で整合性を保つRDBは結構特徴的な位置付けになりそうです。 コスト面はR2と同じくデータ転送に対する課金はなく、割と安価にサービスを提供されると予想されます。

ここまでお読みいただきありがとうございました。キャディにご興味のある方は、お気軽に求人ページからカジュアル面談をお申し込みください。また、 各種エンジニア向けイベント も随時開催しています。こちらもぜひご覧ください。

参考資料

CloudFlare本家 - CloudFlare - Webパフォーマンスとセキュリティを追求する企業 | CloudFlare - エッジコンピューティングとは? | CloudFlare - D1を発表:当社初のSQLデータベース

DevelopersIO - CloudFlareのR2ストレージ | DevelopersIO - [速報] CloudFlare のエッジ環境で使用できる SQL データベース D1 が発表されました! | DevelopersIO

Others - CloudFlare Workers メモ - CloudFlare R2の画像をCache APIでキャッシュして返すメモ - CloudFlare R2もいいぞ! - ゆーすけべー日記 - Remix on CloudFlare WorkersからCloudFlare R2を使う | DevelopersIO