The previous article Golang operating MySql Database introduced how to operate MySql database with Go language. Similarly, Redis is also frequently used in project development. Therefore, this article also introduces the basic use of Go-Redis library in Go language, that is, to operate Redis database with Go language.

Redis is introduced

Redis is an open source in-memory database that provides a variety of different types of data structures to which problems in many business scenarios can be naturally mapped. In addition, with features such as replication, persistence, and client-side sharding, Redis can easily be scaled up to a system that can contain hundreds of gigabytes of data and handle millions of requests per second.

Data structures supported by Redis

Redis supports things like strings, hashes, lists, sets, and sorted with range queries Sets, bitmaps, Hyperloglogs, and geospatial indexes with radius queries and streams. The first five data structures are commonly used.

Redis application scenarios

  • Cache system, relieve the pressure of the main database (MySQL).

  • Count scenes, such as the number of followers and followers on Weibo and Douyin.

  • ZSET is especially good for scenarios where you need to sort hot leaderboards.

  • LIST can be used to achieve the function of the queue.

Prepare the Redis environment

Here directly use Docker to start a Redis environment, easy to learn and use.

Example of Docker starting a 5.0.7 version of Redis Server named Redis507:

Docker run --name redis507 -p 6379:6379 -d redis:5.0.7 docker run --name redis507 -p 6379:6379 -d redis:5.0.7Copy the code

** Note: ** The version, container name, and port number are set according to your own needs.

Start a Redis – CLI connection to the above Redis server:

Docker run-it --network host --rm redis:5.0.7 redis-cliCopy the code

Go – redis library

The installation

Redigo is a popular Go language redis client library. We use github.com/go-redis/re… Connect to the Redis database and perform operations, because Go-Redis supports connecting to Sentry and clustered Redis.

Use the following command to download and install:

go get -u github.com/go-redis/redis
Copy the code

Common connection

Package main import "github.com/go-redis/redis"// Declare a global RDB variable var RDB * redis.client // Initialize the connection func initClient() (err error)  { rdb = redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // no password set DB: 0, // use default DB }) _, err = rdb.Ping().Result() if err ! = nil { return err } return nil}func main() { err := initClient() if err ! = nil { panic(err) }}Copy the code

New version of V8

The latest versions of the Go-Redis library require the context. context argument to be passed. For example:

Package mainImport ("context" "FMT" "github.com/go-redis/redis" "time" "github.com/go-redis/redis/v8" // Note that the new version is imported)var Func initClient() (err error) {RDB = redis.newclient (& redis.options {Addr: "localhost:16379", Password: "", // no password set DB: 0, // use default DB PoolSize: }) CTX, cancel := context.withtimeout (context.background (), 5* time.second) cancel() _, err = rdb.Ping(ctx).Result() return err}func V8Example() { ctx := context.Background() if err := initClient(); err ! = nil { return } err := rdb.Set(ctx, "key", "value", 0).Err() if err ! = nil { panic(err) } val, err := rdb.Get(ctx, "key").Result() if err ! = nil { panic(err) } fmt.Println("key", val) val2, err := rdb.Get(ctx, "key2").Result() if err == redis.Nil { fmt.Println("key2 does not exist") } else if err ! = nil { panic(err) } else { fmt.Println("key2", val2) } // Output: key value // key2 does not exist}Copy the code

Connect to Redis Sentinel mode

func initClient()(err error){ rdb := redis.NewFailoverClient(&redis.FailoverOptions{ MasterName: "master", SentinelAddrs: []string{"x.x.x.x:26379", "xx.xx.xx.xx:26379", "xxx.xxx.xxx.xxx:26379"}, }) _, err = rdb.Ping().Result() if err ! = nil { return err } return nil}Copy the code

Connect to the Redis cluster

func initClient()(err error){ rdb := redis.NewClusterClient(&redis.ClusterOptions{ Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"}, }) _, err = rdb.Ping().Result() if err ! = nil { return err } return nil}Copy the code

The basic use

Set/get the sample

func redisExample() { err := rdb.Set("score", 100, 0).Err() if err ! = nil { fmt.Printf("set score failed, err:%v\n", err) return } val, err := rdb.Get("score").Result() if err ! = nil { fmt.Printf("get score failed, err:%v\n", err) return } fmt.Println("score", val) val2, err := rdb.Get("name").Result() if err == redis.Nil { fmt.Println("name does not exist") } else if err ! = nil { fmt.Printf("get name failed, err:%v\n", err) return } else { fmt.Println("name", val2) }}Copy the code

Zset sample

Func redisExample2() {zsetKey := "language_rank" languages := [] redis.z {Score: 90.0, Member: }, redis.z {Score: 98.0, Member: "Java"}, redis.z {Score: 95.0, Member: "Python"}, redis.z {Score: 97.0, Member: "Python"}, redis.z {Score: 97.0, Member: "Python"}, redis.z {Score: 97.0, Member: Z{Score: 99.0, Member: "C/C++"},} // ZADD num, err := rdb.zadd (zsetKey, languages...) .Result() if err ! = nil {FMT.Printf("zadd failed, err:%v\n", err) return} FMT.Printf("zadd %d succ.\n", num) // Add 10 newScore to Golang's score, Err := rdb.zincrby (zsetKey, 10.0, "Golang").result () if err! = nil { fmt.Printf("zincrby failed, err:%v\n", err) return } fmt.Printf("Golang's score is %f now.\n", NewScore), err := rdb.zRevRangeWithscores (zsetKey, 0, 2).Result() if err! = nil { fmt.Printf("zrevrange failed, err:%v\n", err) return } for _, z := range ret { fmt.Println(z.Member, } op := redis.zrangeby {Min: "95", Max: "100", } ret, err = rdb.ZRangeByScoreWithScores(zsetKey, op).Result() if err ! = nil { fmt.Printf("zrangebyscore failed, err:%v\n", err) return } for _, z := range ret { fmt.Println(z.Member, z.Score) }}Copy the code

The output is as follows:

$./06redis_demo zadd 0 succ.Golang's score is 100.000000 now.Golang 100C/C++ 99Java 98JavaScript 97Java 98C/C++ 99Golang 100Copy the code

Gets the Key based on the prefix

vals, err := rdb.Keys(ctx, "prefix*").Result()
Copy the code

Execute custom commands

res, err := rdb.Do(ctx, "set", "key", "value").Result()
Copy the code

Press the wildcard to delete the key

When the number of wildcard matching Keys is not large, you can use Keys() to get all Keys and then delete them using the Del command. If the number of keys is too large, you can use the Scan command and the Del command to delete them.

func exampleTongPeiFu() { ctx := context.Background() iter := rdb.Scan(ctx, 0, "prefix*", 0).Iterator() for iter.Next(ctx) { err := rdb.Del(ctx, iter.Val()).Err() if err ! = nil { panic(err) } } if err := iter.Err(); err ! = nil { panic(err) }}Copy the code

Pipeline

Pipeline is primarily a network optimization. It essentially means that the client buffers a bunch of commands and sends them to the server all at once. These commands are not guaranteed to be executed in a transaction. This has the advantage of saving network round trip time (RTT) per command.

The following is a basic example of Pipeline:

pipe := rdb.Pipeline()​incr := pipe.Incr("pipeline_counter")pipe.Expire("pipeline_counter", time.Hour)​_, err := pipe.Exec()fmt.Println(incr.Val(), err)
Copy the code

The above code is equivalent to sending the following two commands to the Redis server for execution at one time, which can reduce one RTT compared to not using Pipeline.

INCR pipeline_counterEXPIRE pipeline_counts 3600
Copy the code

Pipelined can also be used:

var incr *redis.IntCmd_, err := rdb.Pipelined(func(pipe redis.Pipeliner) error {  incr = pipe.Incr("pipelined_counter")  pipe.Expire("pipelined_counter", time.Hour)  return nil})fmt.Println(incr.Val(), err)
Copy the code

In some scenarios, when we have multiple commands to execute, we can consider using pipeline for optimization.

The full sample code is archived at GitHub

Golang operation Redis database complete sample code

The above is about the Go language operation Redis introduction, thank you for reading, if you have questions or comments, please comment in the following exchange.

The article comes from the public account of “Go Keyboard Man”. Welcome to follow and learn together!

Previous article:

Golang operates MySql database