Go实战--golang中使用redis(redigo和go-redis/redis这个已测试)
自己做測(cè)試了沒(méi)有問(wèn)題,虛擬機(jī)連不上可以把包下載到本地。
版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。?http://blog.csdn.net/wangshubo1989/article/details/75050024
目錄(?)[-]
生命不止,繼續(xù) go go go !!!
以前介紹過(guò)golang中如何使用sqlite3:?
《Go實(shí)戰(zhàn)–go語(yǔ)言操作sqlite數(shù)據(jù)庫(kù)(The way to go)》
今天跟大家分享的是如何在golang中使用redis數(shù)據(jù)庫(kù)。
何為redis
官網(wǎng):?
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是一個(gè)開(kāi)源的、使用C語(yǔ)言編寫(xiě)的、支持網(wǎng)絡(luò)交互的、可基于內(nèi)存也可持久化的Key-Value數(shù)據(jù)庫(kù)。
Redis 優(yōu)勢(shì)?
性能極高 – Redis能讀的速度是110000次/s,寫(xiě)的速度是81000次/s 。
豐富的數(shù)據(jù)類(lèi)型 – Redis支持二進(jìn)制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數(shù)據(jù)類(lèi)型操作。
原子 – Redis的所有操作都是原子性的,同時(shí)Redis還支持對(duì)幾個(gè)操作全并后的原子性執(zhí)行。
豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過(guò)期等等特性。
Redis與其他key-value存儲(chǔ)有什么不同??
Redis有著更為復(fù)雜的數(shù)據(jù)結(jié)構(gòu)并且提供對(duì)他們的原子性操作,這是一個(gè)不同于其他數(shù)據(jù)庫(kù)的進(jìn)化路徑。Redis的數(shù)據(jù)類(lèi)型都是基于基本數(shù)據(jù)結(jié)構(gòu)的同時(shí)對(duì)程序員透明,無(wú)需進(jìn)行額外的抽象。
Redis運(yùn)行在內(nèi)存中但是可以持久化到磁盤(pán),所以在對(duì)不同數(shù)據(jù)集進(jìn)行高速讀寫(xiě)時(shí)需要權(quán)衡內(nèi)存,因?yàn)閿?shù)據(jù)量不能大于硬件內(nèi)存。在內(nèi)存數(shù)據(jù)庫(kù)方面的另一個(gè)優(yōu)點(diǎn)是,相比在磁盤(pán)上相同的復(fù)雜的數(shù)據(jù)結(jié)構(gòu),在內(nèi)存中操作起來(lái)非常簡(jiǎn)單,這樣Redis可以做很多內(nèi)部復(fù)雜性很強(qiáng)的事情。同時(shí),在磁盤(pán)格式方面他們是緊湊的以追加的方式產(chǎn)生的,因?yàn)樗麄儾⒉恍枰M(jìn)行隨機(jī)訪(fǎng)問(wèn)。
windows安裝redis
這里只簡(jiǎn)單介紹一下Windows上redis的安裝:?
在官網(wǎng)中可以看到這樣的描述:?
Windows?
The Redis project does not officially support Windows. However, the Microsoft Open Tech group develops and maintains this Windows port targeting Win64
下載?
直接去github上下載就好了:?
https://github.com/MicrosoftArchive/redis/releases
這里可以下載msi文件和zip文件,兩者區(qū)別就是msi文件是安裝文件,安裝的過(guò)程中會(huì)幫助我們配好環(huán)境變量,所以推薦。
這里需要提示一下安裝過(guò)程中,如果修改了端口號(hào),一定要記住:?
圖1
啟動(dòng)服務(wù)端?
安裝成功后,通過(guò)終端鍵入如下命令:
- 1
一切沒(méi)問(wèn)題會(huì)出現(xiàn)下面的提示:?
[11368] 13 Jul 10:10:31.487 # Creating Server TCP listening socket 127.0.0.1:6379: bind: No error
啟動(dòng)客戶(hù)端?
新打開(kāi)一個(gè)終端,啟動(dòng)redis客戶(hù)端,鍵入命令:
- 1
測(cè)試:
127.0.0.1:6379> set mykey abc OK 127.0.0.1:6379> get mykey "abc"- 1
- 2
- 3
- 4
開(kāi)源庫(kù)redigo的使用
github地址:?
https://github.com/garyburd/redigo
文檔地址:?
http://godoc.org/github.com/garyburd/redigo/redis
獲取:
go get github.com/garyburd/redigo/redis- 1
連接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() }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
讀寫(xiě)?
這里寫(xiě)入的值永遠(yuǎn)不會(huì)過(guò)期
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
如何設(shè)置過(guò)期呢,可以使用SET的附加參數(shù):
package mainimport ("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)} }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
輸出:?
Get mykey: superWang?
redis get failed: redigo: nil returned
批量寫(xiě)入讀取
MGET key [key …]?
MSET key value [key value …]
批量寫(xiě)入讀取對(duì)象(Hashtable)?
HMSET key field value [field value …]?
HMGET key field [field …]
檢測(cè)值是否存在?
EXISTS key
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
輸出:?
exists or not: false
刪除?
DEL key [key …]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
輸出:?
Get mykey: superWang?
redis get failed: redigo: nil returned
讀寫(xiě)json到redis
package mainimport ("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]stringvalueGet, 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"]) }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
設(shè)置過(guò)期時(shí)間?
EXPIRE key seconds
- 1
- 2
- 3
- 4
- 5
列表操作?
命令:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
代碼實(shí)現(xiàn):
package mainimport ("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)))} }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
輸出:?
mysql?
mongodb?
redis
管道
請(qǐng)求/響應(yīng)服務(wù)可以實(shí)現(xiàn)持續(xù)處理新請(qǐng)求,即使客戶(hù)端沒(méi)有準(zhǔn)備好讀取舊響應(yīng)。這樣客戶(hù)端可以發(fā)送多個(gè)命令到服務(wù)器而無(wú)需等待響應(yīng),最后在一次讀取多個(gè)響應(yīng)。這就是管道化(pipelining),這個(gè)技術(shù)在多年就被廣泛使用了。距離,很多POP3協(xié)議實(shí)現(xiàn)已經(jīng)支持此特性,顯著加速了從服務(wù)器下載新郵件的過(guò)程。?
Redis很早就支持管道化,所以無(wú)論你使用任何版本,你都可以使用管道化技術(shù)
連接支持使用Send(),Flush(),Receive()方法支持管道化操作
Send(commandName string, args ...interface{}) error Flush() error Receive() (reply interface{}, err error)- 1
- 2
- 3
Send向連接的輸出緩沖中寫(xiě)入命令。Flush將連接的輸出緩沖清空并寫(xiě)入服務(wù)器端。Recevie按照FIFO順序依次讀取服務(wù)器的響應(yīng)。下例展示了一個(gè)簡(jiǎn)單的管道:
c.Send("SET", "foo", "bar") c.Send("GET", "foo") c.Flush() c.Receive() // reply from SET v, err = c.Receive() // reply from GET- 1
- 2
- 3
- 4
- 5
Do方法組合了Send,Flush和 Receive方法。Do方法先寫(xiě)入命令,然后清空輸出buffer,最后接收全部掛起響應(yīng)包括Do方發(fā)出的命令的結(jié)果。如果任何響應(yīng)中包含一個(gè)錯(cuò)誤,Do返回錯(cuò)誤。如果沒(méi)有錯(cuò)誤,Do方法返回最后一個(gè)響應(yīng)。
開(kāi)源庫(kù)go-redis/redis的使用
github地址:?
https://github.com/go-redis/redis
文檔地址:?
https://godoc.org/github.com/go-redis/redis
獲取:
go get -u github.com/go-redis/redis- 1
應(yīng)用:
package mainimport ("fmt""github.com/go-redis/redis" )func main() {client := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379",Password: "", // no password setDB: 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)} }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
輸出:?
PONG?
key value?
key2 does not exists
來(lái)源:http://blog.csdn.net/wangshubo1989/article/details/75050024
總結(jié)
以上是生活随笔為你收集整理的Go实战--golang中使用redis(redigo和go-redis/redis这个已测试)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 掌中借是正规的吗
- 下一篇: go语言连接redis(已测试)