Three specific data types in Redis (BitMap Geo and HyperLogLog)

  • 2020-06-07 05:31:35
  • OfStack

preface

Reids is widely used in the development of Web applications, and almost all back-end technologies will involve the use of Redis. In addition to the common string String, dictionary Hash, list List, collection Set, ordered collection SortedSet, and so on, there are 1 other uncommon data types, three of which are highlighted here. Without further ado, let's take a look at the details.

BitMap

BitMap represents the corresponding value or state of an element by 1 bit bit, in which key is the corresponding element itself. In fact, the bottom layer is also implemented by manipulating the string. Redis has added setbit, getbit, bitcount and other bitmap commands since version 2.2. It's a new command, but it's a string operation. Let's start with the syntax:


SETBIT key offset value

offset must be a number, while value can only be 0 or 1. At first, it doesn't work. Let's look at the specific representation of bitmap.

byte bit0 bit1 bit2 bit3 bit4 bit5 bit6 bit7
byte0 1 0 1 0 0 1 0 0
byte1 0 1 0 0 1 0 0 0

You can see that the default value of bit is 0, so how does BitMap work in real development? Here's an example: Storing a user's online status. Only 1 key is needed here, then set user ID as offset, to 1 if online and 0 if not. Example code:


// Set online status 
$redis->setBit('online', $uid, 1);

// Set the offline state 
$redis->setBit('online', $uid, 0);

// To obtain state 
$isOnline = $redis->getBit('online', $uid);

// Get the number of people online 
$isOnline = $redis->bitCount('online');

Geo

The GEO feature of Redis, introduced in version 3.2 of Redis, allows you to store and manipulate the geo-location information given by the user. The data structure of GEO consists of six commands: geoadd, geopos, geodist, georadius, georadiusbymember, gethash.

1.GEOADD


GEOADD key longitude latitude member [longitude latitude member ...]

Adds a given spatial element (latitude, longitude, name) to the specified key. This data is stored in the key as an ordered collection, allowing commands like GEORADIUS and GEORADIUSBYMEMBER to retrieve these elements later via location queries. Example:


redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2

2.GEOPOS


GEOPOS key member [member ...]

Returns the location (longitude and latitude) of all the elements at the given location from the key, for example:


redis> GEOPOS Sicily Palermo Catania NonExisting
1) 1) "13.361389338970184"
 2) "38.115556395496299"

3.GEODIST


GEODIST key member1 member2 [unit]

Returns the distance between two given locations. If one of the two positions does not exist, the command returns a null value. The unit parameter unit must be one of the following :(default: m)

[

m stands for meters.
km means in kilometers.
mi stands for miles.
ft means in feet.

]

redis> GEODIST Sicily Palermo Catania
"166274.15156960039"

4.GEORADIUS


GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]

Centered at a given latitude and longitude, the return key contains all location elements within a given maximum distance from the center. Distance units and 1 above, where the following options:

[

WITHDIST: Returns the distance between the location element and the center as well as 1. The unit of distance and the unit of range given by the user remain 1.
WITHCOORD: Returns the longitude and dimension of the position element as 1.
WITHHASH: Returns the ordered set score of the location element encoded by the original geohash, in the form of a 52-bit signed integer. This option is mainly used for low-level applications or debugging, and is not useful in practice.

]

redis> GEORADIUS Sicily 15 37 200 km WITHDIST
1) 1) "Palermo"
 2) "190.4424"
2) 1) "Catania"
 2) "56.4413"

HyperLogLog

The base statistics of Redis, this structure can be saved in the province to count various counts, such as the number of registered IP, the number of daily visits IP, real-time page UV, online users and so on. But it also has limitations, that is, it can only count the number, there is no way to know what the specific content is.

Of course, you can solve this problem with sets. But if you have a large website with IP per day, say 1 million, and if you do a rough calculation of IP using 15 bytes, then 1 million IP is 15M. In Redis, the content occupied by each key is 12K, and the theoretical storage is approximately 2^64 values. No matter what the stored content is, it is an algorithm based on cardinality estimation, which can only accurately estimate the cardinality, and it can use a small amount of fixed memory to store and identify the only element in the set. And the base of this estimate is not accurate, an approximation with a standard error of 0.81%.

There are three commands for this data structure: PFADD, PFCOUNT, and PFMERGE

1.PFADD


// Set online status 
$redis->setBit('online', $uid, 1);

// Set the offline state 
$redis->setBit('online', $uid, 0);

// To obtain state 
$isOnline = $redis->getBit('online', $uid);

// Get the number of people online 
$isOnline = $redis->bitCount('online');
0

2.PFCOUNT


// Set online status 
$redis->setBit('online', $uid, 1);

// Set the offline state 
$redis->setBit('online', $uid, 0);

// To obtain state 
$isOnline = $redis->getBit('online', $uid);

// Get the number of people online 
$isOnline = $redis->bitCount('online');
1

3.PFMERGE


// Set online status 
$redis->setBit('online', $uid, 1);

// Set the offline state 
$redis->setBit('online', $uid, 0);

// To obtain state 
$isOnline = $redis->getBit('online', $uid);

// Get the number of people online 
$isOnline = $redis->bitCount('online');
2

The cardinality of the merged HyperLogLog is close to the union of all the visible sets of the input HyperLogLog. The merged HyperLogLog is stored in the destkey key. If the key does not exist, an empty HyperLogLog is created for the key before the command executes.


redis> PFADD nosql "Redis" "MongoDB" "Memcached"
(integer) 1
redis> PFADD RDBMS "MySQL" "MSSQL" "PostgreSQL"
(integer) 1
redis> PFMERGE databases nosql RDBMS
OK
redis> PFCOUNT databases
(integer) 6

conclusion


Related articles: