Original link: https://blog.csdn.net/wangshubo1989/article/details/75050024/
Life goes on, go go go!!!
Previously, I introduced how to use sqlite3 in golang:
<Go practice - go language operates sqlite database (The way to go)>
Today I want to share with you how to use redis database in golang.
##What is redis
Official website:
https://redis.io/
Redis is an in-memory database open-source software project implementing a networked, in-memory Key-Value store with optional durability.Redis It is an open-source key value database written in C language, which supports network interaction and can be memory based or persistent.
Redis advantages
Very high performance - Redis can read 110000 times / s and write 81000 times / s.
Rich data types - Redis supports string, lists, hashes, sets and Ordered Sets data type operations of binary cases.
Atom - all operations of Redis are atomic. At the same time, Redis also supports atomic execution after several operations are fully combined.
Rich features - Redis also supports publish/subscribe, notification, key expiration and other features.
How is Redis different from other key value stores?
Redis has a more complex data structure and provides atomic operations on them, which is a different evolution path from other databases. Redis's data types are based on the basic data structure and transparent to programmers without any additional abstraction.
Redis runs in memory but can be persisted to disk, so it needs to balance memory when reading and writing different data sets at high speed, because the amount of data cannot be greater than the hardware memory. Another advantage of in memory database is that compared with the same complex data structure on disk, it is very simple to operate in memory, so redis can do many internal complex things. At the same time, in terms of disk format, they are generated in a compact and additional way, because they do not need random access.
##windows install redis
Here is a brief introduction to the installation of redis on Windows:
You can see this description on the official website:
Windows
The Redis project does not officially support Windows. However, the Microsoft Open Tech group develops and maintains this Windows port targeting Win64
download
Just go to github and download it:
https://github.com/MicrosoftArchive/redis/releases
Here you can download the msi file and the zip file. The difference between them is that the msi file is an installation file. During the installation process, it will help us configure the environment variables, so it is recommended.
Here you need to note that during the installation process, if you change the port number, you must remember:
Figure 1
Start server
After the installation is successful, type the following command through the terminal:
redis-server.exe redis.windows.conf
If everything is OK, the following prompt will appear:
[11368] 13 Jul 10:10:31.487 # Creating Server TCP listening socket 127.0.0.1:6379: bind: No error
Start client
Open a new terminal, start the redis client, and type the command:
redis-cli.exe -h 127.0.0.1 -p 6379
Test:
127.0.0.1:6379> set mykey abc OK 127.0.0.1:6379> get mykey "abc"
##The use of redigo
github address:
https://github.com/garyburd/redigo
Document address:
http://godoc.org/github.com/garyburd/redigo/redis
obtain:
go get github.com/garyburd/redigo/redis
Connect to redis
package main import ( "fmt" "github.com/garyburd/redigo/redis" ) func main() { c, err := redis.Dial("tcp", "127.0.0.1:6379") if err != nil { fmt.Println("Connect to redis error", err) return } defer c.Close() }
Reading and writing
The value written here will never expire
package main import ( "fmt" "github.com/garyburd/redigo/redis" ) func main() { c, err := redis.Dial("tcp", "127.0.0.1:6379") if err != nil { fmt.Println("Connect to redis error", err) return } defer c.Close() _, err = c.Do("SET", "mykey", "superWang") if err != nil { fmt.Println("redis set failed:", err) } username, err := redis.String(c.Do("GET", "mykey")) if err != nil { fmt.Println("redis get failed:", err) } else { fmt.Printf("Get mykey: %v \n", username) } }
How to SET expiration? You can use SET's additional parameters:
package main import ( "fmt" "time" "github.com/garyburd/redigo/redis" ) func main() { c, err := redis.Dial("tcp", "127.0.0.1:6379") if err != nil { fmt.Println("Connect to redis error", err) return } defer c.Close() _, err = c.Do("SET", "mykey", "superWang", "EX", "5") if err != nil { fmt.Println("redis set failed:", err) } username, err := redis.String(c.Do("GET", "mykey")) if err != nil { fmt.Println("redis get failed:", err) } else { fmt.Printf("Get mykey: %v \n", username) } time.Sleep(8 * time.Second) username, err = redis.String(c.Do("GET", "mykey")) if err != nil { fmt.Println("redis get failed:", err) } else { fmt.Printf("Get mykey: %v \n", username) } }
Output:
Get mykey: superWang
redis get failed: redigo: nil returned
Bulk write read
MGET key [key ...]
MSET key value [key value ...]
Bulk write read object (Hashtable)
HMSET key field value [field value ...]
HMGET key field [field ...]
Check whether the value exists
EXISTS key
package main import ( "fmt" "github.com/garyburd/redigo/redis" ) func main() { c, err := redis.Dial("tcp", "127.0.0.1:6379") if err != nil { fmt.Println("Connect to redis error", err) return } defer c.Close() _, err = c.Do("SET", "mykey", "superWang") if err != nil { fmt.Println("redis set failed:", err) } is_key_exit, err := redis.Bool(c.Do("EXISTS", "mykey1")) if err != nil { fmt.Println("error:", err) } else { fmt.Printf("exists or not: %v \n", is_key_exit) } }
Output:
exists or not: false
delete
DEL key [key ...]
package main import ( "fmt" "github.com/garyburd/redigo/redis" ) func main() { c, err := redis.Dial("tcp", "127.0.0.1:6379") if err != nil { fmt.Println("Connect to redis error", err) return } defer c.Close() _, err = c.Do("SET", "mykey", "superWang") if err != nil { fmt.Println("redis set failed:", err) } username, err := redis.String(c.Do("GET", "mykey")) if err != nil { fmt.Println("redis get failed:", err) } else { fmt.Printf("Get mykey: %v \n", username) } _, err = c.Do("DEL", "mykey") if err != nil { fmt.Println("redis delelte failed:", err) } username, err = redis.String(c.Do("GET", "mykey")) if err != nil { fmt.Println("redis get failed:", err) } else { fmt.Printf("Get mykey: %v \n", username) } }
Output:
Get mykey: superWang
redis get failed: redigo: nil returned
Read and write json to redis
package main import ( "encoding/json" "fmt" "github.com/garyburd/redigo/redis" ) func main() { c, err := redis.Dial("tcp", "127.0.0.1:6379") if err != nil { fmt.Println("Connect to redis error", err) return } defer c.Close() key := "profile" imap := map[string]string{"username": "666", "phonenumber": "888"} value, _ := json.Marshal(imap) n, err := c.Do("SETNX", key, value) if err != nil { fmt.Println(err) } if n == int64(1) { fmt.Println("success") } var imapGet map[string]string valueGet, err := redis.Bytes(c.Do("GET", key)) if err != nil { fmt.Println(err) } errShal := json.Unmarshal(valueGet, &imapGet) if errShal != nil { fmt.Println(err) } fmt.Println(imapGet["username"]) fmt.Println(imapGet["phonenumber"]) }
Set expiration time
EXPIRE key seconds
// Set expiration time to 24 hours n, _ := rs.Do("EXPIRE", key, 24*3600) if n == int64(1) { fmt.Println("success") }
List operation
Command:
redis 127.0.0.1:6379> LPUSH runoobkey redis (integer) 1 redis 127.0.0.1:6379> LPUSH runoobkey mongodb (integer) 2 redis 127.0.0.1:6379> LPUSH runoobkey mysql (integer) 3 redis 127.0.0.1:6379> LRANGE runoobkey 0 10 1) "mysql" 2) "mongodb" 3) "redis"
Code implementation:
package main import ( "fmt" "github.com/garyburd/redigo/redis" ) func main() { c, err := redis.Dial("tcp", "127.0.0.1:6379") if err != nil { fmt.Println("Connect to redis error", err) return } defer c.Close() _, err = c.Do("lpush", "runoobkey", "redis") if err != nil { fmt.Println("redis set failed:", err) } _, err = c.Do("lpush", "runoobkey", "mongodb") if err != nil { fmt.Println("redis set failed:", err) } _, err = c.Do("lpush", "runoobkey", "mysql") if err != nil { fmt.Println("redis set failed:", err) } values, _ := redis.Values(c.Do("lrange", "runoobkey", "0", "100")) for _, v := range values { fmt.Println(string(v.([]byte))) } }
Output:
mysql
mongodb
redis
The Conduit
The request / response service enables continuous processing of new requests, even if the client is not ready to read the old response. In this way, the client can send multiple commands to the server without waiting for a response, and finally read multiple responses at a time. This is pipelining, which has been widely used for many years. Distance, many POP3 protocol implementations already support this feature, significantly accelerating the process of downloading new mail from the server.
Redis supports pipelining very early, so no matter what version you use, you can use pipelining technology
Connection supports the use of Send(), Flush(), Receive() method to support pipelining operation
Send(commandName string, args ...interface{}) error Flush() error Receive() (reply interface{}, err error)
Send writes a command to the output buffer of the connection. Flush clears the output buffer of the connection and writes it to the server. Recevie reads the server's responses in FIFO order. The following example shows a simple pipeline:
c.Send("SET", "foo", "bar") c.Send("GET", "foo") c.Flush() c.Receive() // reply from SET v, err = c.Receive() // reply from GET
The Do method combines the Send,Flush, and Receive methods. The Do method first writes the command, then clears the output buffer, and finally receives all the pending responses including the results of the command issued by the Do party. If any response contains an error, Do returns an error. If there are no errors, the Do method returns the last response.
##Use of open source library go redis / redis
github address:
https://github.com/go-redis/redis
Document address:
https://godoc.org/github.com/go-redis/redis
obtain:
go get -u github.com/go-redis/redis
Application:
package main import ( "fmt" "github.com/go-redis/redis" ) func main() { client := redis.NewClient(&redis.Options{ Addr: "127.0.0.1:6379", Password: "", // no password set DB: 0, // use default DB }) pong, err := client.Ping().Result() fmt.Println(pong, err) err = client.Set("key", "value", 0).Err() if err != nil { panic(err) } val, err := client.Get("key").Result() if err != nil { panic(err) } fmt.Println("key", val) val2, err := client.Get("key2").Result() if err == redis.Nil { fmt.Println("key2 does not exists") } else if err != nil { panic(err) } else { fmt.Println("key2", val2) } }
Output:
PONG
key value
key2 does not exists