Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

Continuing from the previous article, we continue to learn about Golang operating redis

A. list B. list C. list D. list

A Redis list is a simple list of strings. The list is ordered and the elements in the list can be repeated.

You can add an element to the head (left) or bottom (right) of the list

Golang Redis list

  • LPush – Inserts data from the left side of the list
  • LPushX – differs from LPush in that data is inserted only when the list exists
  • RPop – Removes the first data from the right side of the list and returns the deleted data
  • RPush – Inserts data from the right side of the list
  • RPushX – Differs from RPush in that data is inserted only when the list exists
  • LPop – Removes the first data from the left side of the list and returns the deleted data
  • LLen – Returns the size of the list
  • LRange – Returns a range of data from the list, or all data
  • LRem – Deletes data from the list
  • LIndex – Queries data in a list based on index coordinates
  • LInsert – Inserts data at the specified position

1.LPush

Insert data from the left side of the list

// Insert data
client.LPush("key"."data1")

// LPush supports inserting any data at once
err := client.LPush("key".1.2.3.4.5).Err()
iferr ! =nil {
	panic(err)
}
Copy the code

2.LPushX

The difference with LPush is that data is inserted only when the list exists, exactly the same way.

3.RPop

Removes the first data from the right side of the list and returns the deleted data

val, err := client.RPop("key").Result()
iferr ! =nil {
	panic(err)
}

fmt.Println(val)
Copy the code

4.RPush

Insert data from the right side of the list

// Insert data
client.RPush("key"."data1")

// Any data can be inserted at once
err := client.RPush("key".1.2.3.4.5).Err()
iferr ! =nil {
	panic(err)
}
Copy the code

5.RPushX

The difference with RPush is that data is inserted only when the list exists. They are used the same way

6.LPop

Removes the first data from the left side of the list and returns the deleted data

val, err := client.LPop("key").Result()
iferr ! =nil {
	panic(err)
}

fmt.Println(val)
Copy the code

7.LLen

Returns the size of the list

val, err := client.LLen("key").Result()
iferr ! =nil {
	panic(err)
}

fmt.Println(val)
Copy the code

8.LRange

Returns a range of data from the list, or all of the data

// Return all data between 0 and -1
vals, err := client.LRange("key".0.- 1).Result()
iferr ! =nil {
	panic(err)
}
fmt.Println(vals)
Copy the code

9.LRem

Delete data from the list

// Starting from the left side of the list, delete 100. If there are duplicate elements, delete only once, that is, delete the first one
dels, err := client.LRem("key".1.100).Result()
iferr ! =nil {
	panic(err)
}

// If there are more than one 100, remove two 100's from the left side of the list
client.LRem("key".2.100)


// If there are more than one 100, remove two 100's starting from the right side of the list
// The negative number of the second argument means that several elements equal to 100 are removed from the right
client.LRem("key".2 -.100)

// If there are more than one 100, the second argument is 0 to delete all elements equal to 100
client.LRem("key".0.100)
Copy the code

10.LIndex

Query the data in the list based on index coordinates

// The list index starts at 0 and returns the sixth element
val, err := client.LIndex("key".5).Result()
iferr ! =nil {
	panic(err)
}

fmt.Println(val)
Copy the code

11.LInsert

Inserts data at the specified location

// Insert 4 before 5 in the list
// Before means before
err := client.LInsert("key"."before".5.4).Err()
iferr ! =nil {
	panic(err)
}

// Insert welcome before tizi365 element in the list
client.LInsert("key"."before"."tizi365"."Welcome")

// Insert 2019 after the tizi365 element in the list
client.LInsert("key"."after"."tizi365"."2019")
Copy the code

8

The set type of Redis is an unordered set of string values with unique elements.

Here is the collection usage of Go Redis.

Go Redis set (set)

  • SAdd – Adds collection elements
  • SCard – Gets the number of collection elements
  • SIsMember – Determines if the element is in the collection
  • SMembers – Gets all the elements in the collection
  • SRem – Removes collection elements
  • SPop,SPopN – Randomly returns the elements in the collection, and deletes the returned elements

1.SAdd

Add collection elements

// Add 100 to the collection
err := client.SAdd("key".100).Err()
iferr ! =nil {
	panic(err)
}

// Add 100,200,300 to the collection
client.SAdd("key".100.200.300)
Copy the code

2.SCard

Gets the number of collection elements

size, err := client.SCard("key").Result()
iferr ! =nil {
	panic(err)
}
fmt.Println(size)
Copy the code

3.SIsMember

Determines whether an element is in a collection

// Check if 100 is included in the collection
ok, _ := client.SIsMember("key".100).Result()
if ok {
	fmt.Println("Collection contains specified elements")}Copy the code

4.SMembers

Gets all the elements in the collection

es, _ := client.SMembers("key").Result()
// Returns es as an array of strings
fmt.Println(es)
Copy the code

5.SRem

Deleting collection elements

// Remove element 100 from the collection
client.SRem("key".100)

// Remove elements tizi and 2019 from the collection
client.SRem("key"."tizi"."2019")
Copy the code

6.SPop,SPopN

Randomly returns the elements in the collection and deletes the returned elements

// Randomly returns an element in the collection and deletes the element
val, _ := client.SPop("key").Result()
fmt.Println(val)

// Randomly return 5 elements from the collection and delete those elements
vals, _ := client.SPopN("key".5).Result()
fmt.Println(vals)
Copy the code

9. Zset

Sorted sets Redis ordered sets (sorted sets) are collections of string elements just like collections. They do not allow duplicate members. Each element is associated with a double score, which is used to sort the set elements.

Here’s how to use ordered sets of Golang Redis

Go Redis ordered set common functions:

  • ZAdd – Adds one or more elements to the collection, updating the score if the element already exists
  • ZCard – Returns the number of collection elements
  • ZCount – Counts the number of elements in a range of fractions
  • ZIncrBy – Increases the score of an element
  • ZRange,ZRevRange – Returns the elements of an index range in the collection, sorted by fraction from smallest to largest
  • ZRangeByScore ZRevRangeByScore – return collection elements, according to the scope of the score elements according to the score from small to large, sorting support paging.
  • ZRem – Removes collection elements
  • ZRemRangeByRank – Removes elements based on index range
  • ZRemRangeByScore – Removes elements based on the score range
  • ZScore – Queries the score of an element
  • ZRank, ZRevRank – Query the rank of elements

1.ZAdd

Adds one or more elements to the collection, updating the score if the element already exists

// Add a set element to the set with a fraction of 2.5 and a name of tizi
err := client.ZAdd("key", redis.Z{2.5."tizi"}).Err()
iferr ! =nil {
	panic(err)
}
Copy the code

The following is the description of the redis.z structure:

type Z struct {
	Score  float64 / / score
	Member interface{} / / element name
}
Copy the code

2.ZCard

Returns the number of collection elements

size, err := client.ZCard("key").Result()
iferr ! =nil {
	panic(err)
}
fmt.Println(size)
Copy the code

3.ZCount

Count the number of elements in a range of fractions

// Returns: 1<= number of elements in the fraction <=5, note that "1" and "5" are strings
size, err := client.ZCount("key"."1"."5").Result()
iferr ! =nil {
	panic(err)
}
fmt.Println(size)

// Returns the number of elements 1< fraction <=5
// Note: By default, the second and third parameters are greater than or equal to and less than or equal to.
// If you add (> or less than), you remove the equality relation.
size, err := client.ZCount("key"."(1"."5").Result()
Copy the code

4.ZIncrBy

Increases the number of elements

// Add 2 points to element 5
client.ZIncrBy("key".2."5")
Copy the code

5.ZRange,ZRevRange

Returns elements of an index range in the collection, sorted by fraction from smallest to largest

// Returns the collection elements from position 0 to -1, sorted by fraction from smallest to largest
// All data is returned from 0 to -1
vals, err := client.ZRange("key".0.- 1).Result()
iferr ! =nil {
	panic(err)
}

for _, val := range vals {
	fmt.Println(val)
}
Copy the code

ZRevRange is used in the same way as ZRange, except that the results of ZRevRange are sorted by fraction from largest to smallest.

6.ZRangeByScore

Returns collection elements by score range, sorted by score from smallest to largest, supports paging.

// Initialize query conditions, Offset and Count are used for paging
op := redis.ZRangeBy{
	Min:"2".// Minimum score
	Max:"10".// Maximum score
	Offset:0.// SQL like limit, indicating the starting offset
	Count:5.// How much data is returned at one time
}
	
vals, err := client.ZRangeByScore("key", op).Result()
iferr ! =nil {
	panic(err)
}

for _, val := range vals {
	fmt.Println(val)
}
Copy the code

7.ZRevRangeByScore

The usage is similar to ZRangeByScore, except that the elements are sorted from highest to lowest by score.

8.ZRangeByScoreWithScores

ZRangeByScore is used in the same way as ZRangeByScore, except that in addition to returning the set element, it also returns the score corresponding to that element

// Initialize query conditions, Offset and Count are used for paging
op := redis.ZRangeBy{
	Min:"2".// Minimum score
	Max:"10".// Maximum score
	Offset:0.// SQL like limit, indicating the starting offset
	Count:5.// How much data is returned at one time
}

vals, err := client.ZRangeByScoreWithScores("key", op).Result()
iferr ! =nil {
	panic(err)
}

for _, val := range vals {
	fmt.Println(val.Member) // Set element
	fmt.Println(val.Score) / / score
}
Copy the code

9.ZRem

Deleting collection elements

// Remove the element tizi from the collection
client.ZRem("key"."tizi")

// Remove tizi and xiaoli from the set
// Multiple elements can be deleted at once
client.ZRem("key"."tizi"."xiaoli")
Copy the code

10.ZRemRangeByRank

Deletes elements based on index range

// Set elements sorted by score, from lowest to highest, delete element 0 to element 5.
// Delete the elements with the lowest score
client.ZRemRangeByRank("key".0.5)

// Write the positional argument as a negative number, indicating that the high score is deleted from the start.
// In this example, remove the two elements with the highest score, -1 for the highest score position, -2 for the second highest score, and so on.
client.ZRemRangeByRank("key".- 1.2 -)
Copy the code

11.ZRemRangeByScore

Remove elements based on the score range

// Delete range: 2<= score <=5 element
client.ZRemRangeByScore("key"."2"."5")

// Delete range: 2<= elements whose score <5
client.ZRemRangeByScore("key"."2"."(5")
Copy the code

12.ZScore

Query the score of the element

// Query the fraction of tizi
score, _ := client.ZScore("key"."tizi").Result()
fmt.Println(score)
Copy the code

13.ZRank

Query the rank of the elements in the collection by element name, starting from 0

rk, _ := client.ZRank("key"."tizi").Result()
fmt.Println(rk)
Copy the code

ZRevRank is the same as ZRank, except that ZRevRank is sorted by score from highest to lowest.

10. Publish and subscribe

Redis provides publish and subscribe functions, which can be used for message transmission. The publish and subscribe mechanism of Redis consists of three parts, publisher, subscriber and Channel.

Publish and subscribe Architecture diagram:

Publishers and subscribers are both Redis clients, while channels are Redis servers. Publishers send messages to a certain Channel, and subscribers who subscribe to this Channel can receive this message. Redis has a publish-and-subscribe mechanism similar to topic-based publish-and-subscribe, with a Channel acting as a topic.

Here’s how Golang uses Redis’s publish and subscribe feature.

Go Redis

  • Subscribe – Subscribes to a channel
  • Subscribe – Subscribe channels support wildcard matching
  • Publish – Sends information to the specified channel.
  • PubSubChannels – Query active channels
  • PubSubNumSub – Queries how many subscribers the specified channel has

1.Subscribe

Subscribe to the channel

Example 1:

// Subscribe to channel1
sub := client.Subscribe("channel1")

// Read a channel message
iface, err := sub.Receive()
iferr ! =nil {
    // handle error
}

// Check the received message type
switch iface.(type) {
case *redis.Subscription:
    // The subscription succeeded
case *redis.Message:
    // Process the received message
    // We need to do a type conversion here
    m := iface.(redis.Message)
    // Print the received small
	fmt.Println(m.Payload)
case *redis.Pong:
    // Received a Pong message
default:
    // handle error
}
Copy the code

Example 2: Handle messages using a Golang channel

// Subscribe to channel1
sub := client.Subscribe("channel1")

Sub.channel () returns a go Channel, which can loop through messages sent by the Redis server
for msg := range sub.Channel() {
	// Prints the received message
	fmt.Println(msg.Channel)
	fmt.Println(msg.Payload)
}
Copy the code

Example 3: Unsubscribe

// Subscribe to channel1
sub := client.Subscribe("channel1")

// Ignore other processing logic
 
// Unsubscribe
sub.Unsubscribe("channel1")
Copy the code

2.PSubscribe

The usage is the same as Subscribe, except that PSubscribe supports pattern matching.

Example:

// Subscribe to channel1
sub := client.PSubscribe("ch_user_*")
// Can match any channel starting with ch_user_
Copy the code

3.Publish

Sends the message to the specified channel

// Send the "message" message to channel1
client.Publish("channel1"."message")
Copy the code

4.PubSubChannels

Query active channels

// All channels are returned if no matching mode is specified
chs, _ := client.PubSubChannels("").Result()
for _, ch := range chs {
	fmt.Println(ch)
}

// Matches a channel starting with user_
chs, _ := client.PubSubChannels("user_*").Result()
Copy the code

5.PubSubNumSub

Queries how many subscribers a specified channel has

Channel1: query the number of subscribers for channel1 and channel2
chs, _ := client.PubSubNumSub("channel1"."channel2").Result()
for ch, count := range chs {
	fmt.Println(ch) / / channel name
	fmt.Println(count) // The number of channel subscribers
}
Copy the code

11. Transaction-related

Redis transactions can execute more than one command at a time with two important guarantees:

  • A transaction is a single isolated operation: all commands in the transaction are serialized and executed sequentially. The transaction will not be interrupted by command requests from other clients during execution.
  • A transaction is an atomic operation: all or none of the commands in a transaction are executed.

The golang Redis transaction usage is described below.

Go Redis transaction common functions:

  • TxPipeline – Operates transactions as pipelines
  • Watch-redis optimistic lock support

1.TxPipeline

Operates transactions as a Pipeline

// Start a TxPipeline transaction
pipe := client.TxPipeline()

// Redis can be read and written using pipe to perform transactions
incr := pipe.Incr("tx_pipeline_counter")
pipe.Expire("tx_pipeline_counter", time.Hour)

// The above code is equivalent to executing the following redis command
//
// MULTI
// INCR pipeline_counter
// EXPIRE pipeline_counts 3600
// EXEC

// Commit the redis transaction via Exec
_, err := pipe.Exec()

// After committing the transaction, we can query the result of the transaction operation
// The Incr function is executed before the exec function is executed.
fmt.Println(incr.Val(), err)
Copy the code

2.watch

The Redis optimistic lock support allows you to listen for some keys through Watch and commit transactions only if the values of these keys have not been changed by others.

// Define a callback function that handles the transaction logic
fn := func(tx *redis.Tx) error {
		// Check the value of the key monitored by watch
		v, err := tx.Get("key").Result()
		iferr ! =nil&& err ! = redis.Nil {return err
		}

		// Business can be handled here
		fmt.Println(v)

		// The Pipelined function is called successfully if the key value is not changed
		_, err = tx.Pipelined(func(pipe redis.Pipeliner) error {
			// Set the latest value for key here
			pipe.Set("key"."new value".0)
			return nil
		})
		return err
	}

// use Watch to listen for some keys, and bind a callback function fn. The logic to listen for keys is written in fn
Client.Watch(fn, "key1", "key2", "key3")
client.Watch(fn, "key")
Copy the code