[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

Time:2021-3-24

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

Redis basic and advanced two articles have all been updated, for word limit and easy reading, divided into two release.

The main content of this article is: NoSQL introduces redis, as well as the installation and configuration under the environment of linux7, and summarizes the very detailed types, usage and examples. Finally, remote operation in idea is realized through jedis and redistemplate in springboot
Redis。

The second article mainly deals with a basic use of some advanced usages, such as configuration file, publish subscribe, master-slave copy, sentry, etc.

A brief introduction to NoSQL

Redis is an open source, network-based, memory based, and optional persistent key value pair storage database, Wikipedia, written in ANSI C

In a nutshell,Redis is a high performance NoSQL database

(1) What is NoSQL?

What we learned earlierMysql databaseIt’s typicalSQL databaseThat is, the traditional relational database, but what we learn todayRedis databaseIs a NoSQL database, also known as non relational database, it is completely different from the familiar concept of MySQL, it is a new database concept, we post a group of Baidu Encyclopedia explanation

NoSQL, generally refers to non relational database. With the rise of Internet Web2.0 website, traditional relational database in dealing with Web2.0 website, especially the super large-scale and high concurrency SNS type Web2.0 pure dynamic website has been unable to cope with, there are many problems that are difficult to overcome, but the non relational database has been very rapid development due to its own characteristics. The production of NoSQL database is to solve the challenge of large-scale data collection and multiple data types, especially the big data application problem Baidu Encyclopedia

Description: the blogs we see now, RSS, P2P, micro-blog, jitter, etc. belong to the product of Web2.0. Web2.0 compared with the past Web1.0, it paid more attention to user interaction. Users can browse not only tiktok, but also upload some resources to websites, such as text or short video, so that users are also involved in the content of the website.

(2) Why NoSQL?

  • Low deployment cost: simple deployment operation, mainly open source software
  • Rich storage format: support key value form, document, picture and many other forms, including object or collection format
  • Fast: the data is stored in the cache, not in the hard disk, and for example, redis is based on key value pairs, and does not need to go through SQL layer parsing, so the performance is very high
  • No coupling, easy to expand

    • In SQL, a data in use is not allowed to be deleted, but NoSQL can operate

(3) Can NoSQL replace SQL?

Some people will say that NoSQL = not SQL, but I prefer to understand NoSQL = not only SQL in this way. We can’t judge the quality of the two technologies with an absolute conclusion. Each technology has its own specific reasons. In my opinion,NoSQL is more suitable as a supplement to SQL databaseDue to the emergence of massive data, the performance requirements are higher, and NoSQL, as a product, is very important forThe structure is simplehoweverLarge amount of dataThe data processing of SQL is much faster than that of traditional SQLThe logic operation must be very simpleOtherwise, it is not enough

In my opinion, NoSQL can simply say that it is to exchange function for performance, but it needs to be improvedDealing with complex business logicIt also needs to be usedRelational databaseTherefore, it is unrealistic to completely replace SQL with NoSQL in the model, which is more like a complementary relationship

Benefits of SQL

  1. Support complex query operation before one table and multiple tables
  2. Support the processing of things, can ensure the security requirements of data
  3. The cost of learning is low and there are many materials

There are many NoSQL products on the market. What we are going to introduce today is redis, one of the databases based on key value storage

(4) Analysis of four classification tables of NoSQL database

classification Examples Typical application scenarios data model advantage shortcoming
Key value Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB Content caching is mainly used to handle the high access load of a large amount of data, and also used in some log systems and so on. Key refers to the key value pair of value, which is usually implemented with hash table Fast search speed Data is unstructured and is usually treated as string or binary data
Column storage database Cassandra, HBase, Riak Distributed file system The data in the same column is stored in a column cluster It has the advantages of fast search speed, strong scalability and easy distributed expansion The function is relatively limited
Document database CouchDB, MongoDb Web application (similar to key value, value is structured, but database can understand the content of value) The key value pair corresponding to the key value, and the value is structured data The requirement of data structure is not strict, and the table structure is variable, so there is no need to define the table structure in advance like relational database Query performance is not high, and lack of unified query syntax.
Graph database Neo4J, InfoGrid, Infinite Graph Social network, recommendation system, etc. Focus on building a relationship map Graph structure Using graph structure correlation algorithm. For example, the shortest path addressing, n-degree relation searching and so on Most of the time, we need to calculate the whole graph to get the required information, and this structure is not good for distributed cluster solution.

Second meeting redis

(1) What is redis

We mentioned it at the beginning,Redis is a high performance NoSQL databaseWhat are its application scenarios?

  • For user content caching, it can handle high access load of a large amount of data, such as data query, news, commodity content
  • Task queue, such as: seckill, 12306
  • Online friends list
  • Application and website access statistics ranking

Since it is based on key value storage, what types of storage can be supported?

  • String type – string
  • List – List: LinkedList
  • Set – set
  • Ordered set sortedset
  • Hash hash: Map

(2) Download and install

explain:

Linux is recommended for deployment, so we will introduce the installation and configuration of Linux in detail later. However, if you just want to learn grammar quickly, you can use the Windows version reluctantly, and the installation will be much easier.

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.

Official website address:https://redis.io/topics/intro…

(1) Linux recommendation

Official website: https://redis.io (recommended)

  • Access may be slow

Chinese website: http://www.redis.net.cn

  • For example, the official website is 6.0.9, and the home page of Chinese website is still 5.0.4

A: Download

#Download redis-6.0.9 package
wget http://download.redis.io/releases/redis-6.0.9.tar.gz

Supplement:

  • Can pass http://download.redis.io/rele… View and select the required version
  • The compressed file downloaded in this way is located in/homeUnder the directory

B: Decompression

Generally speaking, our program will be placed in the/optDirectory, so we first move the compressed file and then unzip it

#Move this file to the opt directory under the root directory
mv redis-6.0.9.tar.gz /opt
#Unzip this file
tar -zxvf redis-6.0.9.tar.gz

After decompression, a redis-6.0.9 folder will appear in the opt directory. We can open it and see some files in it redis.conf It’s the configuration file we’ll use later. Ignore it for the moment

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

It seems that the unzipped files can’t run, of course, because these files haven’t been compiled and installed. Before compiling, first check the GCC version

C: Check GCC Version (redis 6 or below can be ignored)

If you choose redis 6 or above, for example, 6.0.9, if your GCC version is too low, it will lead to compilation errors. At least your GCC version should be 5.3 or above

If there is no GCC, install it first

yum -y install gcc
 
yum -y install gcc-c++

After the installation, thegcc -vIt is found that the installed version is 4. X.x, so to upgrade, the old version of redis can not upgrade

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 start of SCL command is only temporary. Exiting shell or restarting will restore the GCC version of the original system
scl enable devtoolset-9 bash

#Long term use of GCC 9.3 also requires the following operations
echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
source /etc/profile

Check out the updated version

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

D: Compile and install

Compile and install in turn,

#Compile
make

#Installation
make install

Make will slow down and wait patiently. If something goes wrong, it’s usually a GCC problem

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

The content after installation is generally in the/usr/local/bin lower

E: Copy configuration file

We put the original configuration file in the decompression file, which we use and copy separately to facilitate our operation and change

Let’s go first/usr/local/binCreate a new folder in, and then extract the redis.confCopy it

#Jump to the specified directory
cd /usr/local/bin
#Create a new folder
mkdir myconfig
#Replication / opt / redis-6.0.9/ redis.conf  Go to the myconfig folder in the current directory
cp /opt/redis-6.0.9/redis.conf myconfig

Take a look at the process

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

F: Start background operation

In order to ensure that our redis can run in the background, we edit and copy it redis.conf configuration file

vim redis.conf

Found in itdaemonize no

Change no to yes, save and exit

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

G: Run redis

Now let’s run the server (to ensure that theusr/local/bin(Part 2)

#Running server
redis-server myconfig/redis.conf
  • Add myconfig/ redis.conf It is to make the configuration file for its startup

Then run its client

#Run client
redis-cli -p 6379
  • Because it is the local machine, so you only need to specify the port, not the IP

You can simply test it, such as set get. If you can get the value, it means success

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

H: Shut down the service and check if the process exists

Let’s take a look at the existence of the process when it is running

#View redis process
ps -ef|grep redis

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

In the client, you can shut down through shutdown and exit (this is done in the redis client)

#Closing
127.0.0.1:6379> shutdown
not connected> exit

#Check the progress again
[[email protected] bin]# ps -ef|grep redis

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

(2) Not recommended by windows

We can go to GitHub to find the Windows version, but the version will lag behind, at least the official does not support the update, maybe Microsoft still wants to drag him. The latest version seems to be several years ago

https://github.com/microsofta…

Decompression is available: start redis separately- server.exe And redis- cli.exe Can you test and use it directly? If there is any problem, please modify it redis.windows.conf configuration file

  • redis- server.exe : redis server
  • redis- cli.exe : redis client
  • redis.windows.conf : Profile

3. Redis General Command

(1) Opening and closing command

(1) Start redis service

redis-server [--port 6379]

Sometimes there are too many parameters. It is recommended to use configuration file to start

redis-server [xx/redis.conf]

For example:redis-server myconfig/redis.conf

(2) Client connection to redis

redis-cli [-h 127.0.0.1 -p 6379]

For example:redis-cli -p 6379

(3) Stop redis

In the client (marked with 127.0.0.1:6379 >), you can directly enter shutdown, etc

#Closing
127.0.0.1:6379> shutdown
not connected> exit

If it is in the directory$And so on)

redis-cli shutdown
kill redis-pid

(4) Test connectivity

Return to Pong to connect

127.0.0.1:6379> ping
PONG

(2) Key and general operation

Note: the storage mode of each type is different, so the operation here will not talk about adding storage, which will be explained in detail in each type below.

Just want to test first, you can use these commands temporarily (this is string type)

  • have access toset key valueadd to

    • Set is the command, key is the key, and value is the value
    • For example:set test ideal-20
  • get keyGet value

(1) Get all keys

  • Syntax: keys pattern
127.0.0.1:6379> keys *
1) "test"
2) "test2"
  • *As a wildcard, it represents any character, because it will traverse all the keys, and then display all the key lists. The time complexity is O (n), and it should be used cautiously in the environment with large amount of data

(2) Get the total number of keys

  • Syntax: dbsize
127.0.0.1:6379> dbsize
(integer) 2
  • The internal variable stores this value. When the acquisition operation is performed, it is non ergodic, so the time complexity is O (1)

(3) Judge whether the current key exists

  • Syntax: exists key [key…]
127.0.0.1:6379> exists test
(integer) 1
  • The last return is the number of existence

(4) Query key type

  • Syntax: type key
127.0.0.1:6379> type test
string

(5) Mobile key

  • 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"
  • Note: redis has 16 databases by default. Move represents which one to move to, and select represents switching to this database

(6) Delete key

  • Syntax: del key [key…]
127.0.0.1:6379> del test2
(integer) 1

(7) Set expiration time

  • Second syntax: expire key seconds
  • Millisecond syntax: pexpire key milliseconds
127.0.0.1:6379> expire test 120
(integer) 1

(8) Life cycle of query key (seconds)

  • Second syntax: TTL key
  • MS syntax: pttl key
127.0.0.1:6379> ttl test
(integer) 116

(9) Settings never expire

  • Syntax: persist key
127.0.0.1:6379> persist test
(integer) 1
127.0.0.1:6379> ttl test
(integer) -1

(10) Change the name of the key

  • Syntax: Rename key newkey
127.0.0.1:6379> rename test ideal
OK
127.0.0.1:6379> keys *
1) "ideal"

(11) Clear current database

  • Grammar: flushdb
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty array)

(12) Clear all database contents

  • Grammar: flushall
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> 

Four common types of support operations

(1) String type – string

(1) Storage

  • Syntax: set key value [ex seconds] [PX milliseconds] [nx|xx]

    • Later, you can follow the expiration time selectively
127.0.0.1:6379> set address beijing 5000
OK

(2) Get

  • Syntax: get key
127.0.0.1:6379> get address
“beijing”

(3) Delete

  • Syntax: del key
127.0.0.1:6379> del address
(string) 1

(4) Increasing or decreasing

If the value in the string is of numeric type, it can be incremented or decremented, and other types will report errors

  • Incremental syntax: incr key
  • Incremental syntax: incrby key step
  • Decrement syntax: decr key
  • Decrement syntax: decrement by key step
127.0.0.1:6379> set age 21 
OK
127.0.0.1:6379 > incr age # increasing
(integer) 22 
127.0.0.1:6379 > incrby age 5
(integer) 27
127.0.0.1:6379 > decr age # decreasing
(integer) 26
127.0.0.1:6379 > decrease by age 5
(integer) 21

(5) Additional content

  • Syntax: append key value
127.0.0.1:6379> set ideal hello
OK
127.0.0.1:6379 > append idea, idea-20 ා additional content
(integer) 14
127.0.0.1:6379> get ideal
"hello,ideal-20"

(6) Intercept part of 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"

(7) Replace partial string

  • Syntax: setrange key start
127.0.0.1:6379> get ideal
"hello,ideal-20"
127.0.0.1:6379 > setrange ideal 6 BWh
(integer) 14
127.0.0.1:6379> get ideal
"hello,bwhal-20"

(8) Gets the length of the value

  • Syntax: strlen key
127.0.0.1:6379> strlen addr1
(integer) 7

(9) Set when it doesn’t exist

  • Syntax: setnx key value

    • If it does not exist, it will be created
    • If it exists, it fails
127.0.0.1:6379 > setnx address Guangdong # address key does not exist
(integer) 1
127.0.0.1:6379> get address
"guangdong"
If 127.0.0.1:6379 > setnx address Beijing # address key exists, it fails
(integer) 0
127.0.0.1:6379> get address
"guangdong"

(10) Store multiple values at the same time

  • Store multiple values at the same time: Mset key1 value1 key2 Value2
  • Get multiple values at the same time: mget key1 key2
  • Store multiple values at the same time (ensure they don’t exist): msetnx key1 value1 key2 Value2

    • As an atomic operation, this operation fails if it fails
127.0.0.1:6379 > Mset ADDR1 Beijing addr2 Guangdong addr3 Shanghai # store multiple values at the same time
OK
127.0.0.1:6379> keys *
1) "addr3"
2) "addr2"
3) "addr1"

127.0.0.1:6379 > mget ADDR1 addr2 addr3 # get multiple values at the same time
1) "beijing"
2) "guangdong"
3) "shanghai"

127.0.0.1:6379 > msetnx age1 20 age2 25 Age3 30 # store multiple values at the same time for the first time (guarantee it does not exist)
(integer) 1
127.0.0.1:6379 > msetnx Age4 35 age5 40 age1 45 # store multiple values at the same time for the second time (guarantee does not exist), failed
(integer) 0
127.0.0.1:6379>

(11) Set object

  • Syntax: key value (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}"
  • The above user:1 The design of is allowed in redis, for 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"

(12) Get before set

  • Syntax: GetSet

    • First get the original value, and then overlay the new value. If there is no original value, return nil
127.0.0.1:6379 > GetSet addr Beijing # originally no value, return nil
(nil)
127.0.0.1:6379> get addr
"beijing"
127.0.0.1:6379 > GetSet addr Guangdong # original value, return the original value, and then override the new value
"beijing"
127.0.0.1:6379> get addr
"guangdong"

(2) List type – List

(1) Add

A: Add elements from left or right

  • Lpush key value: adds an element to the left side of the list
  • Rpush key value: add the element to the right side of the list

The following demonstration is added to the left, and the right is the same, so it will not be demonstrated

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"

B: Inserts a new value before and after 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
(integer) 4

127.0.0.1:6379> lrange list1 0 -1
1) "A"
2) "B"
3) "XXX"
4) "C"

(2) Get:

A: Get the value according to the interval

  • Syntax: lrange key start end
127.0.0.1:6379 > lrange LIST1 0 - 1 # get all values
1) "C"
2) "B"
3) "A"
 
127.0.0.1:6379 > lrange LIST1 0 1 # get the value of the specified interval
1) "C"
2) "B"

B: Get value from subscript

  • Syntax: index list
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"

C: Gets the length of the list

  • Syntax: Allen list
127.0.0.1:6379> llen list1
(integer) 1

(3) Delete

A: Remove the leftmost or rightmost element

  • Lpop key: delete the leftmost element in the list and return the element
  • Rpop key: delete the rightmost element in the list and return 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 # delete the leftmost element in the list and return the element
"D"
127.0.0.1:6379 > rpop LIST1 # delete the rightmost element in the list and return the element
"A"

127.0.0.1:6379> lrange list1 0 -1
1) "C"
2) "B"

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>

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 > rpopplbush LIST1 List2 # remove the last element in LIST1 and add it to List2
"C"

127.0.0.1:6379> lrange list1 0 -1
1) "A"
2) "B"
127.0.0.1:6379> lrange list2 0 -1
1) "C"

(4) Intercepts the list according to the 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 1 2 # truncate values with subscripts 1 to 2
OK

127.0.0.1:6379> lrange list1 0 -1
1) "B"
2) "C"

(5) Replaces the value of the specified subscript

Syntax: lset list subscript value

127.0.0.1:6379 > exists LIST1 # judge whether this list exists
(integer) 0
127.0.0.1:6379 > lset LIST1 0 Beijing #
(error) 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
"guangdong"

127.0.0.1:6379 > lset LIST1 0 Beijing ᦇ exists, replacement is successful
OK
127.0.0.1:6379> lindex list1 0
"beijing"

(3) Set type – set

Set: an unordered (not guaranteed) set whose elements cannot be repeated

(1) Add

  • Syntax: sad 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
The value of 127.0.0.1:6379 > Sadd Set1 C # set cannot be repeated
(integer) 0
127.0.0.1:6379 > smembers Set1 # query all the values of the specified set, out of order
1) "B"
2) "A"
3) "C"

(2) Get

A: Gets all the elements in the set set

  • Syntax: smembers key
127.0.0.1:6379 > smembers Set1 # query all the values of the specified set, out of order
1) "B"
2) "A"
3) "C"

B: Get the number of elements

  • Syntax: scar set
127.0.0.1:6379> scard set1
(integer) 3

C: Random elements

  • Syntax: sembers set [num]

    • The default is to get a random element followed by a number, which means to get several elements randomly
127.0.0.1:6379> smembers set1
1) "D"
2) "B"
3) "A"
4) "C"

127.0.0.1:6379 > srandmember Set1 # get a random element
"D"
127.0.0.1:6379 > srandmember Set1 # get a random element
"B"

127.0.0.1:6379 > srandmember Set1 2 # get two random elements
1) "A"
2) "D"

(3) Delete

A: Delete an element in the set set

  • Syntax: SREM key value
127.0.0.1:6379 > SREM Set1 C # delete the element C
(integer) 1

127.0.0.1:6379> smembers set1
1) "B"
2) "A"

B: Randomly delete an element

  • Syntax: pop set
127.0.0.1:6379> smembers set1
1) "D"
2) "B"
3) "A"
4) "C"
127.0.0.1:6379 > pop Set1 # randomly delete an element
"A"
127.0.0.1:6379 > pop Set1 # randomly delete an element
"B"
127.0.0.1:6379> smembers set1
1) "D"
2) "C"

(4) Moves 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"

(5) Intersection union difference set

  • Sinter Set1 set2: intersection
  • Union 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 > singer Set1 set2 ා intersection
1) "B"
2) "C"
127.0.0.1:6379 > union Set1 set2 ා Union
1) "D"
2) "E"
3) "C"
4) "B"
5) "A"
127.0.0.1:6379 > sdiff Set1 set2 ා difference set
1) "A"

(4) Ordered set type – sortedset / Zset

Like set, this type is also a collection of string type elements, and duplicate elements are not allowed

The difference is that each element is associated with a score of double type. Redis sorts the members of the collection from small to large by the score

The members of an ordered set are unique, but the scores can be repeated

(1) Add

  • Syntax: zadd key score value [score value…]
127.0.0.1:6379 > zadd sortedset1 20
(integer) 1
127.0.0.1:6379 > zadd sortedset1 10 Lisi 60 Wangwu # add multiple
(integer) 2

(2) Get

A: Get all values (default sort)

  • Syntax: zrange sortedset start end [WithCores]

    • Sort according to 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"

B: Get all values (small to large and large to small)

  • Zrangebyscore sortedset – inf + inf: from small to large
  • Zrevrange sortedset 0 – 1: from big to small
127.0.0.1:6379 > zrangebyscore sortedset1 - inf + inf # from small to large
1) "lisi"
2) "zhangsan"
3) "wangwu"

127.0.0.1:6379 > zrevrange sortedset10 - 1 ᦇ from large to small
1) "wangwu"
2) "zhangsan"
3) "lisi"

C: Gets a value with a numeric value

  • Zrangebycore sortedset – inf + inf WithCores: from small to large with value
127.0.0.1:6379 > zrangebyscore sortedset1 - inf + inf WithCores # display from small to large with values attached
1) "lisi"
2) "10"
3) "zhangsan"
4) "20"
5) "wangwu"
6) "60"

127.0.0.1:6379 > zrangebyscore sortedset1 - inf 20 with cores # shows the values from small to large and less than 20
1) "lisi"
2) "10"
3) "zhangsan"
4) "20"
127.0.0.1:6379>

D: Get the number of ordered sets

  • Syntax: zcard sortedset
127.0.0.1:6379> zcard sortedset1
(integer) 2

E: Gets the number of members in the specified interval

  • Syntax: zcount sortedset start end
127.0.0.1:6379> zcount sortedset1 10 60
(integer) 3

(2) Delete

  • 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 # delete Wangwu
(integer) 1

127.0.0.1:6379> zrange sortedset1 0 -1
1) "lisi"
2) "zhangsan"

(5) Hash type – hash

(1) Add

A: Normal addition

  • 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

B: You can only add if it does not exist

  • Syntax: hsetnx hash filed value
127.0.0.1:6379 > hsetnx hASH1 user name Admin888 #, failed
(integer) 0

127.0.0.1:6379 > hsetnx hASH1 code 666 ා does not exist, successful
(integer) 1

(2) Get

A: Gets the value of the specified field

  • Syntax: hget hash field [key field…]
127.0.0.1:6379> hget hash1 password
"admin"

B: Get all the fields and values

  • Syntax: hgetall hash
127.0.0.1:6379> hgetall hash1
1) "username"
2) "admin"
3) "password"
4) "admin"

C: Gets the number of fields in hash

  • Syntax: HLEN hash
127.0.0.1:6379> hlen hash1
(integer) 2

D: Only get all fields or values

  • Hkeys hash: get all field fields
  • Hvals hash: get all value values
127.0.0.1:6379 > hkeys hASH1 # get all field fields
1) "username"
2) "password"

127.0.0.1:6379 > hvals hASH1 # get all value values
1) "admin"
2) "admin"

(3) Delete

  • Syntax: HDEL hash field
127.0.0.1:6379> hdel hash1 username
(integer) 1

(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

Five or three special data types

(1) Geospatial (geographical location)

Use latitude and longitude as geographical coordinates, and then store them in an ordered set Zset / sortedset. Therefore, the 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 (its structure is an ordered structure)
  • Geospatial can be used to store city coordinates. Generally, it is not entered by itself. Because city data is fixed, it is imported directly through Java. Here are some examples
  • Geospatial can also be used to realize the concept of people nearby. Every position is the current longitude and latitude of a person. There are also some methods that can measure the distance and so on, which will be mentioned later

Command list:

(1) Store latitude and longitude

  • Syntax: geoadd key longitude latitude member [..]

    • Longitude latitude
    • The effective longitude is from – 180 degrees to 180 degrees.
    • The effective latitude ranges 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
127.0.0.1:6379> geoadd china:city 112.556391 37.876989 taiyuan
(integer) 1

(2) Gets the coordinates of one or more members of the collection

  • Syntax: geopos key member [member..]
127.0.0.1:6379> geopos china:city beijing zhuhai
1) 1) "116.41338318586349487"
   2) "39.9109247398676743"
2) 1) "116.41338318586349487"
   2) "39.9109247398676743"

(3) Returns the distance between two given positions

  • Syntax: geologist key member1 member2 [unit]

    • The unit is meter by default, which can be modified after member, such as km
    • Parameters for specified unitsunitMust be one of the following:

      • mThe unit is meter
      • kmThe unit is kilometer
      • miThe unit is miles
      • ftThe unit is 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"

(4) Find nearby elements (given latitude and longitude and length)

  • Meaning: take the given latitude and longitude as the center, return the location elements contained in the set
  • Grammar: with digit

    • All position elements whose distance from the center does not exceed the given maximum distance
    • adoptgeoradiusYou can do itpeople nearbyFunction (for example, the position we input is the current position of the person)

      • Withbird: with coordinates
      • Withdist: the distance on the belt, in the same unit as the radius
      • Count: display only the first n (sorted 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 1
1) 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 2
1) 1) "zhuhai"
   2) "0.0002"
   3) 1) "113.58255296945571899"
      2) "22.27656546780746538"
2) 1) "guangzhou"
   2) "100.7111"
   3) 1) "113.27143281698226929"
      2) "23.13533660075498233"

(5) Find nearby elements (specify existing members and length)

  • Meaning: 5 is the same as 4. What is given is not longitude and latitude, but the existing members in the set
  • Membersbiradiu member
127.0.0.1:6379> georadiusbymember china:city zhuhai 500 km
1) "zhuhai"
2) "guangzhou"

(6) Returns the geohash representation of one or more location elements

  • Syntax: geohash key member1 [member2..]
127.0.0.1:6379> geohash china:city zhuhai
1) "weby8xk63k0"

(2) Hyperloglog (cardinality Statistics)

Hyperlog is used to doCardinality (the number of distinct elements in a dataset)Statistical algorithm, the underlying use of string data type

The advantages of hyperlog are:

  • When the number or volume of input elements is very large, the space needed to calculate cardinality is always fixed and small

    • It takes 12 KB of memory to compute the cardinality of nearly 2 ^ 64 different elements

Because hyperloglog only calculates the cardinality based on the input elements and does not store the input elements themselves, hyperloglog cannot return the input elements as a set does

A common example:

  • In the traditional implementation, the ID of the user is stored and compared each time. When there are more users, this way is a waste of space, and our goal is just tocountHyperloglog can help us do it with minimal space.

(1) Add

Meaning: add the specified element to hyperlog

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

(2) Estimating the cardinality of myelx

Meaning: returns the cardinality estimate of a given hyperlog

Syntax: pfcount key [key]

127.0.0.1:6379> pfcount test1
(integer) 7
127.0.0.1:6379> pfcount test2
(integer) 5

(3) Merger

Meaning: merge multiple hyperlogs into one hyperlog

Syntax: pfmerge destkey sourcekey [sourcekey..]

127.0.0.1:6379> pfmerge test test1 test2
OK
127.0.0.1:6379> pfcount test
(integer) 9

(3) Bitmaps (bitmaps)

Bitmaps uses bit storage, and the information status is only 0 and 1

  • Bitma P is a series of consecutive binary digits (0 or 1). The position of each bit is offset. Bitma P can perform and, or, XOR, not and other bit operations on bitmap
  • There are many application scenarios of this type, such as counting whether employees clock in or not, logging in or not, active or not. You can consider using this type

(1) Set value

  • Meaning: sets a value for 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

(2) Get

  • Meaning: get 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

(3) Statistics

  • Meaning: the statistics string is set to the number of bits of 1. You can also specify the statistics range by byte
  • Syntax: bitcount key [start end]
127.0.0.1:6379> bitcount sign
(integer) 4

Six affairs

(1) Definition

Definition: the essence of redis transaction is a set of commands

  • Transactions support multiple commands at a time, and all commands in a transaction will be serialized
  • In the process of transaction execution, the commands in the execution queue will be serialized in order, and the command requests submitted by other clients will not be inserted into the sequence of transaction execution commands

That is: redis transaction is a one-time, sequential, exclusive execution of a series of commands in a queue

first

(2) Characteristics

(1) Atomicity is not guaranteed

Maybe influenced by relational databases, we will generalize transactions and think that transactions in databases are atomic,Transactions in redis are non atomic

AtomicityAll operations must be done or not done. The transaction must be the smallest whole, that is, the atom in the chemical group is the smallest unit of matter.

  • A transaction in the database needs to update a record of table t1 and table t2. When the transaction is committed, both tables T1 and table t2 are updated. As long as one of the tables fails, the transaction will be rolled back

NonatomicThe opposite of atomicity

  • A transaction in the database needs to update a record of table t1 and table t2. When the transaction is committed, both tables T1 and table t2 are updated. If one of the tables fails and the other continues, the transaction will not be rolled back

(2) Transaction rollback is not supported

Most transaction failures are caused by syntax errors or data structure type errors. Syntax errors are detected before the command is queued, while type errors are detected during execution. Redis uses this simple transaction to improve performance

(3) There is no concept of isolation level for transactions

Batch operations are put into the queue cache before the exec command is sent, and will not be actually executed, so there is no query in the transaction. To see the update in the transaction, the query outside the transaction cannot

(3) Related commands

(1) Open transaction

Meaning: when a transaction is started, the next step is to put the content into the queue one by one, and then execute it atomically through the exec command

Command: multi

Since multi and exec need to be used together, we will demonstrate the example in the second point

(2) Executive affairs

Meaning: to perform all operations in a transaction

Command: Exec

A: Normally open and execute a transaction

First save a K1 and K2, start the transaction, modify the two values, then execute the transaction, and finally find two OK values. Then use get to check the change of the values

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379 > multi open transaction
OK
127.0.0.1:6379 > set K1 v11 # modify K1
QUEUED
127.0.0.1:6379 > set K2 V22 ා modify K2
QUEUED
127.0.0.1:6379 > exec # execute transaction
1) OK
2) OK
127.0.0.1:6379> get k1
"v11"
127.0.0.1:6379> get k2
"v22"

B: Transaction failure due to syntax error

The transaction failure caused by syntax error (compiler error) will keep the original value. For example, in the following transaction, it is OK to modify K1, but there is a syntax error when modifying K2. Set is written as sett, and exec will also make an error. Finally, it is found that the values of K1 and K2 have not changed

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379 > multi open transaction
OK
127.0.0.1:6379 > set K1 v11 # modify normal
QUEUED
127.0.0.1:6379 > sett K2 V22
(error) ERR unknown command `sett`, with args beginning with: `k2`, `v22`, 
127.0.0.1:6379 > exec # execute transaction
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> get k2
"v2"

C: Transaction failure due to type error

Transaction exception caused by type error (runtime error). For example, K2 below is treated as a list. In this way, an error will be reported at runtime. Finally, the transaction fails to commit, but it will not be rolled back. As a result, K1 is successfully modified, while K2 fails

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379 > multi open 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"

(3) Cancel transaction

There’s nothing to say about this, just cancel the execution

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

(4) Watch monitoring

Redis commands are atomic, while transactions are non atomic. Through the watch command, redis can be rolled back

The way is to use watch to monitor some key value pairs before multi, and then continue to open and execute transactions

  • If exec does not change these monitored key value pairs when executing a transaction, it will execute the commands in the transaction queue
  • If the monitored key value pair changes when exec executes the transaction, no command in the transaction will be executed, and then the operation in the transaction will be cancelled

We monitor K1, then modify K1 before the transaction starts, and want to modify K1 in the transaction. We can see that in the final result, the operations in the transaction are not 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 v111111 # K1 has been modified
OK
127.0.0.1:6379 > multi open transaction
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 # execute transaction
(nil)
127.0.0.1:6379> get k1
"v111111"
127.0.0.1:6379> get k2
"v2"

(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 # monitoring
OK
127.0.0.1:6379> set k1 v111111
OK
127.0.0.1:6379 > unwatch # cancel monitoring
OK
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"

Using jedis to operate redis in 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 us to operate redis database in Java, download its jar package, or introduce it into Maven. It is very simple to use

(1) Introducing dependencies and coding

I create an empty project here, and then create a normal Maven module to demonstrate jedis

First, we introduce the jedis dependency, and then we need to introduce fastjson

You can check the version in maven, because the redis installed in Linux is a new version, so we also 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>

Create test class

  • If it is a local machine, for example, under windows, start the redis service under win, and then access it with 127.0.0.1
  • If it is a remote machine, virtual machine or cloud server, use the corresponding IP access
  • The new jedis space-time structure represents the default value of “localhost”, port 6379
public class Demo01 {
    public static void main(String[] args) {
        //Remote Linux (virtual machine)
        Jedis jedis = new Jedis("192.168.122.1", 6379);
        //Check if it's connected
        System.out.println(jedis.ping());
    }
}

(2) Operation steps of connecting Linux

If you input IP and port directly, you will not be able to connect, so you need to do the following operations first

① Keep port 6379 open

Take CentOS 7.9 as an example. Other versions, such as 6. X, can check the specific commands and whether the firewall is blocked, as long as the port can be accessed

  • Open port 6379
firewall-cmd --zone=public --add-port=6379/tcp --permanent
#Display 
succss
  • service iptables restart
firewall-cmd --reload
#Display
success
  • Check if the port is on
firewall-cmd --query-port=6379/tcp
#Display
yes
  • Restart redis service
[[email protected] bin]# redis-cli shutdown
[[email protected] bin]# redis-server myconfig/redis.conf 

You can also use telnet 192.168.122.1 6379 on the windows machine to test whether it can be accessed. If there is an error, please check the port and firewall

② Modify redis configuration file

  • Comment on the IP address of the binding (comment out the sentence bind 127.0.0.1)
  • Set the protection mode to no (protected mode changes yes to no)

    • Redis on Linux is in security mode, which makes it impossible for you to easily establish a connection from outside the virtual machine redis.conf Set the protected mode to no in

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

You can access it again in idea

(3) Common API

(1) String type – string

//Storage
jedis.set("address","beijing");

//Get
String address = jedis.get("address");

//Close the connection
jedis.close();

Supplement: setex () method can store data and specify expiration time

//The AAA BBB is stored and expired after 10 seconds
jedis.setex("aaa",10,"bbb")

(2) List type – List

//Storage
jedis.lpush ("listdemo", "Zhangsan", "Lisi", "Wangwu"); // from the left
jedis.rpush ("listdemo", "Zhangsan", "Lisi", "Wangwu"); // from the right
    
//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();

(3) Set type – set

//Storage
jedis.sadd("setDemo","zhangsan","lisi","wangwu");

//Get
Set<String> setDemo = jedis.smembers("setDemo");

//Close the connection
jedis.close();

(4) Ordered set type – sortedset / Zset

//Storage
jedis.zadd("sortedsetDemo",20,"zhangsan");
jedis.zadd("sortedsetDemo",10,"lisi");
jedis.zadd("sortedsetDemo",60,"wangwu");
    
//Get
Set<String> sortedsetDemo = jedis.zrange("sortedsetDemo", 0, -1);

//Close the connection
jedis.close();

(5) Hash type – hash

//Storage
jedis.hset("hashDemo","name","lisi");
jedis.hset("hashDemo","age","20");
    
//Get
String name = jedis.hget("hashDemo", "name");

//Get所有数据
Map<String, String> user = jedis.hgetAll("hashDemo");
    
Set<String> keySet = user.keySet();
for (String key : keySet) {
    //Get value
    String value = user.get(key);
    System.out.println(key + ":" + value);
}

//Close the connection
jedis.close();

(4) Jedis execute transaction

public class Demo01 {
    public static void main(String[] args) {
        //Remote Linux (virtual machine)
        Jedis jedis = new Jedis("192.168.122.1", 6379);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("name", "zhangsan");
        jsonObject.put("age", "21");

        //Open transaction
        Transaction multi = jedis.multi();
        String result = jsonObject.toJSONString();

        try {
            multi.set("userA", result);
            multi.set("userB", result);
            //Executive affairs
            multi.exec();
        } catch (Exception e) {
            //Abandonment of business
            multi.discard();
        } finally {
            System.out.println(jedis.get("userA"));
            System.out.println(jedis.get("userB"));
            //Close the connection
            jedis.close();
        }
    }
}

To display the results, add two output statements before closing

Implementation results:

{“name”:”zhangsan”,”age”:”21″}
{“name”:”zhangsan”,”age”:”21″}

(5) Jedis connection pool

Why do we use connection pooling?

If we want to use jedis, we must establish a connection. Every time we conduct data interaction, we need to establish a connection. Although jedis has high performance, it takes a lot of time to establish a connection. If we use connection pool, we can establish multiple connections at the client side at the same time and do not release them. When connecting, we only need to obtain the established connections in a certain way Then, it will be returned to the connection pool when it is used up, which greatly saves time

Here we create a connection pool directly, but we usually encapsulate a tool class when we use it

@Test
public void testJedisPool(){
    //0. Create a configuration object
    JedisPoolConfig config = new JedisPoolConfig();
    config.setMaxTotal(50);
    config.setMaxIdle(10);

    //1. Create the jedis connection pool object
    JedisPool jedisPool = new JedisPool(config,"192.168.122.1",6379);

    //2. Get the connection
    Jedis jedis = jedisPool.getResource();
    
    //3. Storage
    jedis.set("name","zhangsan");
    //4. Output results
    System.out.println(jedis.get("name"));
    
    //5. Close and return to the connection pool
    jedis.close();;
}

(1) Connection pool tool class

Just use the tool class 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 tool class
 *Load the configuration file and configure the parameters of the connection pool
 *Provides a way to get a connection
 */
public class JedisPoolUtils {

    private static JedisPool jedisPool;

    static {
        //Read configuration file
        InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
        //Create properties object
        Properties pro = new Properties();
        //Associated files
        try {
            pro.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //Get the data and set it into 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 connection method
     */
    public static Jedis getJedis() {
        return jedisPool.getResource();
    }
}

Don’t forget the configuration file

host=192.168.122.1
port=6379
maxTotal=50
maxIdle=100

Call code

@Test
public void testJedisPoolUtil(){

    //0. Get through the connection pool tool class
    Jedis jedis = JedisPoolUtils.getJedis();

    //1. Use
    jedis.set("name","lisi");
    System.out.println(jedis.get("name"));

    //2. Close and return to the connection pool
    jedis.close();;

}

8. Integrating redis with springboot

(1) Simple use (serialization problem)

① Create a springboot project or module and introduce dependencies

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

As you can see, the official starter introduces redis, but not jedis, but lettuce

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

Jedis: it is not safe to use direct connection and multi thread operation. If you want to avoid insecurity, use the jedis pool connection pool! More like bio mode

Lettuce: with netty, instances can be shared among multiple threads, and there is no thread insecurity! Can reduce thread data, more like NiO mode

② Write configuration file

#Configure redis
spring.redis.host=192.168.122.1
spring.redis.port=6379

③ Test code

@SpringBootTest
class Redis02BootApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void contextLoads() {
        redisTemplate.opsForValue().set("name","zhangsan");
        System.out.println(redisTemplate.opsForValue().get("name"));
    }
}

Results of operation:

zhangsan

(2) Use custom redistemplate template (recommended)

The result of the above operation in idea is no problem, but we went to Linux to look at the content of redis, and found that the keys are garbled, for example, the stored name has changed to the following content

127.0.0.1:6379> keys *
1) "\xac\xed\x00\x05t\x00\x04name"

This is the problem of serialization. Next, we will analyze this problem. Here is the solution, that is, to customize the redistemplate template

① Custom redisconfig class

@Configuration
public class RedisConfig {

    /**
     *Customize redistemplate
     *
     * @param factory
     * @return
     */
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        //For the convenience of development, we usually use < string, Object > directly
        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();
        //The key is serialized as string
        template.setKeySerializer(stringRedisSerializer);
        //Hash keys also use string serialization
        template.setHashKeySerializer(stringRedisSerializer);
        //The value serialization method is Jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //The value serialization method of hash is Jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

② Call

@SpringBootTest
class Redis02BootApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void contextLoads() {
        redisTemplate.opsForValue().set("address","beijing");
        System.out.println(redisTemplate.opsForValue().get("address"));
    }
}

We store the two keys Name2 and address respectively, and check them in the terminal

127.0.0.1:6379> keys *
1) "address"
2) "\xac\xed\x00\x05t\x00\x04name"
3) "name2"

As you can see, the problem has been solved

(3) Encapsulating a tool class

What we pursue is convenience, and we use a lot of them every time redisTemplate.opsForValue (). Xxxxx is a very long command, so encapsulating a tool class can get twice the result with half the effort. I won’t post specific tool classes here because it’s too long. Later, I will post it to GitHub and update the link. Of course, Baidu has a lot of search results

For example, after using the tool class, we can simply use the method encapsulating redistemplate

    @Autowired
    private RedisUtil redisUtil;

    @Test
    void contextLoads() {
        redisUtil.set("address2", "zhuhai");
        System.out.println(redisUtil.get("address2"));

    }

(4) Principle of simple analysis

This is a simple analysis, mainly want to make clear four contents

  • ① Is it possible to use lettuce instead of jedis
  • ② View the configuration properties of the configuration file
  • ③ How to operate redis
  • ④ Serialization problem

In previous articles on spring boot, we can see from the principle of automatic configuration that when integrating a content, there will be an automatic configuration class, and then spring.factories Its fully qualified class name can be found in

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

get into spring.factories , find the automatic assembly class about redis

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

After entering the redisautoconfiguration class, you can see the existence of the redisproperties class in the annotation, which is obviously about the configuration file class

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
//This annotation!!!
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
    //... omitted
}

Enter the redisproperties class

Alt + 7 can view the properties and methods of this class in idea. Let’s look at the properties here

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

For example, the configuration of address, port, timeout and so on are clear. For example, our configuration file at that time was configured like this

#Configure redis
spring.redis.host=192.168.122.1
spring.redis.port=6379

Go back to the class and look at the next annotation. 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 {
    //... omitted
}

First of all, let’s go to jedis. Generic object pool and jedis are missing by default, so they will not take effect

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

Let’s take a look at the lettueconnection configuration. There is no problem, so it is true that the default implementation now uses lettuce

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

Continue back to redisautoconfiguration

There are only two beans

  • RedisTemplate
  • StringRedisTemplate

This kind of xxtemplate, such as jdbctemplate, resttemplate, and so on, operate these components through templates. So the two templates here are also used to operate redis and redis’s string data type (because string type is very common)

//Notes
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);
        return template;
    }
}

Pay special attention to this note

@ConditionalOnMissingBean(name = "redisTemplate")

It means that if there is no customization, we will use this by default. That is to say, we can customize the template ourselves to override the default. In the previous use, we know that using the default template will involve garbled code, that is, serialization

Because the objects transmitted in the network need to be serialized, otherwise they will be garbled

Let’s go to the default redistemplate

The first thing you see is some parameters about serialization

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

Looking down, we can see that the default serialization method is JDK serialization, while our customization method is JSON serialization

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

This serializer is used by all the serializers in the default redistemplate

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

Redisserializer provides us with a variety of serialization methods

[1W words + dry goods] Chapter 1, basics: let your redis no longer just install from scratch to uninstall (Linux Environment)

So later, we customized the redistemplate template and redefined the serialization methods of various types, which is also our recommended practice

Recommended Today

Notes on basic learning of ruby metaprogramming

Note 1:The code contains variables, classes and methods, which are collectively referred to as language construct. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # test.rb class Greeting  def initialize(text)   @text = text  end    def welcome   @text  end end my_obj = Greeting.new(“hello”) […]