[redis] redis quick start (Intensive)

Keywords: Database Redis nosql

1, Basic command

1. Switch database (select)

redis has 16 databases by default, and the 0 database is used by default

Command for switching data: select number

localhost:6379> select 2
OK							# Switching succeeded
localhost:6379[2]>          # 6379 [2] represents the third database

2. set and get methods

Command 1: set [key] [value]

localhost:6379[2]> set name tiger
OK
localhost:6379[2]>

Command 2: get [key]

localhost:6379[2]> get name
"tiger"
localhost:6379[2]>

3. View the size of the database (size)

Command: dbsize

localhost:6379[2]> dbsize
(integer) 1
localhost:6379[2]>

4. View all key s

Command: keys*

localhost:6379[2]> keys *
1) "name"
2) "old"
localhost:6379[2]>

5. Empty database

Empty all databases: flush all

Empty the current database: flushdb

localhost:6379[2]> flushdb
OK
localhost:6379[2]> keys *
(empty array)				# Has been emptied
localhost:6379[2]>

2, redis data type

Redis is an open source (BSD licensed) in memory data structure storage system, which can be used as database, cache and message middleware. It supports many types of data structures, such as strings, hashes, lists, sets, sorted sets and range queries, bitmaps, hyperlogs and geospatial index radius queries. Redis has built-in replication, Lua scripting, LRU events, transactions and different levels of disk persistence, and provides high availability through redis Sentinel and Cluster.


1,Redis_key

① Check whether a key exists

127.0.0.1:6379> keys *
1) "myhash"
2) "mylist"
3) "counter:__rand_int__"
4) "name"
5) "key:__rand_int__"
127.0.0.1:6379> exists name			# Check if name exists
(integer) 1							# 1 indicates presence

② Remove the specified key from the current database to another database

127.0.0.1:6379> move name 1		# Move the name in the current database to database 1
(integer) 0						# 0 means the move failed and 1 means the move succeeded

③ Set / view the expiration time of the specified key

127.0.0.1:6379> expire name 10			# Set the lifetime of name to 10 seconds
(integer) 1
127.0.0.1:6379> ttl name				# View the lifetime of name
(integer) 4								# 4 means name has 4 seconds left
127.0.0.1:6379> ttl name
(integer) 2
127.0.0.1:6379> ttl name
(integer) 0								# name has expired
127.0.0.1:6379> get name				# name can't see it anymore
(nil)

④ View available types

127.0.0.1:6379> type myhash				# View the data type of myhash
hash									# The data type of myhash is hash


2. Explanation of String type

① String append (if there is no key, a new one will be created): append key value

127.0.0.1:6379> set name studioustiger
OK
127.0.0.1:6379> get name
"studioustiger"
127.0.0.1:6379> append name -is-a-man   # Append - is-a-man after name
(integer) 22
127.0.0.1:6379> get name	
"studioustiger-is-a-man"				# Append succeeded


② Get the length of the key: strlen key

127.0.0.1:6379> get name
"studioustiger-is-a-man"
127.0.0.1:6379> strlen name   	#Gets the length of the name
(integer) 22


③ Self increment (plus one): incr key

127.0.0.1:6379> set age 15		# Set the initial value of age to 15
OK
127.0.0.1:6379> incr age		# age self increment 1
(integer) 16
127.0.0.1:6379> incr age		# age self increment 1
(integer) 17
127.0.0.1:6379> get age
"17"							# The current value of age is 17, indicating that the auto increment is successful

④ Self subtraction (minus one): decr key

127.0.0.1:6379> get age
"17"
127.0.0.1:6379> decr age		# age self subtraction
(integer) 16
127.0.0.1:6379> get age
"16"							# Self reduction successful

⑤ Specified step size increment: incrby key step size

127.0.0.1:6379> get age				# Current age is 16
"16"
127.0.0.1:6379> incrby age 10		# Self increase 10
(integer) 26
127.0.0.1:6379> get age
"26"								# It's 256 now

⑥ Specify step size self subtraction: decrby key step size

127.0.0.1:6379> get age				# The current age is 26
"26"
127.0.0.1:6379> decrby age 5		# Self subtraction 5
(integer) 21
127.0.0.1:6379> get age
"21"								# It's 21

⑦ Get the specified range of string: getrange key start end

127.0.0.1:6379> get name
"studioustiger-is-a-man"
127.0.0.1:6379> getrange name 0 7  # Gets the fragment from name with index 0 to index 7 (exactly 8 characters)
"studious"

⑧ Replacement string: setrange key index newstr replaces the character corresponding to the index position with newstr

127.0.0.1:6379> get name				# Get name value
"studioustiger-is-a-man"			
127.0.0.1:6379> setrange name 0 S		# Replace the character with index 0 of name with S
(integer) 22
127.0.0.1:6379> setrange name 8 T		# Replace the character with index 8 of name with T
(integer) 22
127.0.0.1:6379> get name				# Get name value
"StudiousTiger-is-a-man"


⑨ Set the survival time while creating the key: setex key seconds value (set with expire)

127.0.0.1:6379> setex gender 30 man  # The creation key is gender, the value is man, and the survival time is 30 seconds
OK
127.0.0.1:6379> ttl gender			 # View the lifetime of gender
(integer) 25
127.0.0.1:6379> ttl gender			 # View the lifetime of gender
(integer) 21

⑩ Only when the key does not exist can it be created successfully: setnx key value (set if not exist)

127.0.0.1:6379> setnx name tiger     # The creation key is name and the value is tiger
(integer) 0							 # 0 means execution failed
127.0.0.1:6379> get name			 
"StudiousTiger-is-a-man"			 # Found that name has been created in advance
127.0.0.1:6379> setnx hobby sleep	 # The creation key is hobby and the value is sleep (does not exist)
(integer) 1							 # Created successfully
127.0.0.1:6379> get hobby
"sleep"								 # hobby was created successfully

11 batch creation: mset key1 value1 key2 value2

127.0.0.1:6379> mset name2 tiger age2 10 hobby eat #Create name2, age2 and hobby at the same time
OK
127.0.0.1:6379> mget name2 age2 hobby			   # Simultaneous acquisition
1) "tiger"
2) "10"
3) "eat"

12 batch creation (atomicity): msetnx key1 key2

127.0.0.1:6379> msetnx name3 tiger age3 10 hobby play
(integer) 0		# Failed to create because the hobby already exists
127.0.0.1:6379> msetnx name3 tiger age3 10 hobby3 play
(integer) 1		# Creation succeeded because hobby3 did not exist before

13 batch acquisition: mget key1 key2

127.0.0.1:6379> mget name3 age3 hobby3
1) "tiger"
2) "10"
3) "play"

14 set / get object: mset user:1:name tiger user:1:age 18

127.0.0.1:6379> mset user:1:name studioustiger user:1:age 18 user:1:gender 18
OK						# Set successfully
127.0.0.1:6379> mget user:1:name user:1:age user:1:gender
1) "studioustiger"		# Get success
2) "18"
3) "18"

15 get the old value first and then set the new value: getset key value

127.0.0.1:6379> getset user:1:gender man #Now get the value of user:1:gender and set it to man
"18"
127.0.0.1:6379> get user:1:gender		 # We found that the current value of user:1:gender has become man
"man"


Application scenario of String: value can be not only a String, but also a number

  • Article reading counter
  • Count multi unit quantity
  • Count fans
  • Object cache storage

3. Explanation of List type

List is actually a linked list, so the operations that can be performed by the linked list can also be implemented in Redis


Left stored value: Lpush key value01 value02
View the values in the specified range from the left: Lrange key start end (view all values: Lrange key 0 -1)
Because the value is stored from the left and taken from the left, the effect is similar to that of the stack (first in and last out). But the Lrange here is not pop but print.

127.0.0.1:6379> lpush mylist tiger01 tiger02 # Insert tiger01 and tiger02 from the left of the list
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1			 # Print out the values in mylist in turn from the left side of the list
1) "tiger02"
2) "tiger01"


Stored value on the right: Lpush key value
View the values in the specified range from the left: Lrange key start end (view all values: Lrange key 0 -1)
Because the value is stored from the left and taken from the left, the effect is similar to that of queue (first in first out). But the Lrange here is not pop but print.

127.0.0.1:6379> rpush mylist tiger01 tiger02 # Insert tiger01 and tiger02 from the left of the list
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1			 # Type the values in mylist from the left side of the list
1) "tiger01"
2) "tiger02"


Pop up the leftmost value: Lpop key
Pop up the rightmost value: Rpop key

127.0.0.1:6379> rpush list data01 data02 data03 data04
(integer) 4
127.0.0.1:6379> lrange list 0 -1      # Currently, the leftmost value is data01 and the rightmost value is data04
1) "data01"
2) "data02"
3) "data03"
4) "data04"
127.0.0.1:6379> lpop list			  # Pop up the leftmost value
"data01"
127.0.0.1:6379> lrange list 0 -1	  # Obviously, data01 has been ejected
1) "data02"
2) "data03"
3) "data04"
127.0.0.1:6379> rpop list			  # Pop up the rightmost value
"data04"
127.0.0.1:6379> lrange list 0 -1	  # Obviously, data04 has been ejected
1) "data02"
2) "data03"
127.0.0.1:6379>

④ Remove the specified value: Lrem key count value

127.0.0.1:6379> rpush list data01 data02 data02 data03 data04
(integer) 5
127.0.0.1:6379> lrange list 0 -1		# It can be found that the same value can be stored in the list
1) "data01"
2) "data02"
3) "data02"
4) "data03"
5) "data04"
127.0.0.1:6379> lrem list 1 data04      # Delete a data04 in the list
(integer) 1
127.0.0.1:6379> lrange list 0 -1		# Delete succeeded
1) "data01"
2) "data02"
3) "data02"
4) "data03"
127.0.0.1:6379> lrem list 2 data02		# Delete; Two data02 in list
(integer) 2
127.0.0.1:6379> lrange list 0 -1		# Obviously, the deletion was successful
1) "data01"
2) "data03"


Get the value in the list by subscript: Lindex key index
Get the length of the list: Llen key

127.0.0.1:6379> rpush list I Love U
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "I"
2) "Love"
3) "U"
127.0.0.1:6379> Lindex list 1    # Gets the value with index 1 in the list
"Love"
127.0.0.1:6379> llen list		 # Gets the length of the list
(integer) 3

⑥ Truncate the position specified in the list: Ltrim key start end

127.0.0.1:6379> lrange list 0 -1
1) "I"
2) "Love"
3) "U"
127.0.0.1:6379> Ltrim list 1 2         # Keep the contents of indexes 1 to 2 in the list
OK
127.0.0.1:6379> lrange list 0 -1       # Obviously, the truncation succeeded
1) "Love"
2) "U"

⑦ Cut the rightmost value in the existing list into other lists: RpopLpush existList otherList

127.0.0.1:6379> lrange mywords 0 -1          # Currently, there are four value s in mywords
1) "I"
2) "Love"
3) "U"
4) "Baby"
127.0.0.1:6379> rpoplpush mywords demo       # Pop up the rightmost value in mywords and write it into the demo
"Boby"
127.0.0.1:6379> lrange mywords 0 -1          # There is no Baby in mywords
1) "I"
2) "Love"
3) "U"
127.0.0.1:6379> lrange demo 0 -1			 # Baby is indeed written in the demo
1) "Baby"

⑧ Update the value of the specified position in the list: Lset key index value

127.0.0.1:6379> lrange mywords 0 -1    # Now the value with index 2 in mywords is U
1) "I"
2) "Love"
3) "U"
127.0.0.1:6379> lset mywords 2 You     # Replace the value with index 2 in mywords with You
OK
127.0.0.1:6379> lrange mywords 0 -1    # Obviously, the replacement was successful
1) "I"
2) "Love"
3) "You"

⑨ Insert a value before or after the specified value in the list: linsert key before / after existvalue

127.0.0.1:6379> lrange mywords 0 -1
1) "I"
2) "Love"
3) "You"
127.0.0.1:6379> Linsert mywords after You Too  # Insert Too after You
(integer) 4
127.0.0.1:6379> lrange mywords 0 -1			   # Obviously, the insertion was successful
1) "I"
2) "Love"
3) "You"
4) "Too"

4. Explanation of Set type

Set is an unordered non repeating set.


Add elements to the set: Sadd key value01 value02
Print elements in the set set: Smembers key

127.0.0.1:6379> sadd set hello world tiger # Add elements to the collection
(integer) 3
127.0.0.1:6379> smembers set               # Print elements in set
1) "hello"
2) "tiger"
3) "world"

② Judge whether there is an element in the set: Sismember key value

127.0.0.1:6379> smembers set
1) "hello"
2) "tiger"
3) "world"
127.0.0.1:6379> sismember set tiger       # Judge whether tiger is in set
(integer) 1						# 1 indicates presence
127.0.0.1:6379> sismember set studious	  # Judge whether studio exists in set
(integer) 0						# 0 means it does not exist

③ Get the size: scar key in the set set

127.0.0.1:6379> Smembers set    # You can find three elements in the set
1) "hello"
2) "tiger"
3) "world"
127.0.0.1:6379> Scard set      # Print the number of elements in the set
(integer) 3

④ Remove elements from set: Srem key value01 value02

127.0.0.1:6379> smembers set			# At this point, there are six elements in the set
1) "tiger"
2) "I"
3) "world"
4) "u"
5) "hello"
6) "Love"
127.0.0.1:6379> srem set I Love u      # Remove the three elements "I", "love" and "U"
(integer) 3
127.0.0.1:6379> Smembers set		   # Obviously, the removal was successful
1) "hello"
2) "world"
3) "tiger"

⑤ Randomly fetch the specified elements in the set: Srangemember key count

127.0.0.1:6379> Smembers set
1) "is"
2) "name"
3) "My"
4) "StudiousTiger"
127.0.0.1:6379> srandmember set 2   # Randomly take 2 elements from the set
1) "name"
2) "is"
127.0.0.1:6379> srandmember set 2   # Randomly take two elements from the set
1) "My"
2) "is"
127.0.0.1:6379> Smembers set        # It can be found that the number of elements has not changed, so it is only taken out rather than removed
1) "is"
2) "name"
3) "My"
4) "StudiousTiger"

⑥ Randomly remove the elements in the set: Spop key count

127.0.0.1:6379> SMEMBERS set
1) "is"
2) "name"
3) "My"
4) "StudiousTiger"
127.0.0.1:6379> Spop set 1       # Randomly remove an element from the set
1) "My"
127.0.0.1:6379> Spop set 1		 # Randomly remove an element from the set
1) "name"
127.0.0.1:6379> SMEMBERS set     # Obviously, the element was removed
1) "is"
2) "StudiousTiger"

⑦ Moves a specified value to another set: Smove currentSet targetSet value

127.0.0.1:6379> SMEMBERS set1
1) "u"
2) "love"
3) "too"
4) "i"
127.0.0.1:6379> Smove set1 set2 too   # Cut "too" in set1 to set2
(integer) 1
127.0.0.1:6379> SMEMBERS set1         # "too" in set1 disappeared
1) "u"
2) "love"
3) "i"
127.0.0.1:6379> SMEMBERS set2         # One more "too" in set2
1) "too"

⑧ Set: difference set, intersection set, union set
It can be used to solve problems of common concern (intersection) in microblog and station B
Difference set of key1 and key2: Sdeff key1 key2
Intersection of key1 and key2: sinter key1 and key2
Union of key1 and key2: Sunion key1 and key2

127.0.0.1:6379> SADD set1 a b c d		# Store a b c d in set1 set
(integer) 4
127.0.0.1:6379> SADD set2 c d e f		# Store c d e f in set2 set
127.0.0.1:6379>
127.0.0.1:6379> Sdiff set1 set2			# Get the difference set of set1 and set2 (different)
1) "b"
2) "a"
127.0.0.1:6379> Sinter set1 set2		# Get the intersection of set1 and set2 (same)
1) "d"
2) "c"
127.0.0.1:6379> Sunion set1 set2		#Gets the Union (merge) of set1 and set2
1) "e"
2) "a"
3) "f"
4) "d"
5) "b"
6) "c"

5. Explanation of Hash type

We can think that the Hash type is HashMap.


Save value to hash (k-v): Hset key field value
Value from hash (k-v): Hget key field

127.0.0.1:6379> Hset user name tiger   # Save value. key is user, field is name, and value is tiger
(integer) 1
127.0.0.1:6379> Hget user name         # Value
"tiger"


Save multiple values (k-v) to the hash: Hmset key field01 value01 field02 value02
Take multiple values (k-v) from hash: Hmget key field01 field02

127.0.0.1:6379> Hmset user name tiger age 18 gender man  #Save multiple values
OK
127.0.0.1:6379> Hmget user name age gender				 # Take multiple values
1) "tiger"
2) "18"
3) "man"

③ Get all the values in the hash (k-v): Hgetall key

127.0.0.1:6379> Hgetall user	# Get all field s and value s
1) "name"						# field
2) "tiger"						# value
3) "age"						# field
4) "18"							# value
5) "gender"						# field
6) "man"						# value

④ Delete the value in the hash: Hdel key field01 field02

127.0.0.1:6379> Hgetall user
1) "name"
2) "tiger"
3) "age"
4) "18"
5) "gender"
6) "man"
127.0.0.1:6379> Hdel user age gender	# Delete age and gender in user
(integer) 2
127.0.0.1:6379> Hgetall user			# Indeed, it has been deleted successfully
1) "name"
2) "tiger"

⑤ Get the length of hash: Hlen key

127.0.0.1:6379> Hset user name tiger age 18 gender man
(integer) 3
127.0.0.1:6379> Hlen user	# Gets the length of the user
(integer) 3

⑥ Judge whether there is a field in the hash: Hexists key field

127.0.0.1:6379> Hgetall user
1) "name"
2) "tiger"
3) "age"
4) "18"
5) "gender"
6) "man"
127.0.0.1:6379> Hexists user name		# Judge whether there is name in user
(integer) 1		# 1 means yes
127.0.0.1:6379> Hexists user hobby		# Judge whether there is a hobby in the user
(integer) 0		# 0 means no


Get only field: Hkeys key
Only get value: Hvals key

127.0.0.1:6379> Hgetall user
1) "name"
2) "tiger"
3) "age"
4) "18"
5) "gender"
6) "man"
127.0.0.1:6379> Hkeys user		# Get only the keys in user
1) "name"
2) "age"
3) "gender"
127.0.0.1:6379> Hvals user		# Get only the value in user
1) "tiger"
2) "18"
3) "man"

⑧ Self increasing or self decreasing: Hincrby key field count

127.0.0.1:6379> Hget user age
"18"
127.0.0.1:6379> Hincrby user age 1		# age plus 1
(integer) 19
127.0.0.1:6379> Hget user age
"19"
127.0.0.1:6379> Hincrby user age -3		# age minus 3
(integer) 16
127.0.0.1:6379> Hget user age
"16"

⑨ If field exists, Hsetnx key field value will not be executed

127.0.0.1:6379> Hsetnx user name studioustiger	# Add a name to user
(integer) 0		# 0 means failure
127.0.0.1:6379> Hsetnx user hobby sleep			# Add a hobby to user
(integer) 1		# 1 indicates success
127.0.0.1:6379> Hgetall user					# We can see that it has indeed been added
1) "name"
2) "tiger"
3) "age"
4) "16"
5) "gender"
6) "man"
7) "hobby"
8) "sleep"

Application: hash can store information in entity classes (objects) well, for example: Hset user:1 name tiger age 18 gender man


6. Explanation of Zset ordered set type

The difference between zset and set is that zset can set a score for each element, and the user sorts the elements according to the score


Add: Zadd key01 score01 value01 key02 score02 value02
Print: Zrange key 0 -1

127.0.0.1:6379> Zadd age 18 tiger 15 mark 8 konkey 23 zhang	#Add elements and set score for each element
(integer) 4
127.0.0.1:6379> Zrange age 0 -1		# Print all elements in ascending order by default
1) "konkey"
2) "mark"
3) "tiger"
4) "zhang"


Ascending (negative infinity, positive infinity): Zrangebyscore key -inf +inf
Ascending (negative infinity, positive infinity) with score: zrangebyscore key - inf + inf withcore

127.0.0.1:6379> Zrangebyscore age -inf +inf			# Ascending arrangement
1) "konkey"
2) "mark"
3) "tiger"
4) "zhang"
127.0.0.1:6379> Zrangebyscore age 18 23				# Specifies the ascending order of the range
1) "tiger"
2) "zhang"
127.0.0.1:6379> Zrangebyscore age 18 23 withscores	# Specifies the ascending order of the range with score
1) "tiger"
2) "18"
3) "zhang"	# value
4) "23"		# score

④ Descending order: Zrevrange key 0 -1

127.0.0.1:6379> Zrevrange age 0 -1				# Sort all elements in descending order
1) "zhang"
2) "tiger"
3) "mark"
4) "konkey"
127.0.0.1:6379> Zrevrange age 0 -1 withscores	# All elements are sorted in descending order with score
1) "zhang"
2) "23"
3) "tiger"
4) "18"
5) "mark"
6) "15"
7) "konkey"
8) "8"

⑤ Remove element: Zrem key value

127.0.0.1:6379> Zrange age 0 -1
1) "konkey"
2) "mark"
3) "tiger"
4) "zhang"
127.0.0.1:6379> Zrem age zhang mark		# Remove zhang and mark from age
(integer) 2
127.0.0.1:6379> Zrange age 0 -1			# Are you sure you have removed
1) "konkey"
2) "tiger"

⑥ Get the number of in the set: Zcard key

127.0.0.1:6379> Zrange age 0 -1
1) "konkey"
2) "tiger"
127.0.0.1:6379> Zcard age		# Gets the number of elements in the age
(integer) 2			# There are 2 elements in age

⑦ Get the number of elements in the specified interval: Zcount key min max

127.0.0.1:6379> Zrange age 0 -1
1) "konkey"
2) "mark"
3) "tiger"
4) "zhang"
127.0.0.1:6379> Zcount age 15 23   # Get the number of elements of score during [15,23]
(integer) 3

Thinking case:
Grade table sorting
Payroll sorting

The weight of ordinary messages is 1
The weight of important messages is 2

Ranking List


3, Detailed explanation of geospatial geographical location

1. Introduction

Website for querying City longitude and latitude: https://jingweidu.bmcx.com/

be careful:
The effective longitude is from - 180 degrees to 180 degrees.
The effective latitude ranges from -85.05112878 degrees to 85.05112878 degrees.
When the coordinate position exceeds the above specified range, the command will return an error.


2. Command

① Add one or more geospatial locations to the sorted set

geoadd key longitude latitude City [longitude latitude city...]

127.0.0.1:6379> geoadd cn:city 116.75199 36.55358 jinan			# Jinan
(integer) 1
127.0.0.1:6379> geoadd cn:city 114.49339 36.61853 handan		# Handan
(integer) 1
127.0.0.1:6379> geoadd cn:city 115.98847 36.43452 liaocheng		# Liaocheng
(integer) 1
127.0.0.1:6379> geoadd cn:city 117.86172 36.49473 zibo			# Zibo
(integer) 1
127.0.0.1:6379> geoadd cn:city 119.16607 36.65458 weifang		# Weifang
(integer) 1
127.0.0.1:6379> geoadd cn:city 121.26757 37.49794 weihai		# Weihai
(integer) 1
127.0.0.1:6379> geoadd cn:city 122.12348 37.50212 yantai		# Yantai
(integer) 1
127.0.0.1:6379> geoadd cn:city 116.29941 37.45079 dezhou		# Texas
(integer) 1
127.0.0.1:6379> geoadd cn:city 118.02279 37.42726 binzhou		# Binzhou
(integer) 1
127.0.0.1:6379> geoadd cn:city 118.58215 37.44878 dongying		# doy 
(integer) 1
127.0.0.1:6379> geoadd cn:city 116.59649 35.4082 jining			# Jining
(integer) 1
127.0.0.1:6379> geoadd cn:city 118.40184 35.08729 linyi			# Linyi
(integer) 1
127.0.0.1:6379> geoadd cn:city 119.46242 35.42545 rizhao		# sunshine
(integer) 1
127.0.0.1:6379> geoadd cn:city 117.4613 35.09963 zaozhuang		# Zaozhuang
(integer) 1

② Returns a standard geospatial Geohash string

geohash key city [City...]

127.0.0.1:6379> geohash cn:city binzhou dongying  # Get the hash string of Binzhou and Dongying
1) "wweuvtmtd70"
2) "wwsm43kfuq0"
# Because the longitude and latitude of Binzhou and Dongying are very close, the hash string corresponding to their longitude and latitude is also relatively close

③ Returns the latitude and longitude of a geospatial

geopos key city [City...]

127.0.0.1:6379> geopos cn:city jinan linyi  # Get the longitude and latitude of Jinan and Linyi
1) 1) "116.75199061632156372"	# Longitude of Jinan
   2) "36.55358010603453778"	# Latitude of Jinan
2) 1) "118.40183883905410767"   # Longitude of Linyi
   2) "35.08728954033782799"	# Linyi latitude

④ Returns the distance between two geospatials

geodist key city 1 city 2 [unit]

Will use some algorithm to calculate the straight-line distance between the two places according to longitude and latitude

127.0.0.1:6379> geodist cn:city jinan linyi km	# Obtain the straight-line distance of Linyi in Jinan (km)
"220.7609"
127.0.0.1:6379> geodist cn:city jinan zibo km   # Obtain the straight-line distance of Zibo in Jinan (km)
"99.4054"

The value of unit is as follows:
m is expressed in meters.
km is expressed in kilometers.
mi is in miles.
ft is in feet.

⑤ Queries a collection of all geospatial elements within a specified radius.

georadius key longitude latitude radius m|km|ft|mi [withcool] [withdist] [withhash] [count]

# Query the cities contained in cn:city with (longitude: 116, latitude: 36) as the center, 100km as the radius
127.0.0.1:6379> georadius cn:city 116 36 100 km
1) "liaocheng"	# Liaocheng
2) "jinan"		# Jinan
3) "jining"		Jining

⑥ Queries a geospatial element that matches the maximum distance within a specified radius.

georadiusbymember key city radius m|km|ft|mi [withcool] [withdist] [withhash] [count]

# Query the cities within 300km around Jinan
127.0.0.1:6379> georadiusbymember cn:city jinan 300 km
 1) "nandan"
 2) "jining"
 3) "zaozhuang"
 4) "liaocheng"
 5) "zibo"
 6) "jinan"
 7) "dezhou"
 8) "binzhou"
 9) "linyi"
10) "rizhao"
11) "weifang"
12) "dongying"

⑦ View all cities

Zrange key 0 -1

127.0.0.1:6379> zrange cn:city 0 -1		# View all cities in cn:city
 1) "nandan"
 2) "jining"
 3) "zaozhuang"
 4) "liaocheng"
 5) "zibo"
 6) "jinan"
 7) "linyi"
 8) "rizhao"
 9) "weifang"
10) "qingdao"
11) "dezhou"
12) "binzhou"
13) "dongying"
14) "weihai"
15) "yantai"

⑧ Remove the specified City

Zrem key city 1 city 2

# Remove Handan, Dongying and Rizhao
127.0.0.1:6379> zrem cn:city nandan dongying rizhao liaochneg 
(integer) 3
127.0.0.1:6379> zrange cn:city 0 -1		# It has indeed been removed
 1) "jining"
 2) "zaozhuang"
 3) "liaocheng"
 4) "zibo"
 5) "jinan"
 6) "linyi"
 7) "weifang"
 8) "qingdao"
 9) "dezhou"
10) "binzhou"
11) "weihai"
12) "yantai"

4, Detailed explanation of hyperloglog cardinality statistics

1. Introduction

What cardinality can be considered as the number of non duplicates in a group of data, which we call the cardinality of the group of data.

In development, we can solve the problem of user view through cardinality. If a user visits multiple times, we still think it is a visit, then we can solve this problem well by using cardinality.

At this time, someone will ask again. Why do I have Hyperloglog in Redis? Isn't it fragrant to use set set? What I want to tell you is that it's really not fragrant.

The space occupied by set is too large, and we use hyperloglog to store 2 ^ 64 songs. Different elements only need 12KB of memory (there is an error rate of 0.81% in the case of big data).

2. Command

① Add all element parameters to the hyperlog data structure
PFadd key element [element ...]

# Store the following song elements into the hyperloglog. We can see that its cardinality is 7
127.0.0.1:6379> pfadd elem a b c d e f g g g g g
(integer) 1

② Returns the cardinality estimate for a given hyperlog
PFcount key [key ...]

127.0.0.1:6379> pfadd elem a b c d e f g g g g g
(integer) 1
127.0.0.1:6379> pfcount elem	# Get cardinality in elem
(integer) 7						# 7 is obviously correct

③ Merge multiple hyperlogs into one hyperlog
PFmerge destkey sourcekey [sourcekey ...]

127.0.0.1:6379> pfadd elem1 a b c d e e f f		# Deposit a B C D E F F into elem1
(integer) 1
127.0.0.1:6379> pfcount elem1					# Obviously, the cardinality of elem1 is indeed 6
(integer) 6
127.0.0.1:6379> pfadd elem2 t h j k l f			# Save t h j k l f to elem2
(integer) 1					
127.0.0.1:6379> pfcount elem2					# Obviously, the cardinality of elem2 is indeed 6
(integer) 6
127.0.0.1:6379> pfmerge elem3 elem1 elem2		# Combine elem1 and elem2 into elem3
OK
127.0.0.1:6379> pfcount elem3					# Obviously, the cardinality of elem3 is really 11
(integer) 11

5, Detailed explanation of bitmap scene

1. Introduction

Bitmap is a data structure implemented by bit storage, so the efficiency of bitmap is very optimistic. But what are the application scenarios of bitmap?

We can use bitmap to store all opposing information. For example, we can count the active status, login status and clock in status of users.

We are using storage. We only need to use 0 and 1 to represent the state.

2. Command

① Save value to bitmap
setbit key offset value

# Next, let's set the clock out of a week (1 means clock out, 0 means no clock out)
127.0.0.1:6379> setbit clockIn 1 1	# Monday: punch in
(integer) 0
127.0.0.1:6379> setbit clockIn 2 0	# Tuesday: no clock in
(integer) 0
127.0.0.1:6379> setbit clockIn 3 0	# Wednesday: no clock in
(integer) 0
127.0.0.1:6379> setbit clockIn 4 1	# Thursday: clock in
(integer) 0
127.0.0.1:6379> setbit clockIn 5 1	# Friday: punch in
(integer) 0
127.0.0.1:6379> setbit clockIn 6 1	# Saturday: punch in
(integer) 0
127.0.0.1:6379> setbit clockIn 0 0	# Sunday: no clock out
(integer) 0

② Value from bitmap
getbit key offset

127.0.0.1:6379> getbit clockIn 4	# Get the clock out on Thursday
(integer) 1		# Clock in on Thursday
127.0.0.1:6379> getbit clockIn 0	# Get the clock out of Sunday
(integer) 0		# Didn't punch in on Sunday

③ Count the number of bitmap s with a median of 1
bitcount key [start] [end]

127.0.0.1:6379> bitcount clockIn		# Count the number of bitmap s with a median of 1
(integer) 4		# Obviously, it does open four times from Monday to Sunday



6, Transactions in redis

1. Introduction

Essence of Redis transaction
① Redis transactions are a collection of commands.
② All commands in a transaction will be serialized and executed in sequence during the execution of the transaction.
③ Redis transactions are one-time, sequential and exclusive.

Differences between Redis and MySQL
In relational databases (e.g. mysql), there is a concept of isolation between transactions, but there is no concept of isolation in Redis. In Redis, all commands are not executed directly in the transaction, but wait for the execution command.

In relational database, transactions have ACID principle, in which atomicity refers to either successful execution or failed execution. However, in Redis, transactions are not atomic, but a single Redis command is atomic.

2. Command

① Open transaction
multi

② Order to join the team
Some commands

③ Execute transaction
exec

④ Cancel transaction
discard

Normal execution of transactions

127.0.0.1:6379> multi				# Open transaction
OK
127.0.0.1:6379(TX)> set name tiger	# Order 1 to join the team
QUEUED
127.0.0.1:6379(TX)> set age 18		# Order 2 to join the team
QUEUED
127.0.0.1:6379(TX)> get name		# Order 3 to join the team
QUEUED
127.0.0.1:6379(TX)> get age			# Order 4 to join the team
QUEUED
127.0.0.1:6379(TX)> exec			# Execute transaction
1) OK
2) OK
3) "tiger"
4) "18"

Cancel transaction execution

127.0.0.1:6379> multi							# Open transaction
OK
127.0.0.1:6379(TX)> set name2 studioustiger		# Command 1
QUEUED
127.0.0.1:6379(TX)> get name2					# Command 2
QUEUED
127.0.0.1:6379(TX)> discard						#Cancel the execution of the transaction
OK
127.0.0.1:6379> get name2						# Command 1 was not executed
(nil)

3. Attention

When there is a compile time exception (queue command error), all transactions in the transaction will not be executed

127.0.0.1:6379> multi			# Open transaction
OK
127.0.0.1:6379(TX)> set name hanjiang		# Command 1
QUEUED
127.0.0.1:6379(TX)> getsss name		# Command 2 (no getss command)
(error) ERR unknown command `getsss`, with args beginning with: `name`,
127.0.0.1:6379(TX)> set age 18		# Command 3
QUEUED
127.0.0.1:6379(TX)> get age			# Command 4
QUEUED
127.0.0.1:6379(TX)> exec			# Execute transaction
# (error) EXECABORT transaction was abandoned due to a previous error
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get name			# Command 1 did not execute
(nil)
127.0.0.1:6379> get age				# Command 3 did not execute
(nil)

When there is a runtime exception (syntax error in the command), the command with only syntax error will not be executed, and an exception will be thrown

127.0.0.1:6379> set age 18yearsOld			# Set a string type
OK
127.0.0.1:6379> multi						# Open transaction
OK
127.0.0.1:6379(TX)> incr age				# Command 1 (obviously syntax error, string cannot be self incremented)
QUEUED
127.0.0.1:6379(TX)> set name zhangsan		# Command 2
QUEUED
127.0.0.1:6379(TX)> set hobby sleep			# Command 3
QUEUED
127.0.0.1:6379(TX)> get name				# Command 4
QUEUED
127.0.0.1:6379(TX)> get hobby				# Command 5
QUEUED
127.0.0.1:6379(TX)> exec
# (error) the value is not an integer or is out of bounds
1) (error) ERR value is not an integer or out of range
2) OK			# Command 2 executed successfully
3) OK			# Command 3 executed successfully
4) "zhangsan"	# Command 4 executed successfully
5) "sleep"		# Command 5 executed successfully



7, watch implements optimistic locking

1. Introduction

In fact, we have learned optimistic lock in the mybatis plus stage. I won't repeat it here, but just make a brief introduction.

There are two ways to prevent dirty data in the database: pessimistic lock and optimistic lock.
① Pessimistic lock: it is considered that the data will be modified in advance before the data operation is completed, so a thread lock will be added to each operation.
② Optimistic lock: it is considered that the data will not be modified in advance before the data operation is completed, so the thread lock will not be added to each operation.

Since optimistic locks do not lock threads, how can we ensure that the data is not dirty? We can use a version field to judge. Regulation: when the data is modified, the corresponding version must be increased by one. In this way, we only need to obtain the sequential version before the update. The update is performed to compare whether the current version has changed. The operation will be performed only if the previous and subsequent versions are consistent.

In mysql, the above provisions are easy to implement, but how to implement them in Redis? Let's solve this problem.

2. Command

In Redis, we can add a watch to a data. When a data is added with a watch and the current data is modified by other threads, the transactions after the watch will not be executed. We can think that when a data is added with a watch, it is equivalent to adding a version and version=1. Whenever the data is modified, its version will be + 1.

Command to add monitoring to data
watch key

① Thread safe

127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> watch money				# Put money under surveillance
OK
127.0.0.1:6379> multi					# Open transaction
OK
127.0.0.1:6379(TX)> incrby money 10		# Add 10 to money
QUEUED
127.0.0.1:6379(TX)> get money			# Get money
QUEUED
127.0.0.1:6379(TX)> exec				# Commit transaction
1) (integer) 110						# Obviously, the transaction was executed successfully
2) "110"

② Thread unsafe

127.0.0.1:6379> get money
"100"
127.0.0.1:6379> watch money				# Put money under surveillance
OK
127.0.0.1:6379> decrby money 20			# After adding monitoring, the money data was modified
(integer) 80
127.0.0.1:6379> multi					# Open transaction
OK
127.0.0.1:6379(TX)> incrby money 10		# Command 1
QUEUED
127.0.0.1:6379(TX)> get money			# Command 2
QUEUED
127.0.0.1:6379(TX)> exec				# Commit transaction
(nil)									# Obviously, the transaction did not commit successfully



8, jedis operation Redis

Note: we are based on the maven project. Linux uses the local Linux virtual machine.

1. java connection to redis (☆)

① Import dependent

<dependencies>
    <!-- jedis rely on -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.5.2</version>
    </dependency>
    <!-- fastjson rely on -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.78</version>
    </dependency>
    <!-- junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>

</dependencies>

② Writing test classes

@Test
public void t1(){
    //1. Create a jedis object
    Jedis jedis = new Jedis("192.168.174.128", 6379);
    System.out.printf(jedis.ping());
}

Mistakes you may encounter
redis.clients.jedis.exceptions.JedisConnectionException: Failed connecting to 192.168.174.128:6379
...
Caused by: java.net.SocketTimeoutException: connect timed out

resolvent
① Turn off Linux firewall and set disable bootstrap

[root@localhost bin]# systemctl stop firewalld.service		# Close the protective wall
[root@localhost bin]# systemctl disable firewalld.service	# Prohibit self starting
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.

② Modify the redis.conf configuration file and comment out the bottom 75 lines

72 # IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
73 # JUST COMMENT OUT THE FOLLOWING LINE.
74 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
75 # bind 127.0.0.1 -::1			##The content of line 75 is just dropped, so any IP can be accessed

③ Modify the redis.conf configuration file and change line 94 from yes to no

90 # By default protected mode is enabled. You should disable it only if
91 # you are sure you want clients from other hosts to connect to Redis
92 # even if no authentication is configured, nor a specific set of interfaces
93 # are explicitly listed using the "bind" directive.
94 protected-mode no    # Change the original yes to no

Connection succeeded

3. Practice

The commands mentioned above can be used in Java through jedis objects, so I'll simply use a few here to prove it to you.

① Simple instruction test

@Test
public void t1(){
    //1. Create a jedis object
    Jedis jedis = new Jedis("192.168.174.128", 6379);
    
    //All the instructions we learned before can be used here, so the previous content is really important
    System.out.println(jedis.ping());
    jedis.flushDB();								# Empty the current database
    System.out.println("---------------------");
    
    jedis.set("name", "studioustiger");				# set command
    jedis.set("age","18");
    List<String> mget = jedis.mget("name", "age");	# mget command
    for (String val : mget) {
        System.out.println(val);
    }
    
    System.out.println("----------------------");
    jedis.incrBy("age",5);							# incrby command
    List<String> mget2 = jedis.mget("name", "age");	# nget command
    for (String val : mget2) {
        System.out.println(val);
    }

}

We can see that there is no problem with the result

② Optimistic lock: thread safe
It is worth noting that after a Transaction is started on an element, we cannot use Jedis for Transaction operations before the Transaction is committed, but use Transaction for Transaction operations.

@Test
public void t2(){
    Jedis jedis = new Jedis("192.168.174.128", 6379);
    jedis.flushDB();

    jedis.set("money","100");
    jedis.watch("money");						# Monitor money

    Transaction transaction = jedis.multi();	# Open transaction
    transaction.incrBy("money",10);
    transaction.get("money");
    List<Object> exec = transaction.exec();		# Commit transaction
    
    if(exec==null){
        System.out.println("null");
    }else{
        for (Object o : exec) {
            System.out.println(o);
        }
    }
}

③ Optimistic lock: when thread is unsafe

@Test
public void t3(){
    Jedis jedis = new Jedis("192.168.174.128", 6379);
    jedis.flushDB();

    jedis.set("money","100");
    jedis.watch("money");						# Turn on monitoring for money
    jedis.decrBy("money",20);					# money was modified outside the transaction

    Transaction transaction = jedis.multi();	# Open transaction
    transaction.incrBy("money",10);
    transaction.get("money");
    List<Object> exec = transaction.exec();		# Commit transaction
    
    if(exec==null){
        System.out.println("null");
    }else{
        for (Object o : exec) {
            System.out.println(o);
        }
    }
}

Official document of redis command: https://www.redis.net.cn/order/3685.html

✈ ❀ I hope I can give you an extraordinary experience ☂ ✿ white whoring is guilty ☠ , Remember to pay attention to ❥ (^ -)

Posted by Tomz on Fri, 19 Nov 2021 13:18:23 -0800