>데이터 베이스 >Redis >Redis 비트맵을 사용하여 활성 사용자 수 계산

Redis 비트맵을 사용하여 활성 사용자 수 계산

齐天大圣
齐天大圣원래의
2020-05-20 07:19:212233검색

먼저 시나리오를 살펴보겠습니다. 웹사이트는 일주일 이내에 지속적으로 로그인한 사용자와 한 달 이내에 로그인한 사용자를 계산해야 합니다.

Mysql과 같은 기존 데이터베이스를 사용하여 구현하면 달성하기 어려울 것입니다. 하지만 Redis를 사용하면 매우 간단합니다. Redis의 컬렉션 유형과 비트맵 유형을 쉽게 구현할 수 있습니다. 오늘은 비트맵을 사용하여 활성 사용자 계산 기능을 구현하는 방법에 대해 주로 이야기하겠습니다.

Bitmaps

컴퓨터 시스템에서 정보의 가장 작은 단위는 바이트이고, 1바이트는 8비트와 같고, 각 비트는 0 또는 1만 될 수 있습니다(컴퓨터는 이 두 숫자만 인식합니다). 비트맵을 사용하면 비트를 직접 조작할 수 있습니다.

Bigmaps는 배열로 간주될 수 있습니다. 배열의 각 비트는 0 또는 1일 수 있습니다. 여기서 배열의 첨자는 오프셋으로 간주됩니다.

비트맵과 관련된 몇 가지 명령어를 소개하겠습니다.

setbit

setbit 키 오프셋 값: 해당 비트에 값을 설정합니다.

예를 들어 오늘은 사용자 3, 8, 23이 있습니다. , 32가 웹사이트를 방문한 후

setbit user:view:2020-5-17 3 1
setbit user:view:2020-5-17 8 1
setbit user:view:2020-5-17 23 1
setbit user:view:2020-5-17 32 1

개발 팁: 많은 애플리케이션 ID는 1부터 시작하지 않지만 1001, 10001과 같이 지정된 숫자로 시작하는 경우도 많습니다. 이를 위해 공간 낭비를 방지하기 위해 설정 시 초기 값을 먼저 빼면 됩니다

getbit

getbit 키 오프셋 지정된 비트의 값을 가져옵니다

사용자 수를 알고 싶다면 8 and 45 today 8번 사용자가 로그인했는지 여부에 관계없이

127.0.0.1:6379> getbit user:view:2020-5-17 8
(integer) 1
127.0.0.1:6379> getbit user:view:2020-5-17 45
(integer) 0

에서는 8번 사용자가 오늘 로그인했지만 45번 사용자는 오늘 로그인하지 않았음을 알 수 있습니다.

bitcount

bitcount key [start] [end] 1

지정된 범위의 숫자를 가져옵니다. 오늘 로그인한 사용자 수를 알고 싶습니다. 그런 다음

127.0.0.1:6379> bitcount user:view:2020-5-17
(integer) 4

Bitmaps 작업

bitop op destkey key [key ...]

bitop 명령은 여러 비트맵의 교차(and), 합집합(or), 비(not), 배타적 또는(xor)를 수행할 수 있으며 작업 결과 destkey에 저장됩니다.

3일 연속 로그인한 사용자 수, 즉 5월 17일, 18일, 19일에 로그인한 사용자 수를 알고 싶다면.

지난 3일 동안의 로그인 상황은 다음과 같습니다.

  • 5월 17일 3, 8, 23, 32번 로그인

  • 3, 23, 43, 54번 사용자가 5월 18일 로그인

  • 5월 19일 3, 5, 23, 32, 56, 78에 로그인한 사용자

127.0.0.1:6379> bitop and three:and user:view:2020-5-17 user:view:2020-5-18 user:view:2020-5-19
127.0.0.1:6379> bitcount three:and
(integer) 2

이 3일 동안 얼마나 많은 사용자가 로그인했는지 알고 싶다면.

127.0.0.1:6379> bitop or three:or user:view:2020-5-17 user:view:2020-5-18 user:view:2020-5-19
(integer) 10
127.0.0.1:6379> bitcount three:or
(integer) 9

보시다시피 지난 3일 동안 총 9명의 사용자가 로그인했습니다.

실전 전투

위의 지식에 대해 이야기하면 원하는 요구 사항을 완료할 수 있습니다. 일주일 이내에 지속적으로 로그인한 사용자와 한 달 이내에 로그인한 사용자를 계산해야 합니다.

먼저 30일 이내에 사용자 로그인 상황을 시뮬레이션합니다.

for ($i = 0; $i < 20000; $i++) {
    $userId = mt_rand(1, 10000);
    $date   = time() - 86400 * mt_rand(0, 30);
    $key   = &#39;userlogin_&#39;.date(&#39;Ymd&#39;, $date);
 
    $redis->setBit($key, $userId, 1);
}

일주일 이내에 로그인한 사용자를 가져옵니다. 물론 한꺼번에 가져오지는 않지만 페이징하려고 합니다. 의사 코드는 다음과 같습니다:

for ($i = 1; $i <= 7; $i ++) {
    $key = "userlogin_".date(&#39;Ymd&#39;, time() - (86400*$i));
 
    if ($i == 1) {
        $redis->bitOp(&#39;and&#39;, &#39;week_logined&#39;, $key);
    } else {
        $redis->bitOp(&#39;and&#39;, &#39;week_logined&#39;, &#39;week_logined&#39;, $key);
    }
}
 
// 获取前50个用户
$userIds = [];
for ($i=1; $i<=10000; $i++) {
    $ret = $redis->getBit(&#39;week_logined&#39;, $i);
    $ret && $userIds[] = $i;
 
    if (count($userIds) >=50) break;
}

여기서 주의할 점이 있는데, 이는 또한 처음으로 bitop 중에 week_logined가 존재하지 않기 때문에 실수하기 쉽습니다. 그러나 작업을 수행하는 데 필요한 키는 단 하나뿐입니다. 두 번째부터 시작할 때 작업을 수행하는 키는 2개입니다.

한 달 이내에 로그인한 사용자를 확보하기 위해, and를 or로 변경하는 것을 제외하고는 기본적으로 위와 동일합니다

for ($i = 1; $i <= 3; $i ++) {
    $key = "userlogin_".date(&#39;Ymd&#39;, time() - (86400*$i));
    $redis->bitOp(&#39;or&#39;, &#39;month_loginOnce&#39;, &#39;month_loginOnce&#39;, $key);
}
 
// 获取一个月内登陆过的用户
$userIds = [];
for ($i=1; $i<=10000; $i++) {
    $ret = $redis->getBit(&#39;month_loginOnce&#39;, $i);
    $ret && $userIds[] = $i;
}

or 및 and를 하는 것에는 약간의 차이가 있음을 알 수 있습니다. 또는 처음으로 판단할 필요가 없습니다. 그 이유는 다들 이해하실 겁니다.

위 내용은 Redis 비트맵을 사용하여 활성 사용자 수 계산의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.