TheRiver | blog

You have reached the world's edge, none but devils play past here

0%

golang连接redis

前言

通过redigo连接redis,以后有时间的话搞搞go-redis.

参考

https://github.com/go-redis/redis

https://github.com/gomodule/redigo

redis命令

func

func Dial

1
func Dial(network, address string, options ...DialOption) (Conn, error)

Dial connects to the Redis server at the given network and address using the specified options.

Connect to local instance of Redis running on the default port.

Code:

1
2
3
4
5
c, err := redis.Dial("tcp", ":6379")
if err != nil {
// handle error
}
defer c.Close()

Connect to an Redis instance using the Redis ACL system

Code:

1
2
3
4
5
6
7
8
c, err := redis.Dial("tcp", "localhost:6379",
redis.DialUsername("username"),
redis.DialPassword("password"),
)
if err != nil {
// handle error
}
defer c.Close()

func DialTimeout

1
func DialTimeout(network, address string, connectTimeout, readTimeout, writeTimeout time.Duration) (Conn, error)

DialTimeout acts like Dial but takes timeouts for establishing the connection to the server, writing a command and reading a reply.

Deprecated: Use Dial with options instead.

func NewConn

1
func NewConn(netConn net.Conn, readTimeout, writeTimeout time.Duration) Conn

NewConn returns a new Redigo connection for the given net connection.

func do

1
Do(commandName string, args ...interface{}) (reply interface{}, err error)

The Do method converts command arguments to bulk strings for transmission to the server as follows:

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.Fprint(w, v)

Redis command reply types are represented using the following Go types:

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.

func bytes

1
func Bytes(reply interface{}, err error) ([]byte, error)

Bytes is a helper that converts a command reply to a slice of bytes. If err is not equal to nil, then Bytes returns nil, err. Otherwise Bytes converts the reply to a slice of bytes as follows:

Reply type      Result
bulk string     reply, nil
simple string   []byte(reply), nil
nil             nil, ErrNil
other           nil, error

func ByteSlices

1
func ByteSlices(reply interface{}, err error) ([][]byte, error)

ByteSlices is a helper that converts an array command reply to a [][]byte. If err is not equal to nil, then ByteSlices returns nil, err. Nil array items are stay nil. ByteSlices returns an error if an array item is not a bulk string or nil.

func Bool

1
func Bool(reply interface{}, err error) (bool, error)

Bool is a helper that converts a command reply to a boolean. If err is not equal to nil, then Bool returns false, err. Otherwise Bool converts the reply to boolean as follows:

Reply type Result
integer value != 0, nil
bulk string strconv.ParseBool(reply)
nil false, ErrNil
other false, error

demo

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package main

import (
"fmt"
"log"
"time"

"github.com/gomodule/redigo/redis"
)

//go get -u "github.com/gomodule/redigo/redis"
//go get -u "github.com/gogf/gf/net/gtcp"
func redis_open() (redis.Conn, error) {
connectTimeout := 10 * time.Second
readTimeout := 10 * time.Second
writeTimeout := 10 * time.Second

/*
c1, err := redis.Dial("tcp", "127.0.0.1:6379",
redis.DialPassword("123456"),
redis.DialConnectTimeout(connectTimeout),
redis.DialReadTimeout(readTimeout),
redis.DialWriteTimeout(writeTimeout))
defer c1.Close()
if err != nil {
// handle error
return nil, err
}
*/

/*
conn, err := net.Dial("tcp", "127.0.0.1:6379")
if err != nil {
log.Fatal(err)
}

c2 := redis.NewConn(conn, readTimeout, writeTimeout)
*/

c3, err := redis.DialTimeout("tcp", "127.0.0.1:6379",
connectTimeout,
readTimeout,
writeTimeout)
//defer c3.Close()
if err != nil {
// handle error
return nil, err
}

if _, err = c3.Do("AUTH", "123456"); err != nil {
log.Fatal(err)
}

return c3, nil
}

func main() {
cache, err := redis_open()
defer cache.Close()
if err != nil {
log.Fatal(err)
}

if _, err = cache.Do("SET", "key1", "values1"); err != nil {
log.Fatal(err)
}

bytes, err := redis.Bytes(cache.Do("Get", "key1"))
if err != nil {
log.Fatal(err)
}

fmt.Println(string(bytes))
}

pipeline

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
if _, err = cache.Do("SET", "key2", 1); err != nil {
log.Fatal(err)
}
cache.Send("INCR", "key2")
cache.Send("INCR", "key2")
cache.Send("INCR", "key2")
bytes, err := redis.Bytes(cache.Do("Get", "key2"))
if err != nil {
log.Fatal(err)
}

n, _ := strconv.Atoi(string(bytes))
fmt.Println(n) //4

if _, err = cache.Do("SET", "key3", 1); err != nil {
log.Fatal(err)
}
cache.Send("INCR", "key3")
cache.Send("INCR", "key3")
cache.Send("INCR", "key3")
cache.Flush()

n1, err := cache.Receive()
if err != nil {
log.Fatal(err)
}
fmt.Println(n1) //2

n2, err := cache.Receive()
if err != nil {
log.Fatal(err)
}
fmt.Println(n2) //3

n3, err := cache.Receive()
if err != nil {
log.Fatal(err)
}
fmt.Println(n3) //4

通过Do的get返回的interface{}需要转换成切片再转成数字,receive返回的直接就是interface{}->int64了,这个后面再看下原因。

这里主要的点是连续作业,send+flush+receive或者send+do,do相当于flush+receive了。也可以DO(“”)来flush然后取上一条命令的结果。

ending

----------- ending -----------