The introduction of Redis
Redis is an open source (BSD-licensed), in-memory data structure storage system that can be used as database, cache, and messaging middleware MQ. It supports many types of data structures, such as strings, hashes, lists, sets, sorted sets, range queries, bitmaps, Hyperloglogs and Geospatial index radius query. Redis is built with replocation, LUA scripting, LRU eviction, transactions, and different levels of disk persistence, And high availability through Redis Sentinel and Automated Cluster
Redis common type
- string String
- hash HashMap
- list LinkedList
- set HashSet
- sorted_set TreeSet
Redis data storage format
- Redis itself is a Map where all data is stored in the form of ==key:value==
- == Data type == refers to the type of data stored, that is, the type of the value part, and the key part is always a string
string
- Stored data: Single data, the simplest data storage type, is also the most common data storage type
- Format for storing data: One storage space holds one data
- Store content: Usually a string, which can be used as a numeric operation if it is presented as an integer
Basic operations on string data
- Add/modify data
set key value
- To get the data
get key
- Delete the data
del key
127.0.0.1:6379 >setName maomao OK 127.0.0.1:6379> get name"maomao"127.0.0.1:6379 > del name (integer) 1
127.0.0.1:6379> get name
(nil)
Copy the code
- Add/modify multiple data
mset key1 value1 key2 value2 …
- Get multiple data
mget key1 key2 …
- Get the length of the data string (number of strings)
strlan key
- Append information to original information (append if original information exists, otherwise == new ==)
append key value
127.0.0.1:6379> mset k1 a k2 b k3 c
OK
127.0.0.1:6379> mget k1 k2 k3
1) "a"
2) "b"
3) "c"127.0.0.1:6379 >setName maomao OK 127.0.0.1:6379> strlen name (integer) 6
127.0.0.1:6379> append hello world
(integer) 5
127.0.0.1:6379> get hello
"world"
127.0.0.1:6379> append name zhu
(integer) 9
127.0.0.1:6379> get name
"maomaozhu"
Copy the code
Extended operations on string data
Data addition and subtraction operations
The business scenario
- In large-scale enterprise applications, == is a basic operation. Multiple tables are used to store data of the same type, but the corresponding primary key IDS must be consistent and cannot be repeated. The Oracle database has sequence Settings to solve this problem, but the MySQL database does not have a similar mechanism. How can I solve this problem?
The solution
-
Sets numeric data to increment a specified range of values
incr key
incrby key increment incrbyfloat key increment Copy the code
-
Sets numeric data to reduce a specified range of values
decr key
decrby key increment Copy the code
Redis is inherently single-threaded, so you can solve the distributed ID problem in this way
127.0.0.1:6379 >setNum 0 OK 127.0.0.1:6379> incr numOn the # 1
(integer) 1
127.0.0.1:6379> incr num
(integer) 2
127.0.0.1:6379> get num
"2"127.0.0.1:6379 > decr num# 1
(integer1 127.0.0.1:6379> decr num (integer) 0
127.0.0.1:6379> decr num
(integer) -1
127.0.0.1:6379> get num
"1"127.0.0.1:6379 > incrby num is 10You can set the step size to specify the increment
(integer9 127.0.0.1:6379> incrby num 10 (integer) 19
127.0.0.1:6379> decrby num 9
(integer) 10
127.0.0.1:6379> incrbyfloat num 2.5 # the decimal
"12.5"127.0.0.1:6379 > incrby num is 3.5# incrby can only be an int
(error) ERR value is not an integer or out of range
Copy the code
String as a numeric operation
- String is stored in Redis. Default == is a string. When incR is added or subtracted, decR will be converted to numeric type for calculation.
- Redis all operations are == atomic ==, using a single thread to handle all business, commands are executed one by one, so there is no need to worry about concurrency
Data impact.
- Note: an error will be reported if the original data cannot be converted to a value == or if the redis value == upper limit == is exceeded.
9223372036854775807 (maximum long data in Java, long.max_value)
Redis is used to control the id== of the primary key of the database table and provide a generation policy for the primary key of the database table to ensure the uniqueness of the == primary key of the database table. Applies to all databases and supports database clusters
Data timeliness Settings
The business scenario
- Casting vote can only be done through wechat, each wechat can only cast 1 vote every 4 hours.
- E-commerce merchants open the recommendation of popular commodities, and the popular commodities cannot remain in the popular period all the time. The popular period of each commodity lasts for 3 days, and the popular period will be automatically cancelled after 3 days.
- Hot news will appear on news websites. The biggest characteristic of hot news is timeliness. How to automatically control the timeliness of hot news?
The solution
-
Sets the data to have a specified life cycle
setex key seconds value
psetex key milliseconds value Copy the code
-
Set up separate data
setnx key value
127.0.0.1:6379 > setex tel 10'123456789' # Set a key value to num 10 seconds after expirationOK 127.0.0.1:6379 > TTL tel# Lifecycle
(integer) 6
127.0.0.1:6379> get tel
"123456789"TTL tel (127.0.0.1:6379 >integer) 1
127.0.0.1:6379> get tel
(nil)
127.0.0.1:6379> setnx subject 'redis' If the key does not exist, create the corresponding key
(integer) 1
127.0.0.1:6379> setnx subject 'mongodb' # create failed if key exists
(integer) 0
127.0.0.1:6379> get subject
"redis"127.0.0.1:6379 > psetex zhu, 5000'zhuzhu' # milliseconds
OK
127.0.0.1:6379> ttl zhu
(integer) 1
127.0.0.1:6379> get zhu
(nil)
127.0.0.1:6379> setK1 v1 OK 127.0.0.1:6379> get k1"v1"
127.0.0.1:6379> get k4
(nil)
127.0.0.1:6379> msetnx k1 v1 k4 v4 # msetnx is an atomic operation that either succeeds or fails together
(integer) 0
127.0.0.1:6379> get k4
(nil)
127.0.0.1:6379> get k1
"v1"
Copy the code
Redis == Controls the life cycle of data ==, and controls business behaviors by whether data fails, which is applicable to all operations with time-limited control
Some other operations on string data
-
Gets the range of strings
getrange key start end
-
Replaces the string in the specified range
setrange key offset value
127.0.0.1:6379 >set name 'hello,maomao'OK 127.0.0.1:6379 > get the name"hello,maomao"
127.0.0.1:6379> getrange name 0 3
"hell"127.0.0.1:6379> getrange name 0-1"hello,maomao"
127.0.0.1:6379> setrange name 2 mmm
(integer) 12
127.0.0.1:6379> get name
"hemmm,maomao"
127.0.0.1:6379> setrange name 0 ilove
(integer) 12 127.0.0.1:6379> Getrange name 0-1"ilove,maomao"
Copy the code
- First get the set again
getset key value
127.0.0.1:6379 > getset db redis# Return nil if no value exists(nil) 127.0.0.1:6379 > get db"redis"127.0.0.1:6379 > getset db mongoIf there is a value, get the original value and set the new value
"redis"127.0.0.1:6379 > get db"mongoDB"
Copy the code
- Store an object
set user:1 {name:maomao,age:18} # Set a user:1 object value to json character to save an object!The key here is a clever design: user:{id}:{filed} , 127.0.0.1:6379> mset user:1:name maomao user:1:age 18 user:1:gender nV OK 127.0.0.1:6379> mget user:1:name user:1:age user:1:gender 1)"maomao"
2) "18"
3) "nv"
Copy the code
Precautions for string data operations
- The difference between feedback of unsuccessful data operations and normal data operations
- Indicates whether the running result is successful. (Integer) 0 → false Indicates that the running result is failed. (Integer) 1 → true Indicates that the running result is successful
- Indicates the running result value (INTEGER) 3 → 3 3 (INTEGER) 1 → 1 1
- Data not obtained
(nil) equals null
- Maximum data storage capacity
512MB
- Maximum range of numerical computation (maximum of longs in Java)
9223372036854775807
Application scenario of string
Control the display of high-frequency access information on the homepage, such as the up master of STATION B, the homepage displays the number of fans, the number of likes and the number of plays
- Set user information for big V user in Redis, with user primary key and attribute value as key, and set periodic refresh strategy in the background
- User: id: 110: fans – 2389000
- User: id: 110: he likes – 9476000
- User: id: 110: views – 480000000
- Store up main information in Redis in JSON format and refresh periodically (hash is also possible)
Eg: user: id:110 → {“id”:110,”name”:” fans”:2389000,”likes”:9476000, “views”:480000000}
127.0.0.1:6379> mset user:id:110:likes 9476000 user:id:110:views 480000000OK 127.0.0.1:6379> mget user:id:110:fans user:id:110:likes user:id:110:views 1)"2389000"
2) "9476000"
3) "480000000"127.0.0.1:6379 > incr user: id: 110: fans (integer) 2389001
127.0.0.1:6379> incr user:id:110:views
(integerIncr user:id: 100 :views (integer) 480000002
127.0.0.1:6379> mget user:id:110:fans user:id:110:likes user:id:110:views
1) "2389001"
2) "9476000"
3) "480000002"127.0.0.1:6379 >setUser: id: 120 {id: 120, name: wanglaoju, fans, 2389000, "likes" : 9476000, views: 480000000} OK 127.0.0.1:6379 > get user: id: 120"{id:120,name:wanglaoju,fans:2389000,likes:9476000,views:480000000}"
Copy the code
Key setting conventions
- Hot data key naming convention in the database
Table name: Primary key name: Primary key Value: Field name ORDER: ID: 294375951: Name EQUIP: ID: 390472345: Type news: ID: 202004150: title
hash
- New storage requirements: Groups a series of storage data for easy management. Typical applications store object information
- Required storage structure: One storage space holds multiple key-value pairs of data
- Hash type: The underlying data store uses the == hash table structure ==
Reference to hash tablesBig man’s article
Hash storage structure optimization
- If the number of fields is small, the storage structure is optimized to an array-like structure
- If the number of fields is large, the storage structure uses the HashMap structure
Basic operations on hash data
-
Add/modify data
hset key field value
-
To get the data
hget key field
hgetall key
- Delete the data
hdel key field1 [field2]
127.0.0.1:6379> hset user name xiaotian
(integer) 1
127.0.0.1:6379> hset user age 20
(integer) 1 127.0.0.1:6379> hset user gender naninteger) 1
127.0.0.1:6379> hgetall user
1) "name"
2) "xiaotian"
3) "age"
4) "20"
5) "gender"
6) "nan"127.0.0.1:6379 > hget user name"xiaotian"127.0.0.1:6379 > hget user gender"nan"
127.0.0.1:6379> hdel user gender
(integer) 1
127.0.0.1:6379> hgetall user
1) "name"
2) "xiaotian"
3) "age"
4) "20"
Copy the code
- Add/modify multiple data
Hmset key field1 value1 field2 value2…
- Get multiple data
Hmget key field1 field2…
- Gets the number of fields in the hash table
hlen key
- Gets whether the specified field exists in the hash table
hexists key field
127.0.0.1:6379> hmget user name age
1) "xiaotian"
2) "20"
127.0.0.1:6379> hmset user name feifei age 22 weight 46
OK
127.0.0.1:6379> hgetall user
1) "name"
2) "feifei"
3) "age"
4) "22"
5) "weight"
6) "46"127.0.0.1:6379 > hlen user# fetch the number of fields
(integer) 3
127.0.0.1:6379> hexists user age Check whether the specified field exists
(integer) 1
127.0.0.1:6379> hexists user height
(integer) 0
Copy the code
Hash data extension operation
- Gets the names or values of all fields in a hash table
hkeys key
hvals key
- Sets the numeric data of the specified field to increase the value of the specified range
hincrby key field increment
hincrbyfloat key field increment
127.0.0.1:6379 > hkeys user# all field names
1) "name"
2) "age"
3) "weight"127.0.0.1:6379 > hvals userAll field values
1) "feifei"
2) "22"
3) "46"
127.0.0.1:6379> hincrby user age 1
(integer) 23
127.0.0.1:6379> hincrby user weight 10 # specify increment
(integer) 56
127.0.0.1:6379> hincrby user weight -5 # specify decrement
(integer51)Copy the code
Precautions for hash data operations
- Value == of the hash type can only store string == and cannot store other data types. == does not exist nesting. If the data is not retrieved, the corresponding value is nil.
- Each hash can store 2^32-1 key-value pairs
- The hash type is very close to the data storage form of objects, and can be flexibly added and deleted object attributes. However, hash is not designed to store a large number of objects. Do not abuse hash, let alone use it as a list of objects
- Hgetall operation can == obtain all attributes ==. If there are too many internal fields, the overall data traversal efficiency will be very low, which may become a data access bottleneck
Hash application scenarios
Design and implementation of shopping cart in e-commerce website
Business analysis
- Analyze only the Redis storage model for the shopping cart
- Add, browse, change quantity, delete, empty
- Shopping carts are persistently synchronized across databases
- Relationship between shopping cart and order
- Submit shopping cart: Read data to generate order
- Merchant temporary price adjustment: subject to order level
- Unlogged user shopping cart information store
- Cookies are stored
The solution
- With the customer ID as the key, each customer creates a ==hash storage structure to store the corresponding shopping cart information
- The product number is stored as ==field== and the purchase quantity as ==value==
- Add item: Append new field and value
- Browse: Traverses the hash
- Change the number of items: Increases/decreases, and sets the value to delete an item: deletes the field
- Clear: Deletes the key
Id :001 User ID G01 G02 Commodity ID 127.0.0.1:6379> hmset ID :001 G01 100 G02 200 OK 127.0.0.1:6379> hmset ID :002 G02 10 G04 8 G05 100 OK 127.0.0.1:6379> hset ID: 001G03 5 (integer) 1 127.0.0.1:6379> hgetall ID :001 1)"g01"
2) "100"
3) "g02"
4) "200"
5) "g03"
6) "5"
127.0.0.1:6379> hdel id:001 g01
(integer) 1 127.0.0.1:6379> hgetall ID :001 1)"g02"
2) "200"
3) "g03"
4) "5"127.0.0.1:6379> hincrby ID :001 G03 3 (integer) 8 127.0.0.1:6379> hgetall ID :001 1)"g02"
2) "200"
3) "g03"
4) "8"
Copy the code
However, this is not enough at present. At present, the data is only stored in Redis, which does not accelerate the process. The commodity information also needs to be queried twice in the database
The solution
-
The item record in each shopping cart is saved as two fields
-
Field1 is dedicated to saving purchase quantities
- Naming format: Commodity ID: NUMS
Save data: values
-
Field2 is dedicated to saving the information displayed in the shopping cart, including text descriptions, picture addresses, owner information, and more
- Name format: Product ID :info
Save data: JSON
127.0.0.1:6379> hmset id:003 g01:nums 100 g01:info {diannao,8000} OK 127.0.0.1:6379> hgetall ID :003 1)"g01:nums"
2) "100"
3) "g01:info"
4) "{diannao,8000}"127.0.0.1:6379> hmset id: 004g01 :nums 50 g01:info {diannao,8000} OK 127.0.0.1:6379> hgetall ID :004 1)"g01:nums"
2) "50"
3) "g01:info"
4) "{diannao,8000}"
Copy the code
The new problem with this is that g01:info is duplicated, so we use field2 as a separate hash to hold product information
Finally, if field has a value, do not add it. If field has no value, add it
hsetnx key field value
127.0.0.1:6379> hset ID: 004G01 :nums 200 (integer) 0 127.0.0.1:6379> hget ID: 004g01 :nums"200"127.0.0.1:6379> hsetnx ID: 004g01 :nums 400 (integer) 0
127.0.0.1:6379> hsetnx id:004 g05:nums 400
(integer) 1 127.0.0.1:6379> hgetall ID :004 1)"g01:nums"
2) "200"
3) "g01:info"
4) "{diannao,8000}"
5) "g05:nums"
6) "400"
Copy the code
Shopping spree
On the Double 11 event day, iPhone merchants will launch panic buying activities for iPhone12, iPad Pro and MacBook Pro products costing 5,000 yuan, 6,000 yuan and 10,000 yuan, with the upper limit of 100 units for each product
The solution
- Use the merchant ID as the key
- Take the id of the participating commodity as field
- Take the quantity of commodities participating in the snap up as the corresponding value
- Use a lower value to control the number of products when buying
127.0.0.1:6379> hmset shop:001 iphone12 100 iPad 100 macbook 100 OK 127.0.0.1:6379> hincrby shop:001 iphone12-1 (integer) 99
127.0.0.1:6379> hincrby shop:001 macbook -20
(integer) 80 127.0.0.1:6379> Hgetall Shop :001 1)"iphone12"
2) "99"
3) "ipad"
4) "100"
5) "macbook"
6) "80"
Copy the code