Five common data types
The data type in Redis refers to the data type in which the value is stored, the key is stored as a String type, and the value can be stored as a String, List, etc. according to the needs of the scenario.
Introduction to each data type:
Underlying data structures corresponding to Redis data types
Application Scenarios of String Type
Common commands
-
Stores the key value:set key value [EX seconds] [PX milliseconds] [NX|XX]
-
[NX|XX] :
-
nx: create if key does not exist
-
xx: modify the value of the key if it exists, or use the setnx/setex command directly
-
-
-
Get key: get key
-
Value increment/decrement: incr key
- If the value in the string is of numeric type, you can use the incr command to increment it each time; if it is not of numeric type, an error is reported.
- If you want to increment N at a time, use the incrby command. If the data is floating-point, you can increment it with the incrbyfloat command.
- Similarly, decrementing uses the decr, decrby commands.
-
Batch store key value: mset key value [key value ...]
-
Get keys in bulk: mget key [key ...]
-
Get the length of the value: strlen key
-
Append content: append key value
-
Get partial characters: getrange key start end
cached object
There are two ways to cache objects using String:
- Cache the JSON of the entire object directly, command example: SET user:1 '{"name": "seven", "age":18}'.
- The key is separated into user:ID: attribute, stored by MSET, and the value of each attribute is obtained by MGET, example command: MSET user:1:name seven1 user:1:age 18 user:2:name seven2 user:2:age 20
routine count
For example, counting the number of visits, likes, retweets, inventory counts, and so on.
# Initialize article read count
> SET aritcle:readcount:1001 0
OK
# Read count +1
> INCR aritcle:readcount:1001
(integer) 1
#readcount+1
> INCR aritcle:readcount:1001
(integer) 2
distributed lock
There can be several reasons why Redis is used as a distributed lock:
- redis is fast enough
- redis provides the
setnx + expire
mechanism, which perfectly fits the implementation points of distributed locking -
Redisson
Client-side popularity makes redis-based distributed locking easier
The SET command has an NX parameter that enables "insert only if key does not exist", which can be used to implement distributed locking:
- If the key does not exist, the insertion is successful, which can be used to indicate successful locking;
- If the key exists, an insertion failure is displayed, which can be used to indicate a locking failure.
Typically, an expiration time is also added to the distributed lock. the distributed lock command is as follows:
SET lock_key unique_value NX PX 10000
- lock_key is the key key;
- unique_value is a unique identifier generated by the client;
- NX stands for setting the lock_key only when the lock_key does not exist;
- PX 10000 means set the expiration time of lock_key to 10s, this is to avoid the application can't release the lock when an exception occurs during the running process.
Sharing session information
Usually, session information can be used to save the user's login (session) state. Since this session information is stored on the server side, if user one's session information is stored on server one, but on the second visit user one is assigned to server two, and the server doesn't have user one's session information at this time, the problem of needing to repeat the If the server does not have user 1's session information, there will be a problem of repeated logins. The following is an example:
Redis can be used to store and manage the session information in a unified way, so that no matter which server the request is sent to, the server will go to the same Redis to get the relevant session information, which solves the problem of session storage in a distributed system.
Application Scenarios for List Types
Common commands
-
Stored values:
- Store value at left end: lpush key value [value ...]
- Store value at right end: rpush key value [value ...]
- Index value: lset key index value
-
Popup element:
- Left end popup: lpop key
- Right end popup: rpop key
-
Get the number of elements: llen key
-
Gets the list element:
- Get both sides: lrange key start stop
- Index get: lindex key index
-
Delete the element:
- Delete by value: lrem key count value
- Scope deletion: ltrim key start stop
message queue
- Message order preservation: Use LPUSH + RPOP to perform FIFO message processing on the queue; satisfy the order preservation of the message queue
- Blocking Reads: Use BRPOP; blocking reads from the queue avoids unnecessary performance loss when consumers keep calling RPOP commands.
- Duplicate Message Handling: Producer implements a globally unique ID; satisfies the message queue's ability to handle duplicate messages
- Message reliability: Using BRPOPLPUSH allows the consumer program to read a message from a List, while Redis inserts the message into another List (a backup List, if you will); this way, if the consumer program reads the message but doesn't process it correctly, when it restarts it can re-read the message from the backup List and process it again. This is the way to Satisfying Message Queue Reliability
But there are two problems:
- Producers need to implement globally unique IDs themselves;
- Data cannot be consumed in consumption groups
Hash type
Common commands
-
Deposit value:
- Single: hset key field value
- multi- (faceted, ethnic etc):hmset key field value [field value ...]
- When not present: hsetnx key field value
-
Gets the field value:
- Single: hget key field
- Multiple: hmget key field [field ...]
- Get all keys and values: hgetall key
- Get all fields: hkeys key
- Get all values: hvals key
-
Determine if it exists: hexists key field
-
Get number of fields: hlen key
-
in increasing order/diminish:hincrby key field increment
-
Delete field: hdel key field [field ...]
cached object
In general, objects are stored in String + Json, and some frequently changing properties in the object can be considered to be extracted and stored in Hash type.
cart
The user id is the key, product id is the field, and the number of products is the value, which exactly constitutes the three elements of the shopping cart, as shown in the following figure.
The commands involved are as follows:
- Add product: HSET cart:{user id} {product id} 1
- Add quantity: HINCRBY cart:{user id} {product id} 1
- Total number of commodities: HLEN cart.
- Delete product: HDEL cart.
- Get all items in the cart: HGETALL cart.
Set type
Aggregate computing (concatenation, intersection, difference) scenarios such as likes, co-follows, sweepstakes, etc.
Common commands
-
Stored value: sadd key member [member ...]
-
Get all elements: members key
-
Random access: srandmember langs count
-
Determine whether a member exists: sismember key member
-
Get the number of elements in the set: scard key
-
Delete collection element: rem key member [member ...]
-
Popup element: spop key [count]
kudos
assuredlyOnly one like per userIf you've already liked it, you can't like it again.
# uid:1 Users like article article:1
> SADD article:1 uid:1
(integer) 1
# uid:2 user liked article article:1
> SADD article:1 uid:2
(integer) 1
# uid:3 User liked article article:1
> SADD article:1 uid:3
(integer) 1
# uid:1 Unliked article:1.
> SREM article:1 uid:1
(integer) 1
# Get all the users who liked article:1 :.
> SMEMBERS article:1
1) "uid:3"
2) "uid:2"
# Get the number of users who liked article:1:
> SCARD article:1
(integer) 2
common interest
Set typeSupport for intersection operations, so it can be used to count co-followed friends, public numbers, and so on.
The key can be the user id and the value is the id of the followed public number.
# uid:1 User follows public number with id 5, 6, 7, 8, 9
> SADD uid:1 5 6 7 8 9
(integer) 5
# uid:2 User follows public ids 7, 8, 9, 10, 11
> SADD uid:2 7 8 9 10 11
(integer) 5
# Get co-followers
> SINTER uid:1 uid:2
1) "7"
2) "8"
3) "9"
# Give uid:2 a recommendation for a public number that uid:1 follows: one that is in uid:1 but not in uid:2.
> SDIFF uid:1 uid:2
1) "5"
2) "6"
# Verify if a public number is followed by both uid:1 or uid:2.
> SISMEMBER uid:1 5
(integer) 1 # Returns 0, indicating that it is followed.
> SISMEMBER uid:2 5 (integer) 0 # Returns 0.
(integer) 0 # Returns 0, indicating no concern.
raffle
Stores the user name of the winner of an event, and the Set type can be used because of the de-duplication function.Guarantee that the same user will not win twice。
# key is the raffle name, value is the employee name, put all employee names into the raffle box :
>SADD lucky Tom Jerry John Sean Marry Lindy Sary Mark
(integer) 5
# If you want to allow repeat winners, you can use the SRANDMEMBER command.
# 1 first prize is drawn:
> SRANDMEMBER lucky 1
1) "Tom"
# Draw 2 second prizes:
> SRANDMEMBER lucky 2
1) "Mark"
2) "Jerry"
# 3 third prizes were drawn:
> SRANDMEMBER lucky 3
1) "Sary"
2) "Tom"
3) "Jerry"
# Use the SPOP command if duplicate winners are not allowed.
# Draw first prize 1
> SPOP lucky 1
1) "Sary"
# Draw second prize 2
> SPOP lucky 2
1) "Jerry"
2) "Mark"
# Three third prizes will be drawn
> SPOP lucky 3
1) "John"
2) "Sean"
3) "Lindy"
Zset Type
Sorting scenarios such as leaderboards, phone and name sorting, etc.
Common commands
- stored value:zadd key [NX|XX] [CH] [INCR] score member [score member ...]
- Get element score: zscore key member
- Get rank range: zrange key start stop [WITHSCORES]
- Get the rank of the specified score range: zrangebyscore key min max [WITHSCORES] [LIMIT offset count]
- Increase the score of the specified element: zincrby key increment member
- Get the number of elements in the set: zcard key
- Get the number of scores in the specified range: zcount key min max
- Delete the specified element: zrem key member [member ...]
- Get element rank: zrank key member
Zset structure
typedef struct zset {
dict *dict;//hash table
zskiplist *zsl;//stopwatch
} zset;
There are two data structures in the zset struct: a jump table and a hash table. This has the advantage of allowing both efficient range queries (such as the ZRANGEBYSCORE operation, which makes use of the jump table) and efficient single-point queries (such as the ZSCORE operation, which makes use of the hash table).
the charts (of best-sellers)
Five blog posts that received likes of 200, 40, 100, 50, and 150.
# arcticle:1 Article has received 200 likes
> ZADD user:seven:ranking 200 arcticle:1
(integer) 1
# arcticle:2 The article has received 40 likes.
> ZADD user:seven:ranking 40 arcticle:2
(integer) 1
# arcticle:3 The article has received 100 likes.
> ZADD user:seven:ranking 100 arcticle:3
(integer) 1
# arcticle:4 The article has received 50 likes.
> ZADD user:seven:ranking 50 arcticle:4
(integer) 1
# arcticle:5 The article has received 150 likes.
> ZADD user:seven:ranking 150 arcticle:5
(integer) 1
# Get the 3 articles with the highest number of likes, ZREVRANGE command (in reverse order to get the elements of the ordered set key from the start subscript to the stop subscript)
# WITHSCORES means to display the score as well.
> ZREVRANGE user:seven:ranking 0 2 WITHSCORES
1) "arcticle:1"
2) "200"
3) "arcticle:5"
4) "150"
5) "arcticle:3"
6) "100"
# Get articles with 100 to 200 likes, ZRANGEBYSCORE command (returns members of an ordered set in the specified score range, sorted from lowest to highest)
> ZRANGEBYSCORE user:xiaolin:ranking 100 200 WITHSCORES
1) "arcticle:3"
2) "100"
3) "arcticle:5"
4) "150"
5) "arcticle:1"
6) "200"
Phone, Name Sort
Phone Sorting
# Store the phone number in a SortSet and then fetch the number as needed:
> ZADD phone 0 13100111100 0 13110114300 0 13132110901
(integer) 3
> ZADD phone 0 13200111100 0 13210414300 0 13252110901
(integer) 3
> ZADD phone 0 13300111100 0 13310414300 0 13352110901 (integer) 3 > ZADD phone 0 13300111100 0 13310414300 0 13352110901
(integer) 3
# Get all numbers
> ZRANGEBYLEX phone - +
1) "13100111100"
2) "13110114300"
3) "13132110901"
4) "13200111100"
5) "13210414300"
6) "13252110901"
7) "13300111100"
8) "13310414300"
9) "13352110901"
# Get the number of the 132 segment:
> ZRANGEBYLEX phone [132 (133)
1) "13200111100"
2) "13210414300"
3) "13252110901"
# Get the number of the 132 and 133 segments:
> ZRANGEBYLEX phone [132 (134)
1) "13200111100"
2) "13210414300"
3) "13252110901"
4) "13300111100"
5) "13310414300"
6) "13352110901"
Name Sorting
> zadd names 0 Toumas 0 Jake 0 Bluetuo 0 Gaodeng 0 Aimini 0 Aidehua
(integer) 6
# Get everyone's names.
> ZRANGEBYLEX names - +
1) "Aidehua"
2) "Aimini"
3) "Bluetuo"
4) "Gaodeng"
5) "Jake"
6) "Toumas"
# Get all the people whose names start with a capital A:
> ZRANGEBYLEX names [A (B)
1) "Aidehua"
2) "Aimini"
# Get everyone with a capital C through Z in their name:
> ZRANGEBYLEX names [C [Z
1) "Gaodeng"
2) "Jake"
3) "Toumas"
BitMap (new in version 2.2):
present (sb for a job etc)
Scenarios for binary state statistics.
sign in
Record only check-ins (1) or no check-ins (0)
# Record user signed in on April 3
SETBIT uid:sign:100:202304 2 1
# Check if the user signed in on June 3
> GETBIT uid:sign:100:202306 3
1
# Count the number of times the user has signed in during the month of June.
> BITCOUNT uid:sign:100:202206
1
# Count the number of times a user has clocked in for the first time in this month > BITPOS key bitValue [start] [end], start end denotes the range to be detected
BITPOS uid:sign:100:202206 1
Determine user login status
key = login_status means to store the user login status collection data, using the user ID as the offset, set to 1 if online, set to 0 if offline. determine whether the corresponding user is online through GETBIT. Only 6 MB of space is needed for 50 million users.
# Indicates that the user with ID = 10086 is logged in.
SETBIT login_status 10086 1
# Checks if the user is logged in, returns 1 for logged in.
GETBIT login_status 10086
# Logout, set the value of offset to 0.
SETBIT login_status 10086 0
Total number of consecutive check-ins
Take the date of each day as the key of the Bitmap, userId as the offset, and set the bit at the offset to 1 if it is a punch card. Each bit of data in the set corresponding to the key is a record of a user's punch card on that date.
Then we can set up 7 Bitmaps and do the "and" operation on the corresponding bit positions of these 7 Bitmaps. So when a userID has bit = 1 in the offset position of 7 Bitmaps, it means that the user has clocked in continuously for 7 days. The result is saved in a new Bitmap, then we count the number of bit = 1 by BITCOUNT, then we get the total number of users who have clocked in continuously for 7 days.
HyperLogLog (new in version 2.8)
The scenario of massive data base counting provides inaccurate de-duplication counting. However, note that HyperLogLog's statistical rules are done based on probability and are not very accurate, with a standard false count rate of 0.81%. Therefore, it is suitable for mass data scenarios.
The advantage of HyperLogLog is that the amount of memory required to compute the base is always fixed and small when the number or size of input elements is very, very large. In Redis, each HyperLogLog key only costs 12 KB of memory to compute a base of close to 2^64 different elements, making HyperLogLog very space-efficient compared to the Set and Hash types, which consume more memory as more elements are added.
Millions of web UV counts
When counting UVs, you can use the PFADD command (which is used to add new elements to HyperLogLog) to add every user who visits the page to HyperLogLog.
PFADD page1:uv user1 user2 user3 user4 user5
# You can use the PFCOUNT command to get the UV value of page1 directly and get the statistics result.
PFCOUNT page1:uv
GEO (new in version 3.2)
Scenarios for storing geolocation information
Redis GEO operation methods are:
- geoadd: add the coordinates of the geolocation.
- geopos: Get the coordinates of the geolocation.
- geodist: calculates the distance between two positions.
- georadius: get the set of geographic locations within the specified range based on the latitude and longitude coordinates given by the user.
- georadiusbymember: get a collection of geographic locations within a specified range based on a location stored inside a location collection.
- georadius: centered on the given latitude and longitude, returns all position elements contained in the key whose distance from the center does not exceed the given maximum distance.
GEORADIUS method parameters:
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
Parameter Description:
- m : meters, the default unit.
- km: kilometers.
- mi: miles.
- ft: feet.
- WITHDIST: Returns the distance between the position element and the center at the same time as the position element.
- WITHCOORD: Returns the longitude and dimension of the position element as well.
- WITHHASH: Returns the ordered set of scores of the location elements encoded by the original geohash, as a 52-bit signed integer. This option is mainly used for low-level applications or debugging, and is not very useful in practice.
- COUNT Limits the number of records returned.
- ASC: The results are sorted by distance from the nearest to the farthest.
- DESC: The results are sorted according to the closest to the nearest.
ride-hailing
Assuming the vehicle ID is 33 and the latitude and longitude locations are (116.034579, 39.030452), you can save the latitude and longitude of all the vehicles in a GEO collection with a collection key of cars:locations.
GEOADD cars:locations 116.034579 39.030452 33
The LBS application can use the GEORADIUS command when the user wants to find an internet car in his neighborhood.
For example, when the LBS application executes the following command, Redis looks up information about vehicles within 5 kilometers of the input user's latitude and longitude (116.054579, 39.030452) and returns it to the LBS application.
GEORADIUS cars:locations 116.054579 39.030452 5 km ASC COUNT 10
person in the vicinity
nearbyPeople is a general key, user_1 and user_2 are equivalent to two elements inside nearbyPeople and their corresponding latitude and longitude, this example is to user_1 and user_2 latitude and longitude exists in nearbyPeople this key
redis> GEOADD nearbyPeople 13.36 38.11 "user_1" 15.08 37.50 "user_2"
(integer) 2
Get the latitude and longitude of the elements user_1 and user_2 in nearbyPeople, of course if there is no geoadd latitude and longitude of the corresponding element, it will return nil.
redis> GEOPOS nearbyPeople user_1 user_21) 1) "13.36138933897018433" 2) "38.11555639549629859"2) 1) "15.08726745843887329" 2) "37.50266842333162032"
Get the distance between the nodes user_1 and user_2 in nearbyPeople in the specified unit, as shown below:
- m : meters, the default unit.
- km: kilometers.
- mi: miles.
- ft: feet.
redis> GEODIST nearbyPeople user_1 user_2"166274.1516"redis> GEODIST nearbyPeople user_1 user_2 km"166.2742"redis> GEODIST nearbyPeople user_1 user_2 mi"103.3182"
Find all elements in nearbyPeople that are within 200km of latitude and longitude (15,37) and include the distance:
redis>GEORADIUS nearbyPeople 15 37 200 km WITHDIST
1) 1) "user_1"
2) "190.4424"
2) 1) "user_2"
2) "56.4413"
Stream (new in version 5.0)
Message Queue, which solves two problems that exist in message queues based on List type implementations.
You can automatically generate globally unique message IDs and support consuming data in consumption groups.
Interview questions column
Java interview questions columnIt's online, so feel free to visit.
- If you don't know how to write a resume, resume projects don't know how to package them;
- If there's something on your resume that you're not sure if you should put on it or not;
- If there are some comprehensive questions you don't know how to answer;
Then feel free to private message me and I will help you in any way I can.