0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WordPress を Cloudflare Workers で動かしてわかったこと

0
Posted at

「WordPress は Cloudflare で動くか」という質問には、これまで「動かない」と答えるのが普通でした。Workers が実行できるのは JavaScript と WebAssembly で、WordPress には PHP と MySQL が要るからです。静的ファイルに書き出すか、サーバーを残すかの二択でした。

いまはこの答えが変わっています。WordPress Playground プロジェクトが PHP を WebAssembly 向けにビルドしていて(php-wasm)、そのビルドは Worker の中でも動きます。

私たちは、これを使って既存の WordPress サイトを Workers に移すオープンソースのツール HostlessWP(GPL-2.0)をメンテナンスしています。npx hostlesswp を実行すると、wp-config.php を読み取り、WordPress 本体・テーマ・プラグインを php-wasm(PHP 8.3)で動かし、既存の MySQL には Hyperdrive 経由で接続し、メディアライブラリは R2 などの S3 互換ストレージに置きます。以下は、実用になるかどうかを左右したポイントと、実際に測った数字です。

1. いちばん効くのは Worker を置く場所

WordPress はクエリを一つずつ順番に発行します。今回のテストでは、コアのトップページで 29 回、WooCommerce のトップページで 74 回でした。そのたびにデータベースまでの往復を待つことになります。

データベースは米国東部(バージニア)、リクエストはシンガポールから Cloudflare に入る条件で測りました。デフォルトの配置では Worker が訪問者の近くで動くので、クエリのたびに太平洋を往復します。

構成 1 クエリ コアのトップページ WooCommerce のトップページ
訪問者の近く(シンガポール)で実行 約 230 ms 7.7 秒 19.6 秒
データベースの隣で実行(placement.region = "aws:us-east-1") 約 33 ms 1.2〜1.3 秒 2.9〜3.2 秒
データベースの隣で、Hyperdrive を使わず直接 TCP 接続(未リリース) 約 2 ms 0.07 秒 0.19 秒

ウォーム状態のリクエストで、データベースの待ち時間を含む PHP の処理時間です。各セルは 1〜5 サンプルの中央値なので、桁の目安として読んでください。Worker をデータベースの隣に固定するとページは約 6 倍速くなりました。そのため HostlessWP はデータベースの場所を調べて placement.region を自動で設定します。

ログインしていない訪問者には Workers KV のページキャッシュから返すので、PHP もデータベースも動きません。上の数字が効いてくるのは、ログインユーザー、管理画面、キャッシュされないページです。

2. Hyperdrive は 1 クエリあたり約 30 ms 増え、セッションを保持しない

同じ Worker の呼び出しの中で、直接接続の SELECT 1 は約 2 ms、接続の確立は 2〜7 ms でした。Hyperdrive 経由では約 33 ms です。その差のうち、どこまでが Hyperdrive のプールまでの距離で、どこまでが処理そのものなのかは切り分けられていません。直接接続をまだリリースしていないのは、テスト用データベースがプライベート CA の証明書を使っていて、Workers の TLS クライアントが受け付けなかったためです。

見落としやすいのは、Hyperdrive が連続するステートメントを別々のサーバー接続で実行しうる点です。WordPress やプラグインが SET で設定したセッション変数は、次のクエリでは消えているかもしれません。私たちは SET_VAR ヒントでステートメントごとに状態を渡し、SELECT @@var には SHOW VARIABLES の結果で答え、SQL_CALC_FOUND_ROWS のページングは COUNT を並列に実行する形に変えました。この最後の変更で、REST API の投稿一覧は約 2.5 秒から 1.6 秒になりました。

3. 計算中は時計が進まない

Workers では CPU 処理の間、時計が止まります。時刻が変わるまでループする PHP のコード(たとえば uniqid())は終わらなくなります。読み出すたびに必ず少し先の時刻を返す、単調増加の時計にすることで解決しました。

4. php-wasm の OPcache は明示的に有効にしないと動かない

php-wasm の SAPI は OPcache のホワイトリストに入っていないため、デフォルトでは OPcache が起動しません。これをパッチで有効にし、共有メモリに置き、事前コンパイルしたスクリプトをマウントすると、WordPress と WooCommerce くらいの規模のコードでは大きな差が出ます。

5. まだできないこと

  • PHP の mail()。HTTP API で送信するメールプラグインを使ってください。
  • 管理画面からのプラグインのインストールや更新。元のサイトで変更してから再デプロイします。
  • マルチサイト。
  • Redis などのオブジェクトキャッシュのドロップインは除外されます(WordPress 標準のキャッシュを使います)。
  • Imagick。画像処理は GD で行います。
  • データベースの隣に配置すると、コールドスタートが増えました(連続 25 リクエスト中 11〜16 回。デフォルト配置では 0 回)。原因はまだわかっていません。

WordPress.org でインストール数の多い上位 30 プラグインはページ単位で読み込みと動作を確認し、WooCommerce のチェックアウト、Elementor のエディタ、Yoast のサイトマップはエンドツーエンドでテストしました。プラグインごとの結果は互換性一覧にあります。

試すには

npx hostlesswp check   # 読み取りのみの互換性レポート。何も変更しません
npx hostlesswp         # 対話式のセットアップとデプロイ

今のサイトには手を加えないので、ドメインを切り替えるまでは今まで通り配信されます。この方式で動いている WooCommerce の公開デモがあります: https://hostlesswp-demo.qc2uyes.workers.dev (demo / demo でログイン、3 時間ごとにリセット)。測定方法と数字の詳細: https://hostlesswp.com/benchmarks

まだ初期プレビュー(v0.1)です。ご自身のサイトで試したら、ぜひ数字を教えてください。

0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?