The two basic and advanced Redis articles have been fully updated. For word limit and ease of reading, they are divided into two articles.
The main contents of this paper are: NoSQL introduces Redis, as well as the installation and configuration of Linux7 environment, and summarizes very detailed types, usage and examples, and finally through Jedis and RedisTemplate in Springboot remote operation of Redis in IDEA.
The second article will cover a basic use of configuration files, publish and subscribe, master/slave replication, sentry, and more.
【 9K word +】 second: advanced: master Redis some advanced operations (Linux environment)
Recently, I participated in the 2020 Annual Creators List singles list, [nickname: BWH_Steven] hope you can support me
The Creators of the Year 2020 page
A brief no
Redis is an open source, network-enabled, memory-based, optionally persistent key-value pair storage database, wikipedia, written in ANSI C
In a nutshell, Redis is a high-performance NoSQL database
What is NoSQL?
The MySQL database we learned in front of is a typical SQL database is a traditional relational database, and the Redis database we learn today is a NoSQL database, also known as a non-relational database, it is completely different from the concept of MySQL and so on, it is a new database concept, We post a set of explanations from Baidu encyclopedia
NoSQL refers to a non-relational database. With the rise of the Internet web2.0 website, the traditional relational database in dealing with the web2.0 website, especially the super large scale and high concurrency SNS type of web2.0 pure dynamic website has been inadequate, there are a lot of difficult to overcome problems, while the non-relational database because of its own characteristics has been very rapid development. The creation of NoSQL database is to solve the challenges brought by large-scale data sets and multiple data types, especially the big data application problems — Baidu Encyclopedia
Description: The blogs, RSS, P2P, microblog and Tiktok that we see now are all products of Web2.0. Compared with the past Web1.0, Web2.0 lays more emphasis on user interaction. Users can not only browse, but also upload some resources to the website, such as pictures, texts or short videos. Allows users to participate in the creation of content on the site
(2) Why use NoSQL?
-
Low deployment cost: It is easy to deploy and mainly uses open source software
-
Diversified storage formats: Supports multiple formats such as key-values, documents, and images, including objects and collections
-
Fast: Data is stored in a cache, not on a hard disk, and for example Redis is based on key-value pairs and does not need to be parsed through the SQL layer, which is very high performance
-
No coupling, easy to expand
- In SQL, a data in use is not allowed to be deleted, but NoSQL can
(3) Can NoSQL replace SQL?
Some people will say that NoSQL = Not SQL, but I prefer to understand that NoSQL = Not only SQL, we can Not judge the quality of two technologies with an absolute conclusion, each technology has its specific reasons, in my opinion, NoSQL is more suitable as a supplement to SQL database, Due to the emergence of massive data, performance requirements are high, and NoSQL this product, for simple structure but large amount of data processing is much faster than traditional SQL, but the same, its logical operation must be very simple, otherwise it is also inadequate
In my opinion, it’s easy to say that NoSQL is about trading functionality for performance, but you need to handle complex business logic and use a relational database, so it’s not realistic to completely replace SQL with NoSQL in the model. It’s more like a complementary relationship
Benefits of SQL:
- Supports complex query operations on one table and multiple tables
- Support the processing of things, to ensure data security requirements
- Learning cost is low, more information
There are many NoSQL products on the market, and today we are going to introduce one of them – Redis, a database based on key and value storage
(4)NoSQL database four classification table analysis
classification | Examples for | Typical Application Scenarios | The data model | advantages | disadvantages |
---|---|---|---|---|---|
Key-value | Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB | Content caching, primarily for handling high access loads of large amounts of data, is also used in some logging systems, and so on. | Key refers to the key-value pair of Value, which is usually implemented using a hash table | Fast search speed | Data is unstructured and is usually treated only as string or binary data |
Column storage database | Cassandra, HBase, Riak | Distributed file system | Data in the same column is stored in a column cluster | Fast search speed, strong scalability, easy to carry out distributed expansion | Relatively limited function |
Document database | CouchDB.MongoDb | Web applications (similar to key-value, Value is structured, except that the database can understand the content of Value) | Key-value Indicates the corresponding key-value pair. Value indicates structured data | Data structure requirements are not strict, table structure is variable, do not need to define table structure in advance like relational database | The query performance is not high, and there is no unified query syntax. |
Graph database | Neo4J, InfoGrid, Infinite Graph | Social networks, recommendation systems, etc. Focus on building the relationship map | The graph structure | Using graph structure correlation algorithm. Such as shortest path addressing, N degree relation search and so on | Many times you need to compute the entire graph to get the information you need, and this structure is not good for distributed clustering. |
The first meeting Redis
What is Redis
As we mentioned at the beginning, Redis is a high-performance NoSQL database, so what are its application scenarios?
-
Used for user content caching, can handle high access loads of large amounts of data, such as: data query, news, product content
-
Task queue, for example, seckill, 12306
-
Online friend List
-
Ranking of application and Website access statistics
Since it is based on key-value storage, what types of storage can be supported?
-
String type – String
-
List-list: linkedList
-
Collection – set
-
Ordered set – sortedset
-
Hash: map
(2) Download and install
Description:
Linux is recommended for deployment, so we’ll cover installation and configuration in Linux in more detail later, but if you just want to learn the syntax quickly, you can make do with the Windows version, which is much easier to install.
Redis is written in ANSI C and works in most POSIX systems like Linux,
*BSD
, and OS X, without external dependencies. Linux and OS X are the two operating systems where Redis is developed and tested the most, and we recommend using Linux for deployment . Redis may work in Solaris-derived systems like SmartOS, but the support is best effort. There is no official support for Windows builds.IO /topics/intr…
(1) Linux is recommended
Redis. IO (recommended)
- Access may be slow
Chinese website: www.redis.net.cn
- Version has some lag, for example, the official website has 6.0.9, Chinese home page still hangs 5.0.4
A: download
#Download the redis-6.0.9 packageWget HTTP: / / http://download.redis.io/releases/redis-6.0.9.tar.gzCopy the code
Supplement:
- Can download. Redis. IO/releases to see choose the required version
- This way after downloading the compressed file is located
/home
directory
B: unzip
Generally speaking, our program will be in the /opt directory, so we will first move the compressed file there and then unpack it
#Move this file to the opt directory under the root directoryThe mv redis - 6.0.9. Tar. Gz/opt#Unzip this fileThe tar - ZXVF redis - 6.0.9. Tar. GzCopy the code
Redis.conf is the configuration file that we will use later, so we will ignore it for the moment
C: Check the GCC version (Redis 6 can be ignored)
If you are using a version higher than Redis 6, such as 6.0.9, your GCC version will cause errors if it is too low, at least if your GCC version is higher than 5.3
If GCC is not installed first
yum -y install gcc
yum -y install gcc-c++
Copy the code
After the installation is complete, check through GCC -v that the installed version is 4.x.x, so you need to upgrade, the old version of Redis can not do the upgrade step
Execute each of the following commands in turn
#Upgrade to GCC 9.3
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
#The SCL command is only enabled temporarily, and the original system GCC version will be restored by exiting the shell or restarting it
scl enable devtoolset-9 bash
#You also need to perform the following operations when using GCC 9.3 for a long time
echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
source /etc/profile
Copy the code
Check out the updated version
D: Compile and install
Compile and install in sequence,
#compile
make
#The installation
make install
Copy the code
Make will slow down, wait patiently, and if something goes wrong, it’s usually GCC
The installation content is generally stored in /usr/local/bin
E: Copy the configuration file
We put the original configuration file in that decompression file, we use a separate copy out, convenient for us to operate and change
Go to /usr/local/bin and create a new folder. Then copy the redis.conf folder from the previous folder
#Example Jump to the specified directory
cd /usr/local/bin
#Create a new folder
mkdir myconfig
#Copy /opt/redis-6.0.9/redis.conf to myconfig in the current directoryCp/opt/redis - 6.0.9 / redis. Conf myconfigCopy the code
Look at the process
F: Enable background running
To ensure that our redis can run in the background, we will edit the redis.conf configuration file we copied from it
vim redis.conf
Copy the code
Find daemonize No
Change no to yes, save and exit
G: Run Redis
Run the server (in usr/local/bin)
#Running the server
redis-server myconfig/redis.conf
Copy the code
- Myconfig /redis.conf is added to specify the configuration file for its startup
Then run its client
#Running the client
redis-cli -p 6379
Copy the code
- Because it is the local computer, you only need to specify the port, not the IP address
You can do a simple test like set get, and if you get a value, it’s successful
H: Stop the service and check whether the process exists
Let’s first look at the presence of the process at run time
#View the Redis process
ps -ef|grep redis
Copy the code
On the client side, shutdown and exit can be performed (this is done in the Redis client)
#Shut down
127.0.0.1:6379> shutdown
not connected> exit
#Take another look at the status of the process
[root@centos7 bin]# ps -ef|grep redis
Copy the code
(2) Windows is not recommended
We can go to Github and look for the Windows version, but it will be a bit behind schedule. At least there is no official support for the update. The latest version seems to be several years old
Github.com/microsoftar…
Decompression can be used: start the redis – server. Exe and redis – cli. Exe can test use it directly, there is a problem modifying redis. Windows. The conf configuration file
- Redis-server. exe: indicates the redis server
- Redis -cli.exe: redis client
- Redis.windows. conf: configuration file
Three Redis general command
(1) Open and close commands
(1) Start Redis service
redis-server [--port 6379]
Copy the code
Sometimes there are too many parameters. You are advised to use a configuration file to start the system
redis-server [xx/redis.conf]
Copy the code
For example, run redis-server myconfig/redis.conf
(2) The client connects to Redis
Redis -cli [-h 127.0.0.1 -p 6379]Copy the code
For example, redis-cli -p 6379
(3) stop Redis
In the client (mark: 127.0.0.1:6379>), enter shutown and so on
#Shut down
127.0.0.1:6379> shutdown
not connected> exit
Copy the code
If it is in a directory (preceded by $, etc.), it can be executed
redis-cli shutdown
kill redis-pid
Copy the code
(4) Test connectivity
Go back to PONG and it’s connected
127.0.0.1:6379 > ping PONGCopy the code
(2) Key and general operation
Note: Each type of storage is different, so adding storage will not be covered here, but will be covered in detail in each type.
Just to keep things simple and test them first, you can use these commands for the time being (this is String)
-
You can add it using set key value
-
Set is a command, key is a key, and value is a value
-
For example: Set test Ide-20
-
-
Get Key Obtains the value
(1) Get all keys
- Grammar: Keys pattern
127.0.0.1:6379> keys *
1) "test"
2) "test2"
Copy the code
*
As a wildcard character, it indicates any character, because it will iterate over all keys and then display the list of all keys. Use it with caution when the time complexity is O(n) and the data volume is large
(2) Obtain the total number of keys
- Grammar: dbsize
127.0.0.1:6379 > dbsize (integer) 2Copy the code
- Internal variables store this value, and the fetch operation is not traversal, so the time complexity is O(1).
(3) Check whether the current key exists
- Syntax: exists key [key…
127.0.0.1:6379> exists test
(integer) 1
Copy the code
- And the last thing that’s returned is the number that exists
(4) Query the key type
- Syntax: Type key
127.0.0.1:6379 > type test stringCopy the code
(5) movement keys
- Syntax: Move key DB
127.0.0.1:6379> move test2 3
(string) 1
127.0.0.1:6379> select 3
OK
127.0.0.1:6379[3]> keys *
1) "ideal-20-2"
Copy the code
- Note: Redis has 16 databases by default. Move means to move to one of them, and select means to switch to the database
(6) the delete key
- Syntax: del key [key…
127.0.0.1:6379> del test2
(integer) 1
Copy the code
(7) Set the expiration time
- Expire key seconds
- Milliseconds syntax: pexpire key milliseconds
127.0.0.1:6379> expire test 120
(integer) 1
Copy the code
(8) Query key life cycle (seconds)
- Second syntax: TTL key
- Millisecond syntax: PTTL key
127.0.0.1:6379> ttl test
(integer) 116
Copy the code
(9) Set to never expire
- Syntax: persist key
127.0.0.1:6379> persist test
(integer) 1
127.0.0.1:6379> ttl test
(integer) -1
Copy the code
(10) Change the key name
- Syntax: rename key newkey
127.0.0.1:6379> rename test ideal
OK
127.0.0.1:6379> keys *
1) "ideal"
Copy the code
(11) Clear the database
- Grammar: flushdb
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty array)
Copy the code
(12) Clear all the contents of the database
- Grammar: flushall
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379>
Copy the code
Four Operations supported by Common types
(1) String type – string
(1) storage
- Grammar: set the key value [EX seconds] [PX milliseconds] [NX | XX]
- You can optionally follow the expiration time
127.0.0.1:6379> set address beijing 5000
OK
Copy the code
(2)
- Syntax: Get key
127.0.0.1:6379 > get address "Beijing"Copy the code
(3) deleted
- Syntax: del key
127.0.0.1:6379> del address
(string) 1
Copy the code
(4) increasing or decreasing
If the value in the string is numeric, it can be incremented and decrement, and other types will report an error
- Incremental syntax: INCr key
- Incremental syntax (specify step size) : incrby key step
- Decrement syntax: decr key
- Decrement syntax (specify step size) : decrby key step
127.0.0.1:6379> set age 21 OK 127.0.0.1:6379> incr age # increment (integer) 22 127.0.0.1:6379> incrby age 5 # increment (integer) 27 127.0.0.1:6379> DECr age # decr (integer) 26 127.0.0.1:6379> DECrby age 5 # decr (integer) 21Copy the code
(5) Additional content
- Syntax: append key value
127.0.0.1:6379> set ideal hello OK 127.0.0.1:6379> Append ideal,ideal-20 # addcontent (integer) 14 127.0.0.1:6379> get ideal "hello,ideal-20"Copy the code
(6) Intercept part of the string
- Syntax: getrange key start end
127.0.0.1:6379> get ideal
"hello,ideal-20"
127.0.0.1:6379> getrange ideal 0 3
"hell"
127.0.0.1:6379> getrange ideal 0 -1
"hello,ideal-20"
Copy the code
(7) Replace part of the string
- Syntax: setrange key start
127.0.0.1:6379> get ideal "hello,ideal-20" 127.0.0.1:6379> setrange Ideal 6 BWH # replace (integer) 14 from the subindex 6 127.0.0.1:6379 > get the ideal "hello, bwhal - 20"Copy the code
(8) Get the length of value
- Syntax: strlen key
127.0.0.1:6379> strlen addr1
(integer) 7
Copy the code
(9) Only when it does not exist
- Syntax: setnx key value
- If no, create one
- If it exists, it fails
127.0.0.1:6379> setnx address guangdong # address key not found Create (integer) 1 127.0.0.1:6379> get address "guangdong" 127.0.0.1:6379> setnx address Beijing # address key exists (INTEGER) 0 127.0.0.1:6379> Get address "guangdong"Copy the code
(10) Simultaneously store and obtain multiple values
- Store multiple values simultaneously: mset key1 Value1 KEY2 Value2…
- Get multiple values simultaneously: mget key1 key2
- Store multiple values simultaneously (ensure that they do not exist) : msetNx key1 Value1 KEY2 Value2…
- This operation is atomic and fails all
127.0.0.1:6379> mset addr1 Beijing addr2 guangdong addr3 Shanghai # 127.0.0.1:6379> keys "Addr2" 3) "addr1" 127.0.0.1:6379> mget addr1 addr2 addr3 127.0.0.1:6379> msetNx age1 20 age2 25 age3 30 # Store multiple values at the same time for the first time (integer) 1 127.0.0.1:6379> msetNx age4 35 age5 40 Age1 45 # Failed to store multiple values at the same time (integer) 0 127.0.0.1:6379>Copy the code
(11) Set the object
- Syntax: key value (key for example: user:1, value is a JSON string)
127.0.0.1:6379> set user:1 {name:zhangsan,age:20} # save an object OK 127.0.0.1:6379> keys * 1) "user:1" 127.0.0.1:6379> get user:1 "{name:zhangsan,age:20}"Copy the code
- The above user:1 design is allowed in Redis, as shown in the following example
- Syntax: Object name :{id}:{filed}
127.0.0.1:6379> mset user:1:name lisi user:1:age 25
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "lisi"
2) "25"
Copy the code
(12) First get then set
- Grammar: getset
- Take the original value, and then overwrite the new value, and return nil if there is no original value
127.0.0.1:6379> getset addr Beijing # Nil (nil) 127.0.0.1:6379> get addr "Beijing" 127.0.0.1:6379> getset addr guangdong # Then overwrite new value "Beijing" 127.0.0.1:6379> get addr "guangdong"Copy the code
(2) List type – list
(1) add
A: Add elements from the left or right
- Lpush key Value: Adds elements to the left side of the list
- Rpush key Value: Adds an element to the right of the list
I’m going to add this to the one on the left, and I’m not going to show you the one on the right
127.0.0.1:6379> Lpush list1 A (integer) 1 127.0.0.1:6379> Lpush list1 B (integer) 2 127.0.0.1:6379> Lpush list1 C (INTEGER) 3 127.0.0.1:6379> lrange list1 0-1 1) "C" 2) "B" 3) "A"Copy the code
B: Insert a new value around a value
- Syntax: linsert list before/after value newvalue
127.0.0.1:6379> lrange list1 0-1 1) "A" 2) "B" 3) "C" 127.0.0.1:6379> linsert list1 before C XXX # insert XXX before C (INTEGER) 4 127.0.0.1:6379> lrange list1 0-1 1) "A" 2) "B" 3) "XXX" 4) "C"Copy the code
(2) to obtain:
A: Obtain the value according to the interval
- Syntax: lrange key start end
127.0.0.1:6379> lrange list1 0 -1 # fetching all values 1) "C" 2) "B" 3) "A" 127.0.0.1:6379> lrange list1 0 1 # fetching all values 1) "C" 2) "B"Copy the code
B: Get values based on subscripts
- Syntax: Lindex list subscript
127.0.0.1:6379> lrange list1 0-1 1) "C" 2) "B 127.0.0.1:6379> lindex list1 0 "C" 127.0.0.1:6379> lindex list1 1 "B"Copy the code
C: Gets the length of the list
- Grammar llen list
127.0.0.1:6379> llen list1
(integer) 1
Copy the code
(3) deleted
A: Remove the left-most or right-most element
- Lpop key: Removes the leftmost element in the list and returns the element
- Rpop Key: Removes the rightmost element of the list and returns the element
127.0.0.1:6379> lrange list1 0-1 1) "D" 2) "C" 3) "B" 4) "A" 127.0.0.1:6379> lpop list1 # 127.0.0.1:6379> lrange list1 0-1 1) "C" 2) "B" 127.0.0.1:6379> lrange list1 0-1Copy the code
B: Removes the specified value
- Syntax: Lrem list num value
127.0.0.1:6379> lrange list1 0-1 1) "C" 2) "C" 3) "B" 4) "A" 127.0.0.1:6379> lrem list1 1 A # Delete 1 A (integer) 1 127.0.0.1:6379> lrange list1 0-1 1) "C" 2) "C" 3) "B" 127.0.0.1:6379> lrem list1 2 C # Delete 2 C (integer) 2 127.0.0.1:6379> lrange list1 0-1 1) "B" 127.0.0.1:6379>Copy the code
C: Remove the last element and add it to another list
- rpoplpush list1 list2
127.0.0.1:6379> lrange list1 0 -1 1) "A" 2) "B" 3) "C" 127.0.0.1:6379> rpoplpopl1 127.0.0.1:6379> lrange list1 0-1 1) "A" 2) "B" 127.0.0.1:6379> lrange list2 0-1 1) "C" 127.0.0.1:6379> lrange list2 0-1 1) "C"Copy the code
(4) Intercept list according to subscript range
- Syntax: ltrim list start end
127.0.0.1:6379> Rpush list1 A (integer) 1 127.0.0.1:6379> Rpush list1 B (integer) 2 127.0.0.1:6379> Rpush list1 C (integer) 3 127.0.0.1:6379> rpush list1 D (integer) 4 127.0.0.1:6379> ltrim list1 12 # Truncate values with subscripts 1 to 2 OK 127.0.0.1:6379> lrange list1 0 -1 1) "B" 2) "C"Copy the code
(5) Replace the value of the specified subscript
Syntax: lset list subscript value
List (integer) 0 127.0.0.1:6379> lset list1 0 Beijing # Does not exist, ERR no such key 127.0.0.1:6379> lpush list1 guangdong # Create a list (integer) 1 127.0.0.1:6379> lindex list1 0 OK 127.0.0.1:6379> lindex list1 0 "Beijing"Copy the code
(3) Set type – set
Set: An unordered (not guaranteed) set whose elements cannot be repeated
(1) add
- Syntax: sadd key value
127.0.0.1:6379> sadd set1 A (integer) 1 127.0.0.1:6379> sadd set1 B (integer) 1 127.0.0.1:6379> sadd set1 C (integer) 1 127.0.0.1:6379> sadd set1 C # set values cannot be the same (integer) 0 127.0.0.1:6379> smembers set1 # Query all values of A specified set.Copy the code
(2)
A: Gets all the elements in the set
- Syntax: smembers key
127.0.0.1:6379> smesmbers set1 # query all values of A specified setCopy the code
B: Get the number of elements
- Syntax: scard set
127.0.0.1:6379> scard set1
(integer) 3
Copy the code
C: Get elements randomly
- Sembers set [num]
- The default is to get a random element, followed by a number that represents how many random elements to get
127.0.0.1:6379> smembers set1 1) "D" 2) "B" 3) "A" 4) "C" 127.0.0.1:6379> smembers set1 1) "D" 127.0.0.1:6379 > srandmember # characters to get A random element "B" 127.0.0.1:6379 > srandmember characters 2 # for two random element (1) "A" (2) "D"Copy the code
(3) deleted
A: Delete an element from the set
- Syntax: srem key value
127.0.0.1:6379> srem set1 C # delete this element (integer) 1 127.0.0.1:6379> smembers set1 1) "B" 2) "A"Copy the code
B: Randomly delete an element
- Syntax: spop set
127.0.0.1:6379> smembers set1 1) "D" 2) "B" 3) "A" 4) "C" 127.0.0.1:6379> spop set1 # randomly delete an element "A" 127.0.0.1:6379> spop Set1 # delete element "B" 127.0.0.1:6379> smembers set1 1) "D" 2) "C"Copy the code
(4) Move the specified value to another set
- Syntax: smove set1 set2 value
127.0.0.1:6379> smembers set1 1) "D" 2) "C" 127.0.0.1:6379> smove set1 set2 D # move D from set1 to set2 (integer) 1 127.0.0.1:6379> smembers set1 1) "C" 127.0.0.1:6379> smembers set2 1) "D"Copy the code
(5) Difference set of intersection union
- Sinter set1 set2: intersection
- Sunion set1 set2: union
- Sdiff set1 set2: difference set
127.0.0.1:6379> sadd set1 A (integer) 1 127.0.0.1:6379> sadd set1 B (integer) 1 127.0.0.1:6379> sadd set1 C (integer) 1 127.0.0.1:6379> sadd set2 B (integer) 1 127.0.0.1:6379> sadd set2 C (integer) 1 127.0.0.1:6379> sadd set2 D (integer) 1 127.0.0.1:6379> sadd set2 E (integer) 1 127.0.0.1:6379> sinter set1 set2 # intersection 1) "B" 2) "C" 127.0.0.1:6379> sunion set1 Set2 # union 1) "D" 2) "E" 3) "C" 4) "B" 5) "A" 127.0.0.1:6379>Copy the code
(4) Ordered set type – sortedSet /zset
This type, like set, is a collection of string elements, and no duplicate elements are allowed
The difference is that each element is associated with a double score, which redis uses to sort the members of the collection from smallest to largest
Members of an ordered set are unique, but scores can be repeated
(1) add
- Zadd key score value [score value……]
127.0.0.1:6379> zadd sortedset1 20 zhangsan # Add one (integer) 1 127.0.0.1:6379> zadd sortedset1 10 lisi 60 wangwu # add multiple (integer) 2Copy the code
(2)
A: Get all values (default sort)
- Zrange sortedSet start end [withscores]
- Sorted by the size of that value, for example, 10, 20, 60 above
127.0.0.1:6379> zrange sortedset1 0 -1
1) "lisi"
2) "zhangsan"
3) "wangwu"
Copy the code
B: Get all values (from small to large and from large to small)
- Zrangebyscore sortedSet – INF + INF: From small to large
- Zrevrange SortedSet 0-1: From large to small
1) "lisi" 2) "zhangsan" 3) "wangwu" 127.0.0.1:6379> zrevrange Sortedset1 0-1 # from big to small 1) "wangwu" 2) "zhang "3) "lisi"Copy the code
C: Gets a value with a numeric value
- Zrangebyscore sortedset -inf +inf withscores: from small to large with a value attached
127.0.0.1:6379> zrangeByScore sortedset1 - INF + INF withscores # "Wangwu "6) "60" 127.0.0.1:6379> zrangeByScore sortedset1-INF 20 withscores 1) "lisi" 2) "10" 3) "zhangsan" 4) "20" 127.0.0.1:6379>Copy the code
D: Gets the number of ordered sets
- Syntax: zcard sortedset
127.0.0.1:6379> zcard sortedset1
(integer) 2
Copy the code
E: Obtains the number of members in the specified range
- Syntax: zcount sortedset start end (strat and end are numbers, not subscripts)
127.0.0.1:6379> zcount sortedset1 10 60
(integer) 3
Copy the code
(2) removed
- zrem key value
127.0.0.1:6379> zrange sortedset1 0 - 1
1) "lisi"
2) "zhangsan"
3) "wangwu"
127.0.0.1:6379> zrem sortedset1 wangwu # Remove the wangwu element
(integer) 1
127.0.0.1:6379> zrange sortedset1 0 - 1
1) "lisi"
2) "zhangsan"
Copy the code
(5) Hash type – hash
(1) add
A: Common add
- Syntax: hset hash field value
127.0.0.1:6379> hset hash1 username admin
(integer) 1
127.0.0.1:6379> hset hash1 password admin
(integer) 1
Copy the code
B: You can add it only when it does not exist
- Syntax: hsetNx Hash filed Value
127.0.0.1:6379> hsetnx hash1 username admin888 # exists, failed (integer) 0 127.0.0.1:6379> hsetNx hash1 code 666 # does not exist Success (integer) 1Copy the code
(2)
A: Gets the value of the specified field
- Syntax: hget hash field [key field……]
127.0.0.1:6379> hget hash1 password
"admin"
Copy the code
B: Get all fields and values
- Syntax: hgetall Hash
127.0.0.1:6379> hgetall hash1
1) "username"
2) "admin"
3) "password"
4) "admin"
Copy the code
C: Obtains the number of hash fields
- Syntax: hlen hash
127.0.0.1:6379> hlen hash1
(integer) 2
Copy the code
D: Only all fields or values are obtained
- Hkeys hash: Obtains all field fields
- Hvals hash: Retrieves all values
127.0.0.1:6379> hkeys hash1 # delete (hash (1) and (hash (2))) "admin" 2) "admin"Copy the code
(3) deleted
- Syntax: hdel Hash field
127.0.0.1:6379> hdel hash1 username
(integer) 1
Copy the code
(4) Self-increase and self-decrease
- Hincrby Hash field increment
127.0.0.1:6379> hsetnx hash1 code 666
(integer) 1
127.0.0.1:6379> hincrby hash1 code 2
(integer) 668
127.0.0.1:6379> hincrby hash1 code -68
(integer) 600
Copy the code
Five three special data types
(1) Geospatial
Use latitude and longitude as geographic coordinates and store them in an ordered set zset/sortedset, so commands in zset can also be used
- Especially when you need to delete a location, there is no GEODEL command because you can use ZREM to delete an element whose structure is an ordered structure.
- Geospatial is a type that can be used to store city coordinates. Generally, it is not input by itself, because the city data is fixed, so it is directly imported through Java. The following are some examples
- Geospatial can also be used to realize the concept of nearby people. Each location is the current longitude and latitude of a person, and there are some methods to measure distance and so on, which will be mentioned later
Command list:
(1) Store latitude and longitude
-
Syntax: Geoadd key longitude latitude member [..]
-
Longitud, latitude
-
Effective longitude ranges from -180 degrees to 180 degrees.
-
Valid latitudes range from -85.05112878 degrees to 85.05112878 degrees.
-
127.0.0.1:6379> geoAdd China: City 116.413384 39.910925 Beijing (integer) 1 127.0.0.1:6379> geoAdd China: City 113.271431 23.135336 Guangzhou (integer) 1 127.0.0.1:6379> Geoadd China: City 113.582555 22.276565 zhuhai (integer) 1 Geoadd China: City 112.556391 37.876989 TAIYUAN (integer) 1Copy the code
(2) Obtain the coordinates of one or more members of the set
- Geopos key member [member..]
Geopos China: City Beijing Zhuhai 1) 1) "116.41338318586349487" 2)" "116.41338318586349487" 2) "39.9109247398676743"Copy the code
(3) Returns the distance between two given positions
-
Geodist key member1 member2 [unit]
-
The default unit is meter, which can be changed after member, such as km
-
The parameter unit specifying the unit must be one of the following:
-
M is in meters
-
Km is expressed in kilometers
-
Mi means miles
-
Ft is in feet
-
-
127.0.0.1:6379> geodist china:city guangzhou taiyuan
"1641074.3783"
127.0.0.1:6379> geodist china:city guangzhou taiyuan km
"1641.0744"
Copy the code
(4) Find nearby elements (given latitude and longitude and length)
-
Meaning: Returns the location element of the collection, centered on the given latitude and longitude
-
Grammar: georadius key longitude latitude | km radius m | mi | ft [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT COUNT]
-
All positional elements within a given maximum distance from the center
-
The function of nearby people can be completed through Georadius (for example, the position we input is the current position of people).
-
Withcoord: With coordinates
-
Withdist: with distance, in the same units as radius
-
Count: display only the first n (sort by increasing distance)
-
-
127.0.0.1:6379> Georadius China: City 113.582555 22.276565 500 km 1) "zhuhai" 2) "Guangzhou" 127.0.0.1:6379> Georadius China: City 113.582555 22.276565 500 km Withdist withcoord count 11) 1) "zhuhai" 2) "0.0002" 3) 1) "113.58255296945571899" 2) "22.27656546780746538" 127.0.0.1:6379> Georadius China: City 113.582555 22.276565 500 km Withdist withcoord count 1) 1) "zhuhai" 2) "0.0002" 3) 1) "113.58255296945571899" 2) "22.27656546780746538" 2) 1) 1) "113.27143281698226929" 2) "23.13533660075498233"Copy the code
(5) Search for nearby elements (specify existing members and length)
-
Meaning: 5 is the same as 4, given not the latitude and longitude but the existing members of the set
-
GEORADIUSBYMEMBER key member RADIUS…
127.0.0.1:6379> Georadiusbymember China :city zhuhai 500 km 1) "zhuhai" 2) "guangzhou"Copy the code
(6) Return a Geohash representation of one or more positional elements
- Syntax: GeoHash key member1 [member2..]
127.0.0.1:6379> GeoHash China :city zhuhai 1) "weby8xk63k0"Copy the code
(2) Hyperloglog (Cardinal statistics)
HyperLogLog is an algorithm for counting cardinality (the number of non-repeating elements in a data set). Its underlying type is string
The advantages of HyperLogLog are:
- When the number or volume of input elements is very, very large, the space required to calculate the cardinality is always fixed and small
- With 12 KB of memory, you can calculate the cardinality of nearly 2^64 different elements
Because HyperLogLog only calculates cardinality from the input elements and does not store the input elements themselves, HyperLogLog cannot return individual elements of the input, as collections do
A common example:
- In the traditional implementation, the user id is stored and compared each time. This is a waste of space as the number of users increases and our goal is just to count, so Hyperloglog can help us do it with minimal space.
(1) add
Add the specified element to HyperLogLog
Syntax: PFADD key element1 [elememt2..]
127.0.0.1:6379> pfadd test1 A B C D E F G
(integer) 1
127.0.0.1:6379> pfadd test2 C C C D E F G
(integer) 1
Copy the code
(2) Estimate the cardinality of myelx
Meaning: Returns the cardinality estimate for the given HyperLogLog
PFCOUNT key [key]
127.0.0.1:6379> pfcount test1
(integer) 7
127.0.0.1:6379> pfcount test2
(integer) 5
Copy the code
(3) the merger
Description: Merge multiple HyperLogLog into one HyperLogLog
PFMERGE destkey sourcekey [sourcekey..]
127.0.0.1:6379> pfmerge test test1 test2
OK
127.0.0.1:6379> pfcount test
(integer) 9
Copy the code
(3) BitMaps
BitMaps are stored in bits, with information states of only 0 and 1
- A Bitma p is a series of consecutive binary digits (0 OR 1), each of which is offset. Operations on a bitmap can be performed on AND,OR,XOR,NOT, AND other bits
- This type can be used in many scenarios, such as counting whether employees clock in or not, whether they are logged in or not, and whether they are active or not
(1) set values
- Description: Sets the offset bit of the specified key
- Syntax: setbit key offset value
127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(integer) 0
127.0.0.1:6379> setbit sign 2 0
(integer) 0
127.0.0.1:6379> setbit sign 3 0
(integer) 0
127.0.0.1:6379> setbit sign 4 1
(integer) 0
127.0.0.1:6379> setbit sign 5 1
(integer) 0
127.0.0.1:6379> setbit sign 6 1
(integer) 0
Copy the code
(2)
- Gets the value of offset bit
- Syntax: getbit key offset
127.0.0.1:6379> getbit sign 4
(integer) 1
127.0.0.1:6379> getbit sign 2
(integer) 0
Copy the code
(3) statistics
- Description: The number of bits in the statistics string to be set to 1. The statistics range can also be specified in bytes
- Bitcount key [start end]
127.0.0.1:6379> bitcount sign
(integer) 4
Copy the code
Six transaction
(1) Definition
Definition: Redis transactions are essentially a collection of commands
- Transactions allow multiple commands to be executed at once, and all commands in a transaction are serialized
- During the execution of a transaction, commands in the execution queue are sequentially serialized, and command requests submitted by other clients are not inserted into the transaction execution command sequence
Redis transactions are one-time, sequential, and exclusive executions of a series of commands in a queue
First of all,
(2) Characteristics
(1) Atomicity is not guaranteed
Because of the influence of relational databases, people tend to generalize and think that transactions in databases are atomic, but in fact, transactions in Redis are non-atomic.
Atomicity: all operations must be done or not be done at all. The transaction must be the smallest unit of matter, like the atom in a chemical group.
- When a transaction is committed and both tables are updated, if either table fails, the transaction will be rolled back
Nonatomic: The opposite of atomic
- When a transaction is committed, both tables t1 and T2 are updated. If one table fails and the other table continues, the transaction will not be rolled back
(2) Transaction rollback is not supported
Most transaction failures are caused by syntax errors, which are detected before the command is enqueued, or data structure type errors, which are detected at execution time. Redis uses this simple transaction to improve performance
(3) There is no concept of isolation level for transactions
Batch operations are placed in the queue cache before the EXEC command is sent and are not actually executed, so there is no query within the transaction to see the update, but not to see the update for the query outside the transaction
(3) Relevant orders
(1) Start the transaction
Meaning: Start a transaction, the next step is to queue the contents one by one, and then execute them atomically through exec command
Command: multi
Since multi and exec need to be used together, the examples are shown in the second point
(2) Execute transaction
Meaning: Performs all operations in a transaction
Command: exec
A: A transaction is normally started and executed
First, save a k1 and k2, start the transaction, modify these two values, and then execute the transaction, and finally find two OK, and then use get to check the value change
127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> set k2 v2 OK 127.0.0.1:6379> multi # enable transaction OK 127.0.0.1:6379> set k1 v11 # K1 QUEUED 127.0.0.1:6379> set k2 v22 # QUEUED 127.0.0.1:6379> exec # exec 1) OK 2) OK 127.0.0.1:6379> get k1 "V11" 127.0.0.1:6379> get k2 "v22"Copy the code
B: Transaction failed due to syntax error
If the transaction fails due to syntax error (compiler error), it will keep the original value. For example, in the following transaction, there is no problem in modifying K1, but there is a syntax error when modifying K2. Set is written as sett, and exec is executed, and finally it is found that k1 and k2 are unchanged
127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> set k2 v2 OK 127.0.0.1:6379> multi # enable transaction OK 127.0.0.1:6379> set k1 v11 # QUEUED 127.0.0.1:6379> sett k2 v22 # error error ERR unknown command 'sett', with args beginning with: `k2`, `v22`, 127.0.0.1:6379> exec # Execute Transaction discarded because of previous errors EXECABORT Transaction discarded. 127.0.0.1:6379> get k1 "V1" 127.0.0.1:6379> get k2 "v2"Copy the code
C: The transaction fails due to type error
A transaction exception caused by a type error (runtime error), such as the following k2 being treated as a list, will be reported at runtime and the transaction will fail, but will not be rolled back, resulting in k1 successfully modified and K2 failed
127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> set k2 v2 OK 127.0.0.1:6379> multi # enable transaction OK 127.0.0.1:6379> set k1 v11 QUEUED 127.0.0.1:6379> lpush k2 V22 # Type error QUEUED 127.0.0.1:6379> exec # Execute transaction 1) OK 2) (error) WRONGTYPE Operation Against a key holding the wrong kind of value 127.0.0.1:6379> get k1 "v11" 127.0.0.1:6379> get k2 "v2"Copy the code
(3) Cancel the transaction
There’s nothing to say about that. Just cancel it
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 k11
QUEUED
127.0.0.1:6379> set k2 k22
QUEUED
127.0.0.1:6379> discard
OK
Copy the code
(4) watch monitoring
Redis commands are atomic, while transactions are non-atomic. The watch command can achieve a rollback effect of Redis
The idea is to use Watch to monitor some key-value pairs before Multi, and then continue to start and execute transactions
- If the monitored key-value pairs do not change when exec executes the transaction, it executes the commands in the transaction queue
- If the monitored key-value pairs change while exec executes the transaction, then no commands in the transaction are executed and the actions in the transaction are cancelled
We monitor K1, and then we modify K1 before the transaction starts, and then we want to modify K1 in the transaction, and we see that in the end, none of the operations in the transaction are executed
127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> set k2 v2 OK 127.0.0.1:6379> watch k1 # monitor k1 OK 127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> set k2 v2 OK 127.0.0.1:6379> watch k1 # monitor k1 OK 127.0.0.1:6379> set k1 127.0.0.1:6379> set k1 v11 QUEUED 127.0.0.1:6379> set k2 v22 QUEUED 127.0.0.1:6379> get k1 "v111111" 127.0.0.1:6379> get k2 "v2"Copy the code
(5) Unwatch Cancel monitoring
After cancellation, it can be executed normally
127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> set k2 v2 OK 127.0.0.1:6379> watch k1 # monitor OK 127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> set k2 v2 OK 127.0.0.1:6379 V111111ok 127.0.0.1:6379> multi OK 127.0.0.1:6379> set k1 v11 QUEUED 127.0.0.1:6379> Set k2 v22 QUEUED 127.0.0.1:6379> exec 1) OK 2) OK 127.0.0.1:6379> get k1 "v11" 127.0.0.1:6379> get k2 "v22"Copy the code
Use Jedis to operate Redis in seven IDEA
Jedis is a blazingly small and sane Redis java client.
Jedis was conceived to be EASY to use.
Jedis is a tool that allows you to manipulate your Redis database in Java. It is easy to download the JAR package or import it into Maven
(1) Introducing dependencies and encoding
I created an empty project here and then created a normal Maven module to demonstrate Jedis
Jedis dependencies were introduced first, and fastJSON was introduced later as needed
You can check the version in Maven, because the redis installed in Linux is a new version, so we rely on and use the latest version
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
</dependencies>
Copy the code
Creating a test class
- On a local machine, such as Windows, start the Redis service under Win and access it with 127.0.0.1
- For a remote machine, VM, or cloud server, use the corresponding IP address
- The new Jedis space-time construct represents the default “localhost”, port 6379
public class Demo01 {
public static void main(String[] args) {
// Remote Linux (vm)
Jedis jedis = new Jedis("192.168.122.1".6379);
// Check whether it is connectedSystem.out.println(jedis.ping()); }}Copy the code
(2) The procedure for connecting to Linux
If you enter the IP address and port number, the connection fails. Therefore, you need to perform the following operations first
① Ensure that port 6379 is open
Take centos 7.9 as an example, for other versions such as 6.x, you can check the specific command and whether the firewall is blocked, as long as the port can be accessed
- Enable port 6379
firewall-cmd --zone=public --add-port=6379/tcp --permanent
#According to
succss
Copy the code
- Restarting the Firewall
firewall-cmd --reload
#According to
success
Copy the code
- Check whether the port is enabled
firewall-cmd --query-port=6379/tcp
#According to
yes
Copy the code
- Restart the Redis service
[root@centos7 bin]# redis-cli shutdown
[root@centos7 bin]# redis-server myconfig/redis.conf
Copy the code
You can also use Telnet 192.168.122.1 6379 on a Windows machine to test whether the access is available. If an error occurs, check the port and firewall
② Modify the Redis configuration file
-
Comment the IP address to bind (comment bind 127.0.0.1)
-
Set protected-mode to no
- On Linux, Redis is in secure mode, which prevents you from easily establishing connections from outside the virtual machine, so set protected-mode to no in redis.conf
Visit IDEA again and you can access it
(3) Common APIS
(1) String type – String
/ / store
jedis.set("address"."beijing");
/ / to get
String address = jedis.get("address");
// Close the connection
jedis.close();
Copy the code
Add: the setex() method can store data and specify an expiration time
// Save aaA-BBB and expire after 10 seconds
jedis.setex("aaa".10."bbb")
Copy the code
(2) List type – list
/ / store
jedis.lpush("listDemo"."zhangsan"."lisi"."wangwu");/ / from the left
jedis.rpush("listDemo"."zhangsan"."lisi"."wangwu");/ / from the right
/ / to get
List<String> mylist = jedis.lrange("listDemo".0, -1);
// Delete, and return the element
String e1 = jedis.lpop("listDemo");/ / from the left
String e2 = jedis.rpop("listDemo");/ / from the right
// Close the connection
jedis.close();
Copy the code
(3) Set type – set
/ / store
jedis.sadd("setDemo"."zhangsan"."lisi"."wangwu");
/ / to get
Set<String> setDemo = jedis.smembers("setDemo");
// Close the connection
jedis.close();
Copy the code
(4) Ordered set type – sortedSet /zset
/ / store
jedis.zadd("sortedsetDemo".20."zhangsan");
jedis.zadd("sortedsetDemo".10."lisi");
jedis.zadd("sortedsetDemo".60."wangwu");
/ / to get
Set<String> sortedsetDemo = jedis.zrange("sortedsetDemo".0, -1);
// Close the connection
jedis.close();
Copy the code
(5) Hash type
/ / store
jedis.hset("hashDemo"."name"."lisi");
jedis.hset("hashDemo"."age"."20");
/ / to get
String name = jedis.hget("hashDemo"."name");
// Get all the data
Map<String, String> user = jedis.hgetAll("hashDemo");
Set<String> keySet = user.keySet();
for (String key : keySet) {
/ / get the value
String value = user.get(key);
System.out.println(key + ":" + value);
}
// Close the connection
jedis.close();
Copy the code
(4) Jedis executes transactions
public class Demo01 {
public static void main(String[] args) {
// Remote Linux (vm)
Jedis jedis = new Jedis("192.168.122.1".6379);
JSONObject jsonObject = new JSONObject();
jsonObject.put("name"."zhangsan");
jsonObject.put("age"."21");
// Start the transaction
Transaction multi = jedis.multi();
String result = jsonObject.toJSONString();
try {
multi.set("userA", result);
multi.set("userB", result);
// Execute a transaction
multi.exec();
} catch (Exception e) {
// Discard the transaction
multi.discard();
} finally {
System.out.println(jedis.get("userA"));
System.out.println(jedis.get("userB"));
// Close the connectionjedis.close(); }}}Copy the code
To display the results, add two output statements before closing
Execution Result:
{“name”:”zhangsan”,”age”:”21″} {“name”:”zhangsan”,”age”:”21″}
(5) Jedis connection pool
Why do we use connection pooling?
We need to establish a connection to use Jedis, and we need to establish a connection every time we conduct data interaction. Although Jedis has high performance, it takes more time to establish a connection. If the connection pool is used, multiple connections can be established on the client at the same time and not released. When connecting, you only need to obtain the established connections in a certain way, and then return them to the connection pool. In this way, time is greatly saved
Here we create a connection pool directly, but we usually use it to encapsulate a utility class
@Test
public void testJedisPool(a){
Create a configuration object
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(50);
config.setMaxIdle(10);
Create a Jedis connection pool object
JedisPool jedisPool = new JedisPool(config,"192.168.122.1".6379);
// 2. Obtain the connection
Jedis jedis = jedisPool.getResource();
/ / 3. Storage
jedis.set("name"."zhangsan");
// 4. Output the result
System.out.println(jedis.get("name"));
//5. Close return to connection pool
jedis.close();;
}
Copy the code
(1) Connection pool utility class
Use utility classes directly
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/** * JedisPool utility class * load configuration file, configure the parameters of the connection pool * provide methods to obtain connections */
public class JedisPoolUtils {
private static JedisPool jedisPool;
static {
// Read the configuration file
InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
// Create a Properties object
Properties pro = new Properties();
// Associated file
try {
pro.load(is);
} catch (IOException e) {
e.printStackTrace();
}
// Get data and set it to JedisPoolConfig
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));
// Initialize JedisPool
jedisPool = new JedisPool(config, pro.getProperty("host"), Integer.parseInt(pro.getProperty("port")));
}
/** * get the connection method */
public static Jedis getJedis(a) {
returnjedisPool.getResource(); }}Copy the code
Don’t forget configuration files
host=192.168.122.1
port=6379
maxTotal=50
maxIdle=100
Copy the code
The calling code
@Test
public void testJedisPoolUtil(a){
// 0. Obtain it from the connection pool tool class
Jedis jedis = JedisPoolUtils.getJedis();
/ / 1. Use
jedis.set("name"."lisi");
System.out.println(jedis.get("name"));
// 2. Close return to connection pool
jedis.close();;
}
Copy the code
SpringBoot integration with Redis
(a) Simple use (there are serialization problems)
① Create a Springboot project or module to import dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Copy the code
As you can see, the official starter introduces Redis, but not Jedis, but Lettuce
Jedis: Direct connection, multi-thread operation, is not safe. To avoid insecurity, use the Jedis Pool connection pool! More like BIO mode
Lettuce: With Netty, instances can be shared between multiple threads, no thread insecurity! Can reduce thread data, more like NIO mode
② Write a configuration file
# configuration redis
spring.redis.host=192.168.122.1
spring.redis.port=6379
Copy the code
③ Test code
@SpringBootTest
class Redis02BootApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads(a) {
redisTemplate.opsForValue().set("name"."zhangsan");
System.out.println(redisTemplate.opsForValue().get("name")); }}Copy the code
Running results:
zhangsan
(2) Use custom RedisTemplate template (recommended)
The above operation, in the result of IDEA is certainly no problem, but we go to Linux to look at the content of Redis, but found that the key is garbled, for example, the storage name is changed into the following content
127.0.0.1:6379> keys * 1) "\xac\xed\x00\x05t\x00\ x04Name"Copy the code
This is the serialization problem, which we’ll examine in the following sections. The solution is to customize the RedisTemplate template
① Customize the RedisConfig class
@Configuration
public class RedisConfig {
/** * Custom RedisTemplate rage ban **@param factory
* @return* /
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
,>
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
// Json serialization configuration
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// Serialization of String
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// Key uses String serialization
template.setKeySerializer(stringRedisSerializer);
// The hash key also uses String serialization
template.setHashKeySerializer(stringRedisSerializer);
// Value serialization uses Jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// The hash value serialization method uses Jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
returntemplate; }}Copy the code
(2) call
@SpringBootTest
class Redis02BootApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads(a) {
redisTemplate.opsForValue().set("address"."beijing");
System.out.println(redisTemplate.opsForValue().get("address")); }}Copy the code
We have name2 and address, so let’s go to the terminal
127.0.0.1:6379> keys * 1) "address" 2) "\ xacxed \x00\x05t\x00\ x04Name "3) "name2"Copy the code
As you can see, the problem is solved
(3) Encapsulate a utility class
We pursue the operation is convenient, and every time is to use a lot of redisTemplate. OpsForValue () XXXXX long command, so enclose a utility class can get twice the result with half the effort, specific tools posted, I am not here for too long, I will to making up behind and then update links, Of course baidu is actually a lot of search
For example, using the utility class, we can easily use the method that encapsulates the redisTemplate
@Autowired
private RedisUtil redisUtil;
@Test
void contextLoads(a) {
redisUtil.set("address2"."zhuhai");
System.out.println(redisUtil.get("address2"));
}
Copy the code
(4) Simple analysis principle
In this simple analysis, we mainly want to make clear four contents
- Should we stop using Jedis and use Lettuce instead
- 2 View the configuration properties of the configuration file
- ③ How to operate Redis
- ④ Serialization problem (i.e. storage garble problem)
In the previous Springboot article on the principle of auto-configuration, when you integrate a content, you always have an auto-configuration class, and then you can find its fully qualified class name in spring. Factories
Go into Spring. factories and find the autowiring classes for Redis
After entering the RedisAutoConfiguration class, you can see the existence of the RedisProperties class in the annotations, which is clearly about configuration files
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
// This annotation!!
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
/ /... omit
}
Copy the code
Enter the RedisProperties class
Alt + 7 allows you to view the properties of this class in IDEA
For example, the configuration of address port, timeout time and so on is clear, for example, our configuration file at that time is configured like this
# configuration redis
spring.redis.host=192.168.122.1
spring.redis.port=6379
Copy the code
Going back to the class, look at the following annotation and see that there are two classes
-
LettuceConnectionConfiguration
-
JedisConnectionConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
// This annotation!!
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
/ /... omit
}
Copy the code
GenericObjectPool and Jedis are missing by default, so they don’t take effect
Take a look at LettuceConnectionConfiguration, it is no problem, so now is the default implementation is to use the Lettuce
Continue back to RedisAutoConfiguration
There are only two beans
- RedisTemplate
- StringRedisTemplate
Xxxtemplates, such as JdbcTemplate, RestTemplate, etc., operate on these components through templates, so the two templates here are also fine. String data types used to manipulate Redis and Redis respectively (because String is very common)
/ / note slightly
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
returntemplate; }}Copy the code
Pay special attention to this one note
@ConditionalOnMissingBean(name = "redisTemplate")
Copy the code
It means that if you don’t customize it, you’ll use it by default, which tells us that we can customize the Template to override the default, and as we’ve seen in the past, using the default Template involves garbled, serialization issues
Because objects moving across the network need to be serialized, otherwise they are garbled
Let’s go to the default RedisTemplate and see
The first thing you’ll see is some parameters for serialization
Looking down, you can see that the default serialization uses Jdk serialization, while our customization uses Json serialization
All serializers in the default RedisTemplate use this serializer
RedisSerializer provides a variety of serialization methods
So we customized the RedisTemplate template to redefine the various types of serialization, which is what we recommend