Redis
 Computer >> コンピューター >  >> プログラミング >> Redis

CloudflareとUpstash Redisで実現する、Remixによる爆速Webサイト構築ガイド

WebサイトやWebアプリを開発するとき、速度の最適化だけで何時間も費やしたい人はいませんよね。しかし問題は、高速なWebサイトが非常に重要であり、パフォーマンスがその成功を左右する決定的な要素になりがちだという点です。

Remix RunのようなWebフレームワークは、設定を最小限に抑えながら(いわゆる「ゼロコンフィグ」)Webパフォーマンスを最適化することを目標に生まれました。現在では、高速化を実現するためのフレームワークが数多く存在します。

残念ながら、どれほど優れたサイトの読み込み時間を実現しても、アプリ側のデータベースが高速でなければ意味がありません。

この記事では、優れたWebサイトの読み込み速度を実現し、それをUpstash Redis Global Databasesの最高峰のデータベースパフォーマンスと組み合わせる方法を解説します。

なぜGlobal Databasesなのか?

ほとんどの人は、Webサイトを公開する際にCDN(Content Delivery Network)を利用します。CDNは世界中に分散したサーバーのグローバルネットワークです。Webサイトのファイルをキャッシュして、クライアントから地理的に最も近い場所から配信できるため、単一サーバーシステムよりも大幅に低いレイテンシを実現できます。これにより、世界中どこでもWebサイトが高速に読み込まれるようになります。

UpstashのGlobal Databasesでは、このCDNと同じ概念がRedisデータベースに適用されます。Global Databasesでは、データベースのレプリカが世界各地の複数リージョンに分散配置され、クライアントは最寄りのリージョンへルーティングされるため、10ms未満のレイテンシを体験できます。

はじめに

それでは、実際にどのように動作するのかを見ていきましょう。

構築するもの

今回は、Upstash Redis Global Databasesを使用するRemix Run製のWebアプリを構築し、Cloudflare Workersにデプロイします。

Cloudflare Workersは、CDNと同様にグローバルにデプロイされるという利点があります。つまり、Remixアプリのサーバーサイドレンダリングがクライアントのできるだけ近くで行われ、レイテンシが最小限に抑えられます。UpstashのGlobal Databasesと組み合わせることで、パフォーマンス面で理想的な構成になります。

Remixのセットアップ

任意のフォルダに移動して、以下のコマンドを実行してください。

npx create-remix@latest

対話形式のダイアログが表示され、Remix Runアプリのセットアップを進められます。

デプロイターゲットとして必ずCloudflare Workersを選択してください。このチュートリアルではJavaScriptアプリで進めますが、TypeScriptを選んでも問題ありません。セットアップは以下のようになります。


R E M I X - v1.2.3

💿 Welcome to Remix! Let's get you set up with a new project.

? Where would you like to create your app? upstash-remix
? Where do you want to deploy? Choose Remix if you're unsure, it's easy to change deployment targets. Cloudflare Workers
? TypeScript or JavaScript? JavaScript
? Do you want me to run `npm install`? Yes

インストールが完了したら、新しく作成されたフォルダをコードエディタで開きます。

Upstash Redis Global Databaseの作成

Upstash Redis Global Databaseを作成するには、https://upstash.com/ にアクセスしてログインまたはアカウント登録を行います。コンソールで「Create Database」をクリックし、名前を入力してデータベースタイプとして「Global」を選択します。最後に「Create」を押して、データベースが作成されるのを待ちましょう。

次に、UPSTASH_REDIS_REST_URLUPSTASH_REDIS_REST_TOKENをコピーします。

プロジェクトのルートに.envというファイルを作成し、両方の変数を以下のように追加してください。

UPSTASH_REDIS_REST_TOKEN=<INSERT YOUR UPSTASH_REDIS_REST_TOKEN HERE>
UPSTASH_REDIS_REST_URL=<INSERT YOUR UPSTASH_REDIS_REST_URL HERE>

データベースとやり取りするために、npm install @upstash/redisコマンドで@upstash/redis npmパッケージをインストールしましょう。

Remix Runアプリケーションの作成

データベースの準備ができたら、app/routes/index.jsxファイルを開き、ボイラープレートのコードを削除して、以下のコードを入力します。

import { json, redirect, useLoaderData } from "remix";
import redis from "../utils/redis.server";

export const loader = async () => {
  const start = new Date();
  const count = await redis.get("counter");
  return json({ count, loadingTime: new Date() - start });
};

export const action = async () => {
  await redis.incr("counter");
  return redirect("/");
};

export default function Index() {
  const { count, loadingTime } = useLoaderData();

  return (
    <div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.4" }}>
      <h1>Record speeds with Remix on Cloudflare and Upstash Redis</h1>
      <p>The button below was clicked {count} times already.</p>
      <form method="post" action="/?index">
        <button type="submit">Click me!</button>
      </form>
      <p>
        It took <b>{loadingTime} ms</b> to read the number of button clicks from{" "}
        <a href="https://upstash.com/redis">Upstash Redis</a>{" "}
        <a href="https://docs.upstash.com/redis/features/globaldatabase">
          Global Database
        </a>
        .
      </p>
    </div>
  );
}

さらに、app/utils/redis.server.jsというファイルを以下の内容で作成します。

// app/utils/redis.server.js

import { Redis } from "@upstash/redis/cloudflare";

export default Redis.fromEnv();

このコードには2つの重要なポイントがあります。順番に見ていきましょう。

1. useLoaderDataによるサーバーサイドレンダリング

一番下のreturnステートメントには、次の要素を表示するシンプルなユーザーインターフェースがあります。

  • countというカウンター変数
  • loadingTimeという変数

少し上のコードを見ると、これら2つの変数はuseLoaderData()フックから取得されていることがわかります。このRemix Run固有のフックは、上部にあるloader関数と組み合わせて使用されます。

loader関数内では、データベースからcounterキーを読み取り、その所要時間を計測して、両方の値をuseLoaderData()関数に返します。

loader関数はRemix Runアプリがロードされるたびに実行されるため、誰かがWebサイトにアクセスするたびに、現在のcounter値を読み取り、サーバーサイドでページをレンダリングしてクライアントに返す仕組みになっています。

2. 「Click me!」ボタンクリック時のカウンター増加処理

Remix Runを使うと、フォームを非常に簡単に構築できます。JSXの中にある<form/>タグは、送信ボタンがクリックされると/?indexに対してPOSTリクエストを送信します。Remix Runの素晴らしいところは、ファイルにaction関数を追加するだけで、APIを明示的に作成することなくフロントエンドとバックエンドの連携が完成する点です。

action関数では、単純にカウンターをインクリメントし、変更を反映させるためにクライアントにページの再読み込みを指示しています。

🥳 これで準備完了です

ローカルでの実行

ここで、作成したものを確認したくなるでしょう。npm run devを実行して、ブラウザでアプリを表示してみてください。

  1. 「Click me!」ボタンをクリックして、カウントが増えることを確認します。
  2. 計測されたローディング時間をチェックします。ドイツからの場合、通常20ms未満のレイテンシが見られますが、Cloudflareにデプロイすればさらに半分になることを期待してください。

Cloudflareへのデプロイ

それでは、Cloudflareでフルスピードを目指し、一桁ミリ秒のレイテンシを実現しましょう!

まず、まだインストールしていない場合は、ドキュメントの手順に従ってCloudflare Workers CLI「Wrangler」をインストールしてください: https://developers.cloudflare.com/workers/cli-wrangler/install-update/ 。CLIの認証も忘れずに行ってください。

アカウントをお持ちでない場合は、こちらでCloudflareアカウントを作成し、メールアドレスの認証が完了したら、ダッシュボードに移動して無料のCloudflare Workersサブドメインを設定します。

.envに設定したシークレットを、以下のコマンドでCloudflareにも設定するのを忘れないでください。

wrangler secret put UPSTASH_REDIS_REST_TOKEN
...

wrangler secret put UPSTASH_REDIS_REST_URL
...

これらが完了したら、アプリをデプロイできます。

npm run deploy

Wranglerがデプロイ完了後にアプリへのリンクを提供してくれるので、開いてアプリがどれほど速いか体感してみてください。

サンプルデプロイはこちらで確認できます: https://remix-cloudflare-workers.soenkep.workers.dev/

完全なコード(環境変数を除く)はこちらで参照できます: https://github.com/zunkelty/upstash-remix-run

  1. エッジキャッシングで実現する、世界どこでも5ミリ秒のRedisレイテンシ

    Redisでは、データベースとクライアントが同じリージョン内にあれば、1ミリ秒のレイテンシは容易に実現できます。しかし、クライアントが世界中に分散している場合、レイテンシは100ミリ秒を超えてしまいます。この課題を解決するために開発されたのが「Edge Caching(エッジキャッシング)」です。 エッジキャッシングとは エッジキャッシングでは、CDNと同じようにREST APIのレスポンスが世界各地のエッジロケーションにキャッシュされます。エッジキャッシングを有効にすると、平均5ミリ秒というグローバルレイテンシを実現できます。実際に、10の異なるリージョンに配置したクライアントからレイテンシ

  2. Cloudflare WorkersとRedisで実現するエッジコンピューティング活用術

    エッジコンピューティングは、近年もっとも注目されている技術のひとつです。CDNがファイルをユーザーの近くに配置できるようにしたのと同じように、エッジコンピューティングはアプリケーションそのものをユーザーの近くで実行できるようにします。これにより、開発者はグローバルに分散され、高いパフォーマンスを発揮するアプリケーションを構築できるようになります。 Cloudflare Workersとステートレス性の課題 現在この分野をリードしている製品がCloudflare Workersです。コールドスタートのないサーバーレス実行環境を提供し、Cloudflareのグローバルネットワークを活かすことで、ア