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:

  1. Supports complex query operations on one table and multiple tables
  2. Support the processing of things, to ensure data security requirements
  3. 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/homedirectory

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