目录
golang连接数据常用有两个包:
redigo包装较为精练,一个Do方法涵盖CRUD,但包本身不支持连接redis集群;
go-redis包装程度高,方法多,支持redis集群;
由于实习公司项目原本用的redigo不希望更改,并且希望也能同时支持集群,故本文使用redigo包进行操作。
go get github.com/gomodule/redigo
打开redis服务(默认6379端口),注意防火墙的开启。
redis-server
1.不使用连接池,直接拨号创建连接
import "github.com/gomodule/redigo/redis"
conn, err := redis.Dial("tcp", "127.0.0.1:6379")
if err != nil {
fmt.Println(err)
return
}
defer conn.Close()
2.使用连接池创建连接
import "github.com/gomodule/redigo/redis"
pool := redigoAlone.Pool{
MaxIdle: 5,
MaxActive: 10,
IdleTimeout: time.Minute,
Dial: func() (redigoAlone.Conn, error) {
return redigoAlone.Dial("tcp", "127.0.0.1:6379")
},
TestOnBorrow: func(c redigoAlone.Conn, t time.Time) error {
_, err := c.Do("PING")
return err
},
}
conn := pool.Get()
使用Do方法,第一个参数传入操作命令,后续参数传入键值,与redis-cli命令行操作几乎一致。
conn.Do("SET","s1","test")
res, err := redis.String(conn.Do("GET", "s1"))
String函数为redigo中定义的一系列参数类型转换的工具方法。
p := redigoAlone.PubSubConn{
Conn: conn,
}
// subscribe the channel1
err := p.Subscribe("channel1")
defer p.Unsubscribe("channel1")
if err != nil{
fmt.Println("Subscribe err:",err)
return
}
// listen to the subscribed channel
for {
v := p.Receive()
fmt.Println(v)
}
通过conn获取PubSubConn,后者集成了发布订阅的相关方法,简单调用即可。
注意搭建端口的开放
由于redigo自身不支持集群,所以我们需要导入额外的包进行集群操作
从redigo文档中有两个相关包的推荐:
github.com/chasex/redis-go-cluster
其中redis-go-cluster包在使用时是有些问题:集群MOVED端口时他会拨号给ip:7002@17002(假设MOVED到7002),其中17002理论上是集群节点之间通讯使用,不知为何。
改用几乎一样的github.com/gitstliu/go-redis-cluster包即可正常连接集群。
此外redis-go-cluster与go-redis-cluster都不支持发布订阅操作,但项目需要,故选用redisc
连接池创建函数
func createPool(addr string, opts ...redis.DialOption) (*redis.Pool, error) {
return &redis.Pool{
MaxIdle: 5,
MaxActive: 10,
IdleTimeout: time.Minute,
Dial: func() (redis.Conn, error) {
return redis.Dial("tcp", addr, opts...)
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")
return err
},
}, nil
}
创建集群对象获取连接
cluster := redisc.Cluster{
StartupNodes: []string{"127.0.0.1:7000","127.0.0.1:7001","127.0.0.1:7002"},
DialOptions: []redis.DialOption{redigoAlone.DialConnectTimeout(5 * time.Second)},
CreatePool: createPool,
}
defer cluster.Close()
if err := cluster.Refresh(); err != nil {
log.Fatalf("Refresh failed: %v", err)
}
// get a connection from the cluster
conn := cluster.Get()
defer conn.Close()
cluster对象所Get到的conn就是redigo包中定义的conn接口的实例,所以这个conn的使用和单机模式下的使用完全一样,包括实例化操作发布订阅的PubSubConn,自然支持发布订阅。