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サーバによるエッジコンピューティング
←★今回はココを中心
- サーバレス
- CDNサーバによるエッジコンピューティング
- 安価に始められる
エッジコンピューティング(Edge Computing)とは
「Edge」とはコンピューティングモデルの1つで、Device Locally、Edge Server、IoTなどユーザーの身近なものにアクセスするイメージです。 反対に、Cloud や Origin Server など物理的に遠い場合は「Edge」とは呼びません。
「Edge」と聞いたら「ユーザーに近い」イメージ
CDN Edge server とは
Device Locally、Edge Server、IoTなどユーザーの身近にあるものからつながっているルータやISPに位置しているCDNのことを「Edge Server」と呼んでいます。
CloudFlare services の変遷
下の画像は、CloudFlareの管理画面のサイドバーにある機能とローンチされた年度の一覧です。 結構ここ数年で次々と新たなサービスが開発されているのがわかります。
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
- CloudFlare Workers用のCLI
- https://github.com/cloudflare/wrangler
- v2からminiflare(simulator)を内蔵
- console.logデバッグができるの便利
hono
- CloudFlare Workers向けのweb framework
- https://github.com/honojs/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を押下するとかわいい猫が見られます。
- R2に保存された画像データを取得
- R2から一覧を取得して表示
- 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 } })
);
初回キャッシュ時とそれ以降とではずいぶん落ち着いていることが確認できます。
終わりに
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