オンライン人数カウント ビジネスは、Web 開発時に設計する必要があるビジネス ロジックです。この記事では、各ソリューションの長所と短所を分析するためにいくつかの設計ソリューションを示します:
Use Ordered set
このソリューションは、オンライン ユーザーとユーザーのオンライン時間を同時に保存し、多くの集計計算を実行できますが、消費されるメモリも非常に多くなります。
セットを使用する
このソリューションでは、オンライン ユーザーを保存でき、特定の集計計算も実行できます。順序付きセットと比較して、メモリの消費量が少なくなります。は小さくなりますが、ユーザー数が増加するにつれて、消費されるメモリ領域も増加します
ハイパーログログを使用します
このソリューションはユーザー数に関係なく、オンライン ユーザーはカウントされ、消費されるメモリは 12k ですが、提供できるのはオンライン ユーザーの統計情報のみであり、オンライン ユーザーの正確なリストは取得できません
ビットマップを使用してください
このソリューションはまだ比較的優れています。メモリ領域を可能な限り節約しながらオンライン ユーザーのステータスを記録し、特定の集計操作を実行できます。
以下の実践的な例を使用してみましょう注:
# 说 まず、毎日 10 ~ 30 W の少数のユーザーがおり、100 W のユーザー グループは次のスキームを示します
# #Q :順序付きセットを使用します
最初にユーザーのオンライン記録データを生成します:$start_time = mktime(0, 0, 0, 9, 5); //monday for ($i=0; $i < 6; $i++) { $day_start_time = $start_time + 86400 * $i; //every day begin time $day_end_time = $day_start_time + 86400; //every day end time $online_user_num = mt_rand(100000, 300000); //online user between 100000 and 300000 for ($j=1; $j < $online_user_num; $j++) { $user_id = mt_rand(1, 1000000); $redis->zadd('000|online_users_day_'.$i, mt_rand($day_start_time, $day_end_time), $user_id); } }
//note: 统计每天的在线总人数 for ($i=0; $i < 6; $i++) { print_r($redis->zsize('000|online_users_day_'.$i). "\n"); } //note: 统计最近6天都在线的人数 var_dump($redis->zInter('000|online_users_day_both_6', [ '000|online_users_day_0', '000|online_users_day_1', '000|online_users_day_2', '000|online_users_day_3', '000|online_users_day_4', '000|online_users_day_5' ] )); //note: 统计出近6天中共有多少上线 $redis->zunion('000|online_users_day_total_6', ['000|online_users_day_0', '000|online_users_day_1', '000|online_users_day_2', '000|online_users_day_3', '000|online_users_day_4', '000|online_users_day_5']); //note: 统计某个时间段总共在线用户 print_r($redis->zcount('000|online_users_day_5', mktime(13, 0, 0, 9, 10), mktime(14, 0, 0, 9, 10))); //note: 统计某个时间段在线用户名单 print_r($redis->zrangebyscore('000|online_users_day_5', mktime(13, 0, 0, 9, 10), mktime(14, 0, 0, 9, 10), array('withscores' => TRUE)));
PHP ビデオ チュートリアル]
オプション 2: コレクションを使用する
または まず、ユーザーのためにオンラインでデータを記録しましょう://note set 一般聚合 for ($i=0; $i < 6; $i++) { $online_user_num = mt_rand(100000, 300000); //online user between 100000 and 300000 for ($j=1; $j < $online_user_num; $j++) { $user_id = mt_rand(1, 1000000); $redis->sadd('001|online_users_day_'.$i, $user_id); } }
//note 判断某个用户是否在线 var_dump($redis->sIsMember('001|online_users_day_5', 100030)); //note 每天在线用户总量的统计 for ($i=0; $i < 6; $i++) { print_r($redis->ssize('001|online_users_day_'.$i). "\n"); } //note 对不同时间段的在线用户名单进行聚合 print_r($redis->sInterStore('001|online_users_day_both_4and5', '001|online_users_day_4', '001|online_users_day_5'). "\n"); //note 对指定的时间段的在线用户名单进行统计 print_r($redis->sUnionStore('001|online_users_day_total_4add5', '001|online_users_day_4', '001|online_users_day_5'). "\n"); //note 哪天上线哪天没上线 print_r($redis->sDiffStore('001|online_users_day_diff_4jian5', '001|online_users_day_4', '001|online_users_day_5'). "\n");
オプション 3: hyperloglgo を使用する
まずユーザーのところに来て、オンラインでデータを記録します:// note HyperLogLog 只需要知道在线总人数 for ($i=0; $i < 6; $i++) { $online_user_num = mt_rand(100000, 300000); //online user between 100000 and 300000 var_dump($online_user_num); for ($j=1; $j < $online_user_num; $j++) { $user_id = mt_rand(1, 1000000); $redis->pfadd('002|online_users_day_'.$i, [$user_id]); } }
$count = 0; for ($i=0; $i < 3; $i++) { $count += $redis->pfcount('002|online_users_day_'.$i); print_r($redis->pfcount('002|online_users_day_'.$i). "\n"); } var_dump($count); //note 3 days total online num var_dump($redis->pfmerge('002|online_users_day_both_3', ['002|online_users_day_0', '002|online_users_day_1', '002|online_users_day_2'])); var_dump($redis->pfcount('002|online_users_day_both_3'));
オプション 4: ビットマップを使用する
作者は実際にこのソリューションを気に入っています。多くのメモリ領域を消費しませんが、大量の統計情報が含まれています。まだ古いものです。手順、まずデータを生成します://note bitmap 综合前面3个的优缺点 for ($i=0; $i < 6; $i++) { $online_user_num = mt_rand(100000, 300000); //online user between 100000 and 300000 for ($j=1; $j < $online_user_num; $j++) { $user_id = mt_rand(1, 1000000); $redis->setbit('003|online_users_day_'.$i, $user_id, 1); } }
//note userid today whether online var_dump($userid = mt_rand(1, 1000000)); var_dump($redis->getbit('003|online_users_day_5', $userid)); //note how many user is online var_dump($redis->bitcount('003|online_users_day_5')); //note 6 days both online var_dump($redis->bitop('AND', '003|online_users_day_both_6', '003|online_users_day_0', '003|online_users_day_1', '003|online_users_day_2', '003|online_users_day_3', '003|online_users_day_4', '003|online_users_day_5')); var_dump($redis->bitcount('003|online_users_day_both_6')); //note 6 days total online var_dump($redis->bitop('OR', '003|online_users_day_total_6', '003|online_users_day_0', '003|online_users_day_1', '003|online_users_day_2', '003|online_users_day_3', '003|online_users_day_4', '003|online_users_day_5')); var_dump($redis->bitcount('003|online_users_day_total_6')); //note 6 days only one online var_dump($redis->bitop('XOR', '003|online_users_day_only_one_6', '003|online_users_day_0', '003|online_users_day_1', '003|online_users_day_2', '003|online_users_day_3', '003|online_users_day_4', '003|online_users_day_5')); var_dump($redis->bitcount('003|online_users_day_only_one_6'));
以上がPHP+REDIS の実践: オンライン人数をカウントするためのいくつかのソリューションの分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。