ホームページ >バックエンド開発 >PHPチュートリアル >Redis を使用して分散スケジュールされたタスクを PHP に実装する

Redis を使用して分散スケジュールされたタスクを PHP に実装する

王林
王林オリジナル
2023-05-15 14:01:361130ブラウズ

Redis は、高速な読み取りおよび書き込み速度、一定レベルの永続性、および豊富なデータ型をサポートするという利点を備えた、高性能のインメモリ データベースです。 Redis は、キャッシュ、メッセージ キュー、リアルタイム ランキングなどのシナリオでよく使用されます。開発中、電子メールの送信、一時ファイルのクリーニング、キャッシュの更新など、分散スケジュールされたタスクを実装する必要がある場合があります。この記事では、Redis を使用して分散スケジュールされたタスクを実装する方法を紹介します。

1. Redis でサポートされるデータ型

Redis でサポートされるデータ型には、文字列、ハッシュ、リスト、セット、順序付きセットが含まれます。分散スケジュールされたタスクを実装するときは、主に順序付きセットとリストという 2 つのデータ タイプに焦点を当てます。

  1. 順序付きセット

順序付きセットは、Redis によって提供されるデータ型です。ハッシュ テーブルに似ており、キーと値のペアを格納できますが、値 (スコアと呼ばれる) は反復可能であり、各値は並べ替えに使用されるスコアに関連付けられています。順序付きセット内の要素は、スコアに基づいて小さいものから大きいものへと並べ替えられます。

順序付きセットを使用して分散スケジュールされたタスクを実装する場合、タスクの実行時間をスコアとして、タスクの内容を値として使用し、各タスクを順序付きセットに保存できます。

  1. List

List は Redis が提供するデータ型で、配列に似ており、リストの先頭または末尾に要素を追加または削除できます。 Redis は、lpush、rpush、lpop、rpop などのコマンドの豊富なリストを提供します。

リストを使用して分散スケジュールされたタスクを実装する場合、タスクの内容をリストに保存し、lpop コマンドを使用して実行するタスクを取得できます。

2. 分散スケジュール タスクを実装する手順

分散スケジュール タスクの実装は、次の手順に大別できます:

  1. タスクを順序付きリスト コレクションに追加し、タスクの実行時間をスコアとして設定します。
  2. バックグラウンド プロセスを開始して、順序付けされたコレクション内のタスクをスキャンし、タスクを実行する必要があるかどうかを判断し、実行する必要があるタスクをタスク リストに追加します。
  3. 複数のワーカー プロセスを開始し、タスク リストからタスクをポップして実行します。
  4. 実行後、順序付きセットからタスクを削除します。
  5. 順序付きコレクションにタスクを追加する

次のコマンドを使用して、順序付きコレクションにタスクを追加します:

ZADD タスクのタイムスタンプの内容

Amongそれら、tasks は順序付けられたコレクションの名前、timestamp はタスクの実行時間 (Unix タイムスタンプ)、content はタスクの内容です。

たとえば、タスク「メールの送信」を順序付きコレクションに追加するには、実行時間が 10 分になった後、次のコマンドを使用できます。

ZADD タスク $(date -d " 10 minutes " %s) "send email"

  1. 順序付けられたコレクション内のタスクをスキャンします

バックグラウンド プロセスを開始し、次のコマンドを使用して必要なすべてのデータを取得します順序付きコレクションのタスク 実行されたタスク:

ZRANGEBYSCORE タスク -inf $(date %s) WITHSCORES

ここで、-inf は順序付きセットの最小値を表し、$(date %s) は現在の時刻のタイムスタンプの Unix。

上記のコマンドは、スコアを含むリストを返します。例:

1) "clear temp files"
2) "1626387489"

その中には、" 「一時ファイルのクリア」はタスクの内容、「1626387489」はタスクの実行時間です。

実行する必要のあるタスクをすべて取得したら、これらのタスクをタスク リストに追加します。

  1. タスクの実行

複数のワーカー プロセスを開始し、タスク リストからタスクをポップアップして実行します。実行後、タスクは順序付きセットから削除されます。

次のコマンドを使用して、リストからタスクをポップし、実行します。

lpop task

ここで、tasks はリストの名前です。

    #順序付きセットからタスクを削除します
  1. #タスクの実行後、次のコマンドを使用して順序付きセットからタスクを削除します:

ZREM タスクのコンテンツ

このうち、タスクは順序付けられたコレクションの名前、コンテンツはタスクの内容です。

3. コードの実装

以下では、PHP を使用して上記の手順を実装します。

順序付きコレクションにタスクを追加する
  1. 次のコードを使用して、順序付きコレクションにタスクを追加します:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// 添加任务到有序集合
$timestamp = strtotime("+10 minutes");
$redis->zAdd('tasks', $timestamp, 'send email');

タスクのスキャン順序付きコレクション内で
  1. #次のコードを使用して、順序付きコレクション内のタスクをスキャンし、実行する必要があるタスクをタスク リストに追加します:
  2. while(true) {
        // 扫描有序集合中的任务
        $scoreTasks = $redis->zRangeByScore('tasks', '-inf', time(), array('withscores' => true));
        foreach($scoreTasks as $task => $score) {
            // 将需要执行的任务添加到任务列表中
            $redis->lpush('task_list', $task);
            // 将任务从有序集合中删除
            $redis->zRem('tasks', $task);
        }
        // 每隔5秒扫描一次
        sleep(5);
    }

タスクの実行

  1. 次のコードを使用して複数のワーカー プロセスを開始し、タスク リストからタスクをポップアップして実行します:
  2. $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);
    
    for($i=0; $i<10; $i++) {
        // 启动10个Worker进程
        $pid = pcntl_fork();
        if($pid == -1) {
            echo 'fork error!' . PHP_EOL;
            exit;
        } else if($pid == 0) {
            // 子进程中获取任务列表中的任务并执行
            while(true) {
                // 从列表中弹出一条任务
                $task = $redis->rpop('task_list');
                if(empty($task)) {
                    continue;
                }
                // 执行任务
                mail('user@example.com', 'Task', $task);
            }
        }
    }
4. 概要

上記は Redis を使用して実装されています分散スケジュールされたタスクの手順とコードの実装。 Redisを利用すると分散タスクスケジューリングを簡単に実装でき、タスクの同時処理能力や実行効率を向上させることができます。実際のアプリケーションでは、ロックを利用してタスクリストを相互に排他的にアクセスしたり、タイマーを利用して定期的にタスクを取得したりするなど、実情に応じてコードを最適化する必要があります。

以上がRedis を使用して分散スケジュールされたタスクを PHP に実装するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。