Redis は、高速な読み取りおよび書き込み速度、一定レベルの永続性、および豊富なデータ型をサポートするという利点を備えた、高性能のインメモリ データベースです。 Redis は、キャッシュ、メッセージ キュー、リアルタイム ランキングなどのシナリオでよく使用されます。開発中、電子メールの送信、一時ファイルのクリーニング、キャッシュの更新など、分散スケジュールされたタスクを実装する必要がある場合があります。この記事では、Redis を使用して分散スケジュールされたタスクを実装する方法を紹介します。
1. Redis でサポートされるデータ型
Redis でサポートされるデータ型には、文字列、ハッシュ、リスト、セット、順序付きセットが含まれます。分散スケジュールされたタスクを実装するときは、主に順序付きセットとリストという 2 つのデータ タイプに焦点を当てます。
順序付きセットは、Redis によって提供されるデータ型です。ハッシュ テーブルに似ており、キーと値のペアを格納できますが、値 (スコアと呼ばれる) は反復可能であり、各値は並べ替えに使用されるスコアに関連付けられています。順序付きセット内の要素は、スコアに基づいて小さいものから大きいものへと並べ替えられます。
順序付きセットを使用して分散スケジュールされたタスクを実装する場合、タスクの実行時間をスコアとして、タスクの内容を値として使用し、各タスクを順序付きセットに保存できます。
List は Redis が提供するデータ型で、配列に似ており、リストの先頭または末尾に要素を追加または削除できます。 Redis は、lpush、rpush、lpop、rpop などのコマンドの豊富なリストを提供します。
リストを使用して分散スケジュールされたタスクを実装する場合、タスクの内容をリストに保存し、lpop コマンドを使用して実行するタスクを取得できます。
2. 分散スケジュール タスクを実装する手順
分散スケジュール タスクの実装は、次の手順に大別できます:
次のコマンドを使用して、順序付きコレクションにタスクを追加します:
ZADD タスクのタイムスタンプの内容
Amongそれら、tasks は順序付けられたコレクションの名前、timestamp はタスクの実行時間 (Unix タイムスタンプ)、content はタスクの内容です。
たとえば、タスク「メールの送信」を順序付きコレクションに追加するには、実行時間が 10 分になった後、次のコマンドを使用できます。
ZADD タスク $(date -d " 10 minutes " %s) "send email"
バックグラウンド プロセスを開始し、次のコマンドを使用して必要なすべてのデータを取得します順序付きコレクションのタスク 実行されたタスク:
ZRANGEBYSCORE タスク -inf $(date %s) WITHSCORES
ここで、-inf は順序付きセットの最小値を表し、$(date %s) は現在の時刻のタイムスタンプの Unix。
上記のコマンドは、スコアを含むリストを返します。例:
1) "clear temp files"
2) "1626387489"
その中には、" 「一時ファイルのクリア」はタスクの内容、「1626387489」はタスクの実行時間です。
実行する必要のあるタスクをすべて取得したら、これらのタスクをタスク リストに追加します。
複数のワーカー プロセスを開始し、タスク リストからタスクをポップアップして実行します。実行後、タスクは順序付きセットから削除されます。
次のコマンドを使用して、リストからタスクをポップし、実行します。
lpop task
ここで、tasks はリストの名前です。
ZREM タスクのコンテンツ
このうち、タスクは順序付けられたコレクションの名前、コンテンツはタスクの内容です。
3. コードの実装
以下では、PHP を使用して上記の手順を実装します。
順序付きコレクションにタスクを追加する$redis = new Redis(); $redis->connect('127.0.0.1', 6379); // 添加任务到有序集合 $timestamp = strtotime("+10 minutes"); $redis->zAdd('tasks', $timestamp, 'send email');
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); }
タスクの実行
$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); } } }
以上がRedis を使用して分散スケジュールされたタスクを PHP に実装するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。