中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP+REDIS如何統計在線人數

發布時間:2021-03-18 09:07:55 來源:億速云 閱讀:335 作者:小新 欄目:編程語言

小編給大家分享一下PHP+REDIS如何統計在線人數,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

在線人數統計業務是我們開發web肯定要設計的業務邏輯,本文就會給出幾種設計方案,來分析下各個方案的優缺點:

  • 使用有序集合

這種方案能夠同時儲存在線的用戶 和 用戶上線時間,能夠執行非常多的聚合計算,但是所消耗的內存也是非常可觀的。

  • 使用集合

這種方案能儲存在線的用戶,也能夠執行一定的聚合計算,相對有序集合,所消耗的內存要小些,但是隨著用戶量的增多,消耗內存空間也處于增加狀態

  • 使用hyperloglog

這種方案無論統計多少在線用戶, 消耗的內存都是12k,但是只能給出在線用戶的統計信息,無法獲取準確的在線用戶名單

  • 使用bitmap

這種方案還是比較好的,在盡可能節省內存空間情況下,記錄在線用戶的情況,而且能做一定的聚合運算

下面我們就用實際例子來說明:

我們先以每天會有10w~30w的小量用戶, 100w的用戶群來說明下面的幾種方案

方案一:使用有序集合

先生成用戶在線記錄數據:

$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視頻教程】

方案二:使用集合

還是先來成用戶在線記錄數據:

//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");

是不是也挺不錯的,先不要著急, 我們接著往下看

方案三:使用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'));

好少啊,是的, 這種方案僅僅只能統計出某個時間段在線人數的總量, 對在線用戶的名單卻無能為力,但是卻挺節省內存的,對統計數據要求不多情況下 ,我們便可以考慮這種方案。

方案四:使用bitmap

筆者對這種方案其實挺喜歡的,消耗的內存空間不多, 統計的信息卻挺多的,還是老步驟,先來生成數據:

//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如何統計在線人數”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

化州市| 龙江县| 吉林省| 蒙自县| 喀喇| 柳州市| 深圳市| 呼和浩特市| 新郑市| 耿马| 齐齐哈尔市| 防城港市| 同心县| 漳浦县| 株洲市| 绥棱县| 新余市| 桂平市| 天镇县| 衡水市| 英吉沙县| 迭部县| 盘山县| 翼城县| 通榆县| 巴里| 武鸣县| 章丘市| 邵东县| 祁东县| 报价| 焉耆| 南充市| 德保县| 南投县| 澄迈县| 三门县| 临颍县| 星子县| 许昌市| 三原县|