Redigo,官方推荐的Redis Go语言客户端的开源实现,支持Print-alike API, Pipelining (transactions), Pub/Sub, Connection pooling, scripting。
连接Connections
Conn接口是访问Redis的主要接口,业务通过调用Dial,DialWithTimeout或者NewConn函数来创建连接。以后会增加共享或者其他类型连接的创建函数。当用完连接以后,应用必须调用连接Close函数。
命令执行Commands
Conn接口有一个通用函数(generic method)来执行Redis方法:
Do(commandName string, args ...interface{}) (reply interface{}, err error)
Redis命令参考指南列出了可用的命令。作为例子,Redis APPEND命令使用方法如下:
n, err := conn.Do("APPEND", "key", "value")
Do方法转换命令参数到二进制串,用于传输到Redis服务器。转换方法如下:
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命令的响应类型使用以下的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.
使用类型断言或者响应值辅助(helper)函数来转换interface{}到特定的Go类型命令结果。
流水线Pipelining
连接Connections使用Send/Flush/Receive来支持命令流水线Pipelining
Send(commandName string, args ...interface{}) error
Flush() error
Receive() (reply interface{}, err error)
Send函数把命令内容写到连接connection的输出buffer。Flush函数把输出buffer的内容发送到Redis服务器。Receive函数从服务器读取单条回复。简单的流水线实例如下:
c.Send("SET", "foo", "bar")
c.Send("GET", "foo")
c.Flush()
c.Receive() // reply from SET
v, err = c.Receive() // reply from GET
Do函数组合了Send/Flush/Receive函数的功能。Do函数执行流程第一步,写入命令内容到输出buffer并发送。第二步,接收未定的响应值(pending replies),包括通过Do发送的所有命令的响应。如果接收的任何一个响应值是error,则Do函数返回error。如果响应值没有error则返回最后的响应值(reply)。如果Do函数的命令参数为空字符串“”,则Do函数刷新(flush)输出缓冲区,并接收未定的响应值,而不发送命令。
使用Send和Do函数可以实现流水线事务:
c.Send("MULTI")
c.Send("INCR", "foo")
c.Send("INCR", "bar")
r, err := c.Do("EXEC")
fmt.Println(r) // prints [1, 1]
并发Concurrency
连接Connections支持给Send/Flush 函数 和 Receive 函数各分配一个并发调用方(concurrent caller)。其他对Do函数的调用都不支持并发。
对Redis的并发返回,使用线程安全池(thread-safe Pool)来获取(get),从goroutine内使用和释放连接。Pool返回的连接Connections有如上所述的并发限制。
发布和订阅PubSub
使用Send/Flush和Receive函数可以实现Pub/Sub 订阅器(subscribers)
c.Send("SUBSCRIBE", "example")
c.Flush()
for {
reply, err := c.Receive()
if err != nil {
return err
}
// process pushed message
}
PubSubConn类型包装Conn,提供易用的函数来实现订阅器。Subscribe, PSubscribe, Unsubscribe, PUnsubscribe函数会Send和flush订阅管理命令。Receive函数在一个类型Switch代码块中转换消息(pubshed message)为用户方便使用的类型。
psc := redis.PubSubConn{c}
psc.Subscribe("example")
for {
switch v := psc.Receive().(type) {
case redis.Message:
fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
case redis.Subscription:
fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
case error:
return v
}
}
响应值辅助函数ReplyHelpers
Bool/Int/Bytes/String/Strings和Values函数转换响应值到特定类型的值。为了方便包装连接Connection的Do和Receive函数的调用,这些函数(Bool/Int/Bytes/String/Strings和Values函数)支持error类型作为第二个参数。如果error非空(non-nil),helper函数返回错误。如果error为空,helper函数转换响应到特定类型:
exists, err := redis.Bool(c.Do("EXISTS", "foo"))
if err != nil {
// handle error return from c.Do or type conversion error.
}
Scan函数转换array响应的各个元素为Go类型:
var value1 int
var value2 string
reply, err := redis.Values(c.Do("MGET", "key1", "key2"))
if err != nil {
// handle error
}
if _, err := redis.Scan(reply, &value1, &value2); err != nil {
// handle error
}