preface

Have you ever wondered how to count active users? If you do it yourself, how do you do it?

Think about it for a minute, and I’ll share how to use bitmaps in Redis to count active users.

The body of the

What is a bitmap?

A bitmap is a binary array of bytes, or simply a string. It stores binary data in byte arrays to store data.

Figure 1.1

How do I use bitmaps?

Clarify concepts

When I explained what a bitmap is, I said that a bitmap can be understood as a normal string, so why do we use a bitmap instead of a string?

Below is a schematic of storing strings in Redis

Figure 2.1

As shown in the figure, string storage is stored in redis in the form of binary array of strings. Bitmap can operate on binary array directly. The advantage of bitmap is that it can store Boolean values with 0 and 1, which greatly reduces our storage space consumption. Thanks to this feature, we use bitmaps to record check-in information, active users, etc., which can achieve space-saving capabilities (more on that later).

So how do we operate on binary arrays?

Basic access

setbit | getbit

We can add, search and modify the binary array

How do you add and find?

setbit [keyName] [offset] [value]
Copy the code

Offset: the offset, which refers to the index of the array; Value: indicates data. The value can be 0 or 1.

This command can either add or modify data.

How do you do that?

getbit [keyName] [offset]
Copy the code

Offset: the offset, which refers to the index of the array. Here, all queries return 0 except for offset, where value is 1

Addendum: It says that bitmaps can be interpreted as strings, so can they interoperate with each other?

Figure 2.2

  1. It is stored as a string and can passgetbitDoes the command get a value?

    We can verify it by combining the query with the offset shown in the picture and the corresponding value

    > set str hi
    OK
    
    > getbit str 0
    (integer) 0
    
    > getbit str 4
    (integer) 1
    
    > getbit str 7
    (integer) 0
    
    > getbit str 15
    (integer) 1
    Copy the code

    Verdict: Yes

  2. It is stored as a string and can passsettbitChange the value?

    We can try to change the value of offset 7 to 1. If successful, the h character should be changed to I

    > setbit str 7 1
    (integer) 0
    
    > get str
    "ii"
    Copy the code

    Verdict: Yes

  3. withsetbitStore string binary data, which can be passedgetGet string?

    Let’s store the binary of the character H into a bitmap to see if we can get it

    > setbit bitmap 0 0
    (integer) 0
    > setbit bitmap 1 1
    (integer) 0
    > setbit bitmap 2 1
    (integer) 0
    > setbit bitmap 3 0
    (integer) 0
    > setbit bitmap 4 1
    (integer) 0
    > setbit bitmap 5 0
    (integer) 0
    > setbit bitmap 6 0
    (integer) 0
    > setbit bitmap 7 0
    (integer) 0
    > get bitmap
    "h"
    Copy the code

    Verdict: Yes

Above introduces the basic concept and use of bitmap, through a series of exploration hope to help you better understand bitmap

So, how to apply bitmap in the project?

Statistics and lookup

bitcount | bitpos

Bitcount is used to find the number of occurrences of 1. This can be used for bitmaps or strings as follows:

bitcount [keyName] [startWith] [endWith]
Copy the code

Note that startWith and endWith are not subscripts of binary arrays.

StartWith and endWith can be interpreted as subscripts of strings. A string corresponds to 8-bit binary data. They are analogous to truncated strings, such as s= “hi”, s[0:0] = “h”, which correspond to binary arrays with subscripts 0,7, and so on.

In fact, it is hard to explain here, so let’s take the code first, which can be combined with Figure 2.2 above, and you can understand it later

> set str hi
> bitcount str 0 0
(integer) 4
> bitcount str 0 1
(integer) 8
> bitcount str
(integer) 8
Copy the code

Note: startWith and endWith default to full range when not set

Application scenario: Statistics the number of active users

Bitpos is used to find the first 0 or 1 in a specified range, as follows:

bitpos [keyName] [bit] [start] [end]
Copy the code

Bit: the desired 0 or 1, start and end same as startWith and endWith above

Application scenario: Obtain the time of first check-in and first uncheck-in

Application scenarios

The above roughly describes two application scenarios:

  1. Count active users
  2. Gets the time of first check-in and first missed check-in

I’ll give you a brief introduction here, and then add a statistic of active users for your reference

Count active users

  1. Set the keyName of the bitmap to be countedBehavior and time horizon[ation: date], such as:login:2020-3
  2. Map the user to the position diagramoffset, such asidThe subscript of the binary array,idint
  3. Login successfully usedsetbitThe correspondingoffsetSet to 1
  4. usebitcountStatistics aBehavior and time horizonThe number of active people, e.gbitcount login:2020-3

Demo: DailyActiveUsers

Gets the time of first check-in and first missed check-in

  1. Set the keyName of the bitmap to be countedBehavior and time range and object[ation: date: person], such as:login:2020-3:Tom
  2. Match the date to the position diagramoffsetFor example, number 1 corresponds to the subscript 0 of the binary array, number 2 is 1
  3. Login successfully usedsetbitThe correspondingoffsetSet to 1
  4. usebitposStatistics aBehavior and time range and object, such asbitpos login:2020-3:Tom 1

conclusion

  1. There is no essential difference between bitmaps and strings, just the way they operate
  2. Using bitmaps to store Boolean data can save a lot of space
  3. Access command setbit/getbit
  4. Statistics find bitcount/bitpos

The last

If the above content is helpful to you, please help me point a thumbs-up 👍, creation is not easy, thank you for your support!

If there are any mistakes in this article, thank you for your criticism and advice!