Maison >développement back-end >tutoriel php >Pratique PHP+REDIS : analyse de plusieurs solutions de comptage de personnes en ligne
Le comptage des personnes en ligne est la logique métier que nous devons concevoir lors du développement Web. Cet article donnera plusieurs solutions de conception pour analyser les avantages et les inconvénients de chaque solution :
Utilisation commandée. set
Cette solution peut stocker simultanément les utilisateurs en ligne et le temps de connexion des utilisateurs, et peut effectuer de nombreux calculs d'agrégation, mais la mémoire consommée est également très considérable.
Utiliser une collection
Cette solution permet de stocker des utilisateurs en ligne et peut également effectuer certains calculs d'agrégation. Par rapport aux collections ordonnées, elle consomme de la mémoire. est plus petit, mais à mesure que le nombre d'utilisateurs augmente, la consommation d'espace mémoire augmente également
Utiliser hyperloglog
Cette solution Peu importe le nombre les utilisateurs en ligne sont comptés, la mémoire consommée est de 12 Ko, mais seules les informations statistiques des utilisateurs en ligne peuvent être fournies et la liste précise des utilisateurs en ligne ne peut pas être obtenue
Utiliser le bitmap
Cette solution est meilleure. Elle enregistre le statut des utilisateurs en ligne tout en économisant autant que possible de l'espace mémoire, et peut effectuer certaines opérations d'agrégation
Utilisons des exemples pratiques ci-dessous Description :
>
Option 1 : Utiliser un ensemble ordonné pour générer les données d'enregistrement en ligne de l'utilisateur : $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);
}
}
D'accord, écrivez-le et voyons quelles informations nous pouvons compter
//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)));
Non seulement ceux-ci, nous pouvons également compter le statut en ligne des utilisateurs le matin, midi, après-midi, soir et à d'autres moments, et il y en a bien d'autres. Utilisons notre imagination. il n'y en a pas beaucoup ? C'est juste que cela consomme beaucoup d'espace mémoire
[Recommandé :
Tutoriel vidéo PHP]
Option 2 : Utiliser les collections
Tout de même, enregistrons les données en ligne en tant qu'utilisateur : //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);
}
}
D'accord, écrivons-les et voyons quelles informations nous pouvons obtenir
//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");
N'est-ce pas plutôt bien Don ? Ne vous inquiétez pas encore. Passons à l'
Option 3 : Utiliser hyperloglgoCommençons par les utilisateurs à enregistrer des données en ligne : // 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]);
}
}
Prenons un regardez cette solution Voyons quels services peuvent être obtenus
$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'));
Il y en a si peu Oui, cette solution ne peut compter que le nombre total de personnes en ligne sur une certaine période de temps, mais elle ne peut rien faire. sur la liste des utilisateurs en ligne, mais c'est plutôt bien. On peut envisager cette solution si elle économise de la mémoire et ne nécessite pas beaucoup de données statistiques.
Option 4 : Utiliser le bitmapL'auteur aime en fait cette solution. Elle ne consomme pas beaucoup d'espace mémoire mais contient beaucoup d'informations statistiques. , générez d'abord des données : //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);
}
}
Ensuite, jetons un coup d'œil aux informations statistiques qui le satisfont. Que diriez-vous de
//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'));
? Si la collection peut être comptée, ce type peut-il aussi la compter ? Et cela consomme moins de contenu.
En fait, chacune de ces solutions a ses propres avantages Selon les statistiques de l'entreprise, choisissez la solution correspondante à mettre en œuvre, afin que l'utilisation de la mémoire soit plus raisonnable
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!