利用redis實現使用者簽到

2021-09-01 11:35:53 字數 1907 閱讀 2604

很多**都提供了簽到功能(這裡不考慮資料落地事宜),並且需要展示最近乙個月的簽到情況,如果使用bitmap我們怎麼做?一言不合亮**!

<?php

$redis = new redis();

$redis->connect('127.0.0.1');

//使用者uid

$uid = 1;

//記錄有uid的key

$cachekey = sprintf("sign_%d", $uid);

//開始有簽到功能的日期

$startdate = '2017-01-01';

//今天的日期

$todaydate = '2017-01-21';

//計算offset

$starttime = strtotime($startdate);

$todaytime = strtotime($todaydate);

$offset = floor(($todaytime - $starttime) / 86400);

echo "今天是第天" . php_eol;

//簽到

//一年乙個使用者會占用多少空間呢?大約365/8=45.625個位元組,好小,有木有被驚呆?

$redis->setbit($cachekey, $offset, 1);

//查詢簽到情況

$bitstatus = $redis->getbit($cachekey, $offset);

echo 1 == $bitstatus ? '今天已經簽到啦' : '還沒有簽到呢';

echo php_eol;

//計算總簽到次數

echo $redis->bitcount($cachekey) . php_eol;

/*** 計算某段時間內的簽到次數

* 很不幸啊,bitcount雖然提供了start和end引數,但是這個說的是字串的位置,而不是對應"位"的位置

* 幸運的是我們可以通過get命令將value取出來,自己解析。並且這個value不會太大,上面計算過一年乙個使用者只需要45個位元組

* 給我們的**定乙個小目標,執行30年,那麼一共需要1.31kb(就問你屌不屌?)

*///這是個錯誤的計算方式

echo $redis->bitcount($cachekey, 0, 20) . php_eol;

redis> bitcount bits

(integer) 0

redis> setbit bits 1 1          

(integer) 0

redis> setbit bits 2 1

(integer) 0

redis> bitcount bits

(integer) 2

redis> bitcount bits 2 -1

(integer) 0

為什麼我設定了bitcount的start後會取不到值?

「redis的setbit修改的是bit位置,而bitcount檢查的是byte位置,兩者相差有8的倍數」,再看文件確實是有這個說明,不過太不明顯了

所以在setbit 前把offset * 8 才可以。

$redis = new redis();

$redis->connect('127.0.0.1', 6379, 10);

// 乘以8的原因是這個操作修改的是bit位置

$start = 1;

$offset = $start * 8;

$redis->setbit('bit', $offset, 1);

$count = $redis->bitcount('bit', $start, -1);

var_dump($count);

參考:

Redis基於Bitmap實現使用者簽到功能

目錄 很多應用上都有使用者簽到的功能,尤其是配合積分系統一起使用。現在有以下需求 對於使用者簽到資料,如果直接採用資料庫儲存,當出現高併發訪問時,對資料庫壓力會很大,例如雙十一簽到活動。這時候應該採用快取,以減輕資料庫的壓力,redis是高效能的記憶體資料庫,適用於這樣的場景。如果採用string型...

利用 dev mem實現使用者空間驅動

dev mem是物理記憶體的全映像,可以用來訪問物理記憶體,一般用法是open dev mem o rdwr o sync 然後mmap,接著就可以用mmap的位址來訪問物理記憶體,這實際上就是實現使用者空間驅動的一種方法。它的好處參見博文 include include include inclu...

用redis實現使用者登入計數

最近有個問題 實現顯示使用者本月登入日期 累計天數到一定數目可參加活動,和下圖展示的功能類似。過去看過使用redis bitmap進行活躍使用者統計的例子,覺得和本功能非常match,決定用redis的bitset來實現。每個使用者每月產生乙個key,字段意義如下 0 位表示某月1日登入 1表示某月...