3.5K Views
August 07, 23
スライド概要
第 43 回 PostgreSQL アンカンファレンス@オンライン 2023/8/7
Qiita や Zenn でいろいろ書いてます。 https://qiita.com/hmatsu47 https://zenn.dev/hmatsu47 MySQL 8.0 の薄い本 : https://github.com/hmatsu47/mysql80_no_usui_hon Aurora MySQL v1 → v3 移行計画 : https://zenn.dev/hmatsu47/books/aurora-mysql3-plan-book
Cloudflare Workers から PostgreSQL に接続可能になったので 試してみた 第 43 回 PostgreSQL アンカンファレンス@オンライン 2023/8/7 まつひさ(hmatsu47)
自己紹介 松久裕保(@hmatsu47) ● https://qiita.com/hmatsu47 ● 現在のステータス: ○ 名古屋で Web インフラのお守り係をしています ○ 現在は自社サービスのセキュリティ強化中 ○ ついでに MySQL HeatWave をのんびり検証中 ○ #pgunconf ゆるふわ勢 2
本日のネタ ● Cloudflare Workers、TCP ソケットで作成可能な connect()API を発表 https://www.infoq.com/jp/news/2023/07/cloudflare-workers-connect-api/ 3
本日のネタ ● Connect to databases(Cloudflare Docs) https://developers.cloudflare.com/workers/databases/connecting-to-databases/ ● Connect to PostgreSQL (beta)(Cloudflare Docs) https://developers.cloudflare.com/workers/databases/connect-to-postgres/ ※まだベータリリースなので使い方が予告なく変わる可能性があります 4
Cloudflare Workers とは? ● Cloudflare の一般的なイメージ ○ CDN ● Cloudflare 自身が表現する事業のコアドメイン ○ ウェブサイトのセキュリティーとパフォーマンス改善 ● Cloudflare Workers ○ エッジロケーションのサーバーレス環境 ○ ユーザーに近い場所でサーバーサイド JS を実行(SSR など) 5
Cloudflare Workers とは? ● Cloudflare の一般的なイメージ ○ CDN ● Cloudflare 自身が表現する事業のコアドメイン ○ ウェブサイトのセキュリティーとパフォーマンス改善 ● Cloudflare Workers ○ エッジロケーションのサーバーレス環境 ○ ユーザーに近い場所でサーバーサイド JS を実行(SSR など) 6
余談:最近の CDN ● エッジロケーションのサーバーレス環境は当たり前に ○ AWS : Lambda@Edge・CloudFront Functions ○ Fastly : Compute@Edge ○ Akamai : EdgeWorkers 7
Cloudflare Workers に connect()API が実装された ● 何ができる? ○ Workers から直接 TCP ベースの接続が可能 ■ 従来は HTTP(S) ベースか Cloudflare 内のサービスの接続のみ可能 ● Cloudflare 外のデータベースへの接続が可能に ○ PostgreSQL(TCP:5432)の外部データベース接続をサポート ■ node-postgres(pg)を使用 ■ ポート番号自体は変更可能 8
やってみた ● 前掲「Connect to PostgreSQL (beta)」のサンプル ○ RNAcentral の「Public Postgres database」に接続 RNAcentral: The non-coding RNA sequence database https://rnacentral.org/help/public-database 9
0. 事前準備 ● 詳細は省略します ○ Cloudflare にサインアップ ○ Node.js 16.13.0 以降と npm・Wrangler をインストール ○ Cloudflare dashboard で Worker を作成 ○ Worker project を TypeScript で作成 ○ node-postgres(pg)8.11.0 以降をインストール ■ npm・yarn などで pg と @types/pg をインストール 10
1. DB 接続用の環境変数をセット ● 秘匿する情報は secret にセット ○ 例) wrangler secret put DB_PASSWORD ● それ以外は wrangler.toml の [vars] に記述 ○ 例) [vars] DB_USERNAME = "postgres" # Set your password by creating a Secret so it is not stored as plain text DB_HOST = "ep-aged-sound-175961.us-east-2.aws.neon.tech" DB_PORT = "5432" DB_NAME = "neondb" 11
1. DB 接続用の環境変数をセット ● 今回は公開情報なので wrangler.toml に DB_URL を記述 name = "pg-test" main = "src/index.ts" compatibility_date = "2023-08-01" # Ensure you enable Node.js compatibility to your project node_compat = true [vars] DB_URL = "postgres://reader:[email protected]:5432/pfmegrnargs" ※今回のサンプルはこちらの GitHub リポジトリにあります https://github.com/hmatsu47/cloudflare-workers-pg-connect 12
2. コードを記述
import { Client } from 'pg';
export interface Env {
DB_URL: string;
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === '/favicon.ico') return new Response(null, { status: 404 });
const client = new Client(env.DB_URL);
await client.connect();
// Query the RNA database!
const result = await client.query({
text: 'SELECT * FROM rnc_database LIMIT 10',
});
console.log(JSON.stringify(result.rows));
const resp = Response.json(result.rows);
// Clean up the client, ensuring we don't kill the worker before that is completed.
ctx.waitUntil(client.end());
return resp;
},
};
13
2. コードを記述
● 個別のパラメーターを指定する場合
○ 例)
// 環境変数取得用interface部分
export interface Env {
DB_USERNAME: string;
DB_PASSWORD: string;
DB_HOST: string;
DB_PORT: number;
DB_NAME: string;
}
// 接続パラメーター指定部分
const client = new Client({
user: env.DB_USERNAME,
password: env.DB_PASSWORD,
host: env.DB_HOST,
port: env.DB_PORT,
database: env.DB_NAME
})
// TLS接続はこちらを参照
// https://developers.cloudflare.com/workers/databases/connect-to-postgres/#ssl-modes
14
3. Cloudflare Workers にデプロイ npx wrangler deploy ⛅ wrangler 3.4.0 -----------------▲ [WARNING] Enabling Node.js compatibility mode for built-ins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details. Your worker has access to the following bindings: - Vars: - DB_URL: "postgres://reader:NWDMCE5xdipIjRrp@hh..." Total Upload: 352.86 KiB / gzip: 70.51 KiB Uploaded pg-test (1.40 sec) Published pg-test (0.40 sec) https://pg-test.【アカウント名】.workers.dev ←デプロイ先のURL Current Deployment ID: ********-****-****-****-************ 15
4. 動作確認
curl 【デプロイ先のURL】 | jq
% Total
% Received % Xferd
100
[
{
3116
100
3116
0
0
Average Speed
Time
Dload Upload
Total
766
0 0:00:04
Time
Time Current
Spent
Left Speed
0:00:04 --:--:-780
"id": "5",
"timestamp": "2017-05-17T00:00:00.000Z",
"userstamp": "RNACEN",
"descr": "VEGA",
"current_release": 98,
"full_descr": "VEGA",
"alive": "N",
"for_release": null,
"display_name": "VEGA",
"project_id": "PRJEB4568",
"avg_length": null,
"min_length": null,
"max_length": null,
"num_sequences": "0",
"num_organisms": "0"
},
(後略)
16
デモ(時間があれば) ● SQL 文を書き換えて再デプロイしてみます 17
注意事項 ● Cloudflare Workers には実行時間制限がある ○ 無料プラン(リクエストあたり)CPU 時間:10 ミリ秒 ○ 有料プラン(同上)実時間:30 秒 ■ CPU 時間≠実時間(実際の実行時間) ■ CPU 時間に DB からのレスポンス待ち 時間は含まない模様 https://www.cloudflare.com/ja-jp/plans/developer-platform/ 18
注意事項 ● 処理が遅いとエッジロケーションで実行する意味がない ○ おそらく DB から取得したデータをキャッシュすることになる? ■ KV や Durable Objects に入れる? ■ ものによっては D1(エッジロケーションの分散 SQLite)に入れる? https://www.publickey1.jp/blog/23/cloudflaresqlitecloudflare_d110.html ● DB のアクセス許可範囲を正しく設定する ○ DB をパブリック IP アドレスで公開する必要があるので 19
まとめ ● Cloudflare Workers:エッジロケーション JS 実行環境 ● Cloudflare Workers が connect()API を実装 ● PostgreSQL への接続がサポートされたのでやってみた ● Workers には実行時間制限がある点に注意 ● データ取得後のキャッシュ戦略が重要になりそう ● DB のセキュリティ設定に気を付けるべし 20