go語(yǔ)言 Redis的使用和操作

Reids

Redis是一個(gè)開(kāi)源的、使用C語(yǔ)言編寫的、支持網(wǎng)絡(luò)交互的、可基于內(nèi)存也可持久化的Key-Value數(shù)據(jù)庫(kù)。

Reids的特點(diǎn)

  • 速度快,因?yàn)閿?shù)據(jù)存在內(nèi)存中,類似于HashMap,HashMap的優(yōu)勢(shì)就是查找和操作的時(shí)間復(fù)雜度都是O(1)
  • 支持豐富數(shù)據(jù)類型,支持string,list,set,sorted set,hash
  • 支持事務(wù),操作都是原子性,所謂的原子性就是對(duì)數(shù)據(jù)的更改要么全部執(zhí)行,要么全部不執(zhí)行
  • 豐富的特性:可用于緩存,消息,按key設(shè)置過(guò)期時(shí)間,過(guò)期后將會(huì)自動(dòng)刪除
  • 可以對(duì)數(shù)據(jù)進(jìn)行持久化和數(shù)據(jù)同步
  • Redis是單進(jìn)程單線程的

golang操作Redis

redigo是GO語(yǔ)言的一個(gè)redis客戶端實(shí)現(xiàn)。項(xiàng)目位于地址

安裝
go get github.com/garyburd/redigo/redis

redigo的使用

連接

package main
import (
    "fmt"
    "github.com/garyburd/redigo/redis"
)
func main() {
    cnn, err := redis.Dial("tcp", "localhost:6379")
    if err != nil {
        fmt.Println("Connect to redis error", err)
        return
    }else {
        fmt.Println("連接成功")
    }
    defer cnn.Close()
}

命令

數(shù)據(jù)類型轉(zhuǎn)換

go對(duì)應(yīng)redis的數(shù)據(jù)類型

Go Type Conversion
[]byte Sent as is
string Sent as is
int, int64 strconv.FormatInt(v)
float64 strconv.FormatFloat(v, 'g', -1, 64)
bool true -> "1", false -> "0"
nil ""
all other types fmt.Print(v)

Redis 命令響應(yīng)會(huì)用以下Go類型表示:

Redis type Go type
error redis.Error
integer int64
simple string string
bulk string []byte or nil if value not present.
array []interface{} or nil if value not present.

可以使用GO的類型斷言或者reply輔助函數(shù)將返回的interface{}轉(zhuǎn)換為對(duì)應(yīng)類型
Do方法組合了Send,Flush和 Receive方法。Do方法先寫入命令,然后清空輸出buffer,最后接收全部掛起響應(yīng)包括Do方發(fā)出的命令的結(jié)果。如果任何響應(yīng)中包含一個(gè)錯(cuò)誤,Do返回錯(cuò)誤。如果沒(méi)有錯(cuò)誤,Do方法返回最后一個(gè)響應(yīng)。

  • 讀寫

寫入值永不過(guò)期

_, err = c.Do("SET", "username", "nick")
if err != nil {
fmt.Println("redis set failed:", err)
}

寫入值10S后過(guò)期

_, err = c.Do("SET", "password", "123456", "EX", "10")
if err != nil {
fmt.Println("redis set failed:", err)
}

簡(jiǎn)單讀

username, err := redis.String(c.Do("GET", "username"))
if err != nil {
fmt.Println("redis get failed:", err)
} else {
fmt.Printf("Got username %v \n", username)
}
  • 批量讀寫

批量讀寫

key:=make([]string,5)
value:=make([]string,5)
for i:=0;i<5 ;i++  {
    key=append(key,string(i) )
    value=append(value,string(i) )
}
_, err = cnn.Do("MSET", key,value)
if err != nil {
    fmt.Println("redis set failed:", err)
}
val,err:= cnn.Do("MGET",key)
if err != nil {
    fmt.Println("redis set failed:", err)
}

批量寫入讀取對(duì)象(Hashtable)

HMSET key field value [field value ...]
HMGET key field [field ...]

檢測(cè)key值是否存在

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)
}

刪除key

_, err = c.Do("DEL", "mykey")
if err != nil {
    fmt.Println("redis delelte failed:", err)
}

設(shè)置過(guò)期時(shí)間

n, _ := rs.Do("EXPIRE", key, 24*3600)  
if n == int64(1) {  
    fmt.Println("success")  
}  

管道

請(qǐng)求/響應(yīng)服務(wù)可以實(shí)現(xiàn)持續(xù)處理新請(qǐng)求,即使客戶端沒(méi)有準(zhǔn)備好讀取舊響應(yīng)。這樣客戶端可以發(fā)送多個(gè)命令到服務(wù)器而無(wú)需等待響應(yīng),最后在一次讀取多個(gè)響應(yīng)。這就是管道化(pipelining),這個(gè)技術(shù)在多年就被廣泛使用了。

c.Send("SET", "foo", "bar")//Send向連接的輸出緩沖中寫入命令
c.Send("GET", "foo")//
c.Flush()//Flush將連接的輸出緩沖清空并寫入服務(wù)器端
//Recevie按照FIFO順序依次讀取服務(wù)器的響應(yīng)
c.Receive() // reply from SET
v, err = c.Receive() // reply from GET

Do方法組合了Send,Flush和 Receive方法。Do方法先寫入命令,然后清空輸出buffer,最后接收全部掛起響應(yīng)包括Do方發(fā)出的命令的結(jié)果。如果任何響應(yīng)中包含一個(gè)錯(cuò)誤,Do返回錯(cuò)誤。如果沒(méi)有錯(cuò)誤,Do方法返回最后一個(gè)響應(yīng)。

并發(fā)

連接并不支持并發(fā)調(diào)用寫入方法(Send,Flush)或者讀取方法(Receive)。但是連接支持并發(fā)的讀寫。

因?yàn)镈o方法組合了Send,F(xiàn)lush和Receive,Do不可以與其他方法并發(fā)執(zhí)行

連接池

package main
import (
    "fmt"
    "github.com/garyburd/redigo/redis"
    "runtime"
    "sync"
    "time"
)
var w sync.WaitGroup
func newRdsPool(server, auth string) *redis.Pool {
    return &redis.Pool{
        //最大空閑
        MaxIdle:     100,
        //最大活動(dòng)量
        MaxActive:   30,
        //空閑超時(shí)
        IdleTimeout: 60 * time.Second,
        Dial: func() (redis.Conn, error) {
            c, err := redis.Dial("tcp", server)
            if err != nil {
                return nil, err
            }
            if auth == "" {
                return c, err
            }
            if _, err := c.Do("AUTH", auth); err != nil {
                c.Close()
                return nil, err
            }
            return c, err
        },
        TestOnBorrow: func(c redis.Conn, t time.Time) error {
            _, err := c.Do("PING")
            return err
        },
    }
}
func main() {
    w.Add(2)
    runtime.GOMAXPROCS(runtime.NumCPU())
    var rc1 redis.Conn = newRdsPool(`127.0.0.1:6379`, ``).Get()
    defer rc1.Close()
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.1 資料 ,最好的入門小冊(cè)子,可以先于一切文檔之前看,免費(fèi)。 作者Antirez的博客,Antirez維護(hù)的R...
    JefferyLcm閱讀 17,320評(píng)論 1 51
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,578評(píng)論 19 139
  • 本文將從Redis的基本特性入手,通過(guò)講述Redis的數(shù)據(jù)結(jié)構(gòu)和主要命令對(duì)Redis的基本能力進(jìn)行直觀介紹。之后概...
    kelgon閱讀 61,663評(píng)論 23 625
  • 看了《西游伏妖篇》,說(shuō)說(shuō)感受。任何事物都有兩面的分化,單單說(shuō)好和壞沒(méi)有什么意思。電影在我看來(lái)特效一般,劇情有點(diǎn)意思...
    天翼至空閱讀 1,186評(píng)論 4 3
  • (一) 村里有個(gè)女兒阿蓮,嫁到一個(gè)偏遠(yuǎn)的小山村里去了,那是一個(gè)很落后的窮苦山村,據(jù)說(shuō)...
    胖小溜閱讀 724評(píng)論 2 4

友情鏈接更多精彩內(nèi)容