著者は、 Write for DOnations プログラムの一環として、 Girls WhoCodeを選択して寄付を受け取りました。

序章

Redis(リモートディクショナリサーバー)は、高速なオープンソースのインメモリデータベースであり、高度にスケーラブルでパフォーマンス指向のシステムのキーバリューストアとして使用できます。 Redisのユースケースには、キャッシング、高速トランザクション、リアルタイム分析、ライブ通知、機械学習、検索、キュー/ジョブ処理などがあります。 Redisはメモリ内のKey-Valueストアであるため、そのパフォーマンスにより、アプリケーションでデータをキャッシュするのに適しています。

Caching は、データを一時的に高速ストレージレイヤー(たとえば、コンピューターのRAM)に保存して、クライアントが同じ将来の要求を行ったときにデータをより高速に提供します。 これにより、ディスクから毎回データをフェッチするのではなく、以前に計算されたデータの再利用が強化されます。

PHPおよびMySQLを使用している場合、Redisはハードディスク(HDD)の数倍の速度でデータをRAMに保存するため、キャッシュとしてRedisを使用するとアプリケーションのパフォーマンスが向上します。またはソリッドステートドライブ(SSD)。 キャッシュはまた、データベースのコスト(つまり、バックエンドデータベースに対して行われるラウンドトリップの数)を削減し、バックエンドの過負荷を回避します。

データのキャッシュは、書き込みよりも読み取りが多いWebアプリケーションを設計する場合に不可欠な設計機能です。 このようなアプリケーションには、ブログ、オンラインストア、ソーシャルメディアサイトが含まれます。

このチュートリアルでは、Redisを使用して、Ubuntu20.04でPHPを使用してMySQLデータをキャッシュします。

前提条件

このチュートリアルを完了するには、次のものが必要です。

ステップ1—PHP用のRedisライブラリをインストールする

まず、php-redis拡張機能をインストールします。これにより、PHPを使用してRedisと通信できるようになります。 次のコマンドを実行してサーバーを更新し、拡張機能をインストールします。

  1. sudo apt update
  2. sudo apt install php-redis

インストールを確認し、Apache Webサーバーを再起動して、拡張機能をロードします。

  1. sudo systemctl restart apache2

依存関係をインストールしたので、データベースをセットアップします。

ステップ2—テストデータベース、テーブル、およびサンプルデータを設定する

このステップでは、データを永続的にディスクに保存するためのMySQLデータベースを作成します。 また、データベースに対する完全な権限を持ついくつかのテーブルとユーザーアカウントを作成します。

まず、rootユーザーとしてMySQLサーバーにログインします。

  1. sudo mysql -u root -p

LAMP前提条件で設定したMySQLサーバーのrootパスワードを入力します。 次に、ENTERを押して続行します。

次に、次のコマンドを使用してtest_storeデータベースを作成します。

  1. CREATE database test_store;

出力を確認して、アクションが成功したことを確認します。

Output
Query OK, 1 row affected (0.00 sec)

次に、データベースのユーザーを作成します。 このチュートリアルでは、このユーザーをtest_userと呼びます。 PASSWORDも強力なパスワードに置き換えます。

  1. CREATE USER 'test_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'PASSWORD';

次に、test_usertest_storeデータベースへの完全な権限を次のように付与します。

  1. GRANT ALL PRIVILEGES ON test_store.* TO 'test_user'@'localhost';

最後に、次のコマンドを実行して、MySQLで許可テーブルを再ロードします。

  1. FLUSH PRIVILEGES;

コマンドが成功するたびに、次の出力が得られることを確認してください。

Output
Query OK, 0 rows affected (0.01 sec)

MySQLルートセッションを終了します。

  1. quit;

Byeという単語が表示され、サーバーのコマンドラインインターフェイスに戻ります。

作成したtest_userの資格情報を使用してMySQLサーバーに再度ログインします。

  1. mysql -u test_user -p

test_userのパスワードを入力して続行します。 次に、mysql>プロンプトが表示されたら、test_storeデータベースに切り替えます。

  1. USE test_store;

次の出力が表示されることを確認してください。

Output
Database Changed.

次に、3列のproductsテーブルを作成します。 product_id列を使用して、各製品を一意に識別します。 IDを手動で割り当てないようにするには、AUTO_INCREMENTキーワードを使用します。 次に、product_id列のBIGINTデータ型を使用して、大きなデータセットをサポートします。 BIGINTデータ型は、最小値-2^63および最大値2^63-1を保持できます。

product_nameフィールドには、アイテムの実際の名前が保持されます。 この場合、50文字の長さのVARCHARデータ型で十分です。 productsテーブルの最後の列はpriceです。DOUBLEデータ型を使用して、小数の価格(たとえば、16.33)に対応します。

productsテーブルを作成するには、次のコマンドを実行します。

  1. CREATE table products
  2. (
  3. product_id BIGINT PRIMARY KEY AUTO_INCREMENT,
  4. product_name VARCHAR(50),
  5. price DOUBLE
  6. ) Engine = InnoDB;

次の出力が表示されます。

Output
Query OK, 0 rows affected (0.01 sec)

次に、テスト用にproductsテーブルにいくつかのレコードを入力します。

AUTO_INCREMENT列がこれを完了するため、product_id列にデータを手動で入力する必要はありません。 次のコマンドを1つずつ実行します。

  1. INSERT INTO products(product_name, price) VALUES ('Virtual Private Servers', '5.00');
  2. INSERT INTO products(product_name, price) VALUES ('Managed Databases', '15.00');
  3. INSERT INTO products(product_name, price) VALUES ('Block Storage', '10.00');
  4. INSERT INTO products(product_name, price) VALUES ('Managed Kubernetes', '60.00');
  5. INSERT INTO products(product_name, price) VALUES ('Load Balancer', '10.00');

各コマンドを実行した後、次の出力が得られることを確認してください。

Output
Query OK, 1 row affected (0.00 sec)

SELECTコマンドを使用してデータを確認します。

  1. SELECT * FROM products;

次のような出力が表示されます。

Output
+------------+-------------------------+-------+ | product_id | product_name | price | +------------+-------------------------+-------+ | 1 | Virtual Private Servers | 5 | | 2 | Managed Databases | 15 | | 3 | Block Storage | 10 | | 4 | Managed Kubernetes | 60 | | 5 | Load Balancer | 10 | +------------+-------------------------+-------+ 5 rows in set (0.00 sec)

test_userのMySQLセッションを終了します。

  1. quit;

test_storeデータベース、productsテーブル、および test_user を設定したら、PHPスクリプトをコーディングして、MySQLデータベースからデータを取得してキャッシュします。 Redis。

ステップ3—MySQLデータをフェッチおよびキャッシュするためのPHPスクリプトを設計する

このステップでは、前のステップで作成したサンプルデータを取得するためのPHPスクリプトを作成します。

スクリプトを初めて実行すると、MySQLから(つまり、ディスクから)データが読み取られ、Redisにキャッシュされます。 その結果、製品のデータの後続の読み取りはRedisから(つまり、システムRAMから)行われます。 システムメモリは最速のソリッドステートドライブよりも数倍高速であるため、データはシステムディスクから読み取るよりもRedisキャッシュから高速に取得されます。

注:パフォーマンスは向上しない可能性がありますが、MySQLデータベースから取得するレコードはわずかであるため、いくつかのベンチマークでは、Redisからキャッシュされたデータを取得する方が、処理時にMySQLから読み取るよりも数倍高速であることが証明されています。数十万のレコードがあります。

Webサイトのルートディレクトリにproducts.phpファイルを作成します。

  1. sudo nano /var/www/html/products.php

まず、次の情報を入力してRedisのインスタンスを接続して作成し、オブジェクトとして$redis変数に保存します。

アドレス127.0.0.1localhostに接続します。 リモートサーバーからRedisを実行している場合は、この値を変更できます。 REDIS_PASSWORDを、/etc/redis/redis.conf構成ファイルで設定されたRedisの特定のパスワードに置き換えることを忘れないでください。

また、適切なポート番号を入力します。 デフォルトでは、Redisはポート6379で実行されます。

/var/www/html/products.php
<?php

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('REDIS_PASSWORD');

注:このガイドでは、$redis->auth('REDIS_PASSWORD')コマンドがパスワードをプレーンテキストでRedisに送信します。 実稼働環境では、 TLS(Transport Layer Security)などのより強力なアクセス制御レイヤーを使用して、RedisとPHPコードを実行しているクライアントサーバー間のエンドツーエンド通信を保護することを検討できます。 また、/etc/redis/redis.confファイルでRedisパスワードを設定するときは、ブルートフォース攻撃を防ぐために、長くて強い値を設定してください。

次のステップは、Redisでキーとして使用するPHP変数を初期化することです。

このガイドで前述したように、Redisはキー値データベースとして機能するため、保存および取得するデータに対して一意のキーが必要です。

したがって、/var/www/html/products.phpファイルに次の情報を追加して、PRODUCTSキーを定義します。 PRODUCTSキーの代わりに任意の名前を自由に使用できます。

データがMySQLデータベースから取得されると、PHPスクリプトはこのキーを使用して情報をRedisにキャッシュします。

/var/www/html/products.php
...
$key = 'PRODUCTS';

次に、条件付きPHP if...elseステートメントを含めて、PRODUCTSキーがRedisに存在するかどうかを確認します。

/var/www/html/products.php
...
if (!$redis->get($key)) {
    $source = 'MySQL Server';
    $database_name     = 'test_store';
    $database_user     = 'test_user';
    $database_password = 'PASSWORD';
    $mysql_host        = 'localhost';

    $pdo = new PDO('mysql:host=' . $mysql_host . '; dbname=' . $database_name, $database_user, $database_password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql  = "SELECT * FROM products";
    $stmt = $pdo->prepare($sql);
    $stmt->execute();

    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
       $products[] = $row;
    }

    $redis->set($key, serialize($products));
    $redis->expire($key, 10);

} else {
     $source = 'Redis Server';
     $products = unserialize($redis->get($key));

}

echo $source . ': <br>';
print_r($products);

キーがRedisに存在しない場合、スクリプトは前に作成したデータベースに接続し、productsテーブルにクエリを実行し、$redis->set($key, serialize($products))コマンドを使用してデータをRedisに保存します。

$redis->expire($key, 10);コマンドは、有効期限を10秒に設定します。 キャッシュポリシーに応じて、この値を微調整できます。

$source変数は、echo $sourceおよびprint_r($products)コマンドを使用して、スクリプトの最後に配列としてエコーされたデータのソースを識別するのに役立ちます。

すべてをまとめると、/var/www/html/products.phpファイルは次のようになります。

/var/www/html/products.php
<?php

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('REDIS_PASSWORD');

$key = 'PRODUCTS';

if (!$redis->get($key)) {
    $source = 'MySQL Server';
    $database_name     = 'test_store';
    $database_user     = 'test_user';
    $database_password = 'PASSWORD';
    $mysql_host        = 'localhost';

    $pdo = new PDO('mysql:host=' . $mysql_host . '; dbname=' . $database_name, $database_user, $database_password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql  = "SELECT * FROM products";
    $stmt = $pdo->prepare($sql);
    $stmt->execute();

    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
       $products[] = $row;
    }

    $redis->set($key, serialize($products));
    $redis->expire($key, 10);

} else {
     $source = 'Redis Server';
     $products = unserialize($redis->get($key));

}

echo $source . ': <br>';
print_r($products);

ファイルを保存して閉じます。

これで、MySQLに接続してデータをRedisにキャッシュするPHPスクリプトを設定しました。 次のステップでスクリプトをテストします。

ステップ4—PHPスクリプトをテストする

RedisがMySQLデータベースからデータをキャッシュしているかどうかをテストするには、ブラウザウィンドウにPHPスクリプトのパスを入力します。 your_server_IPは、http://your_server_IP/products.phpのように、サーバーのパブリックIPアドレスに置き換えることを忘れないでください。

スクリプトを初めて実行すると、MySQLデータベースからのデータを表示する次の出力が表示されます。この時点では、PHPスクリプトはまだRedisにデータをキャッシュしていないためです。

MySQL Server
Array ( [0] => Array ( [product_id] => 1 [product_name] => Virtual Private Servers [price] => 5 ) [1] => Array ( [product_id] => 2 [product_name] => Managed Databases [price] => 15 ) [2] => Array ( [product_id] => 3 [product_name] => Block Storage [price] => 10 ) [3] => Array ( [product_id] => 4 [product_name] => Managed Kubernetes [price] => 60 ) [4] => Array ( [product_id] => 5 [product_name] => Load Balancer [price] => 10 ) )

スクリプトを再度実行すると、MySQLのキャッシュとして機能しているRedisからデータを読み取っていることを確認する出力が表示されます。

Redis Server
Array ( [0] => Array ( [product_id] => 1 [product_name] => Virtual Private Servers [price] => 5 ) [1] => Array ( [product_id] => 2 [product_name] => Managed Databases [price] => 15 ) [2] => Array ( [product_id] => 3 [product_name] => Block Storage [price] => 10 ) [3] => Array ( [product_id] => 4 [product_name] => Managed Kubernetes [price] => 60 ) [4] => Array ( [product_id] => 5 [product_name] => Load Balancer [price] => 10 ) )

キーは10秒後に期限切れになり、データはMySQLから再度取得されることに注意してください。

結論

このガイドでは、Redisを使用してUbuntu20.04でPHPを使用してMySQLデータをキャッシュしました。 このガイドのコーディングを使用して、MySQLデータのキャッシュメカニズムを設定できます。これは、トラフィックの多いWebアプリケーションで特に役立ちます。

その他の教育リソースについては、Redisトピックページをご覧ください。 または、 PHPトピックページのチュートリアルとコンテンツを使用して、PHPでのコーディングの詳細を確認してください。