Go Redis专题精讲
Go Redis专题精讲
一、介绍
https://github.com/redis/go-redis
1.1、客户端列表
go-redis提供各种类型的客户端:
-
- Redis 单节点客户端
- Redis 集群客户端
- Redis 哨兵客户端
- Redis 分片客户端
- Redis 通用客户端
go-redis 也可以用于 kvrocks, kvrocks 是分布式键值 NoSQL 数据库,使用 RocksDB 作为存储引擎,兼容 redis 协议。
二、入门
2.1、Installation
go-redis supports 2 last Go versions and requires a Go version with modules support. So make sure to initialize a Go module:
go mod init github.com/my/repo
Then install go-redis/v9:
go get github.com/redis/go-redis/v9
2.2、QuickStart
import ( "context" "fmt" "github.com/redis/go-redis/v9" ) var ctx = context.Background() func ExampleClient() { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // no password set DB: 0, // use default DB }) err := rdb.Set(ctx, "key", "value", 0).Err() if err != nil { panic(err) } val, err := rdb.Get(ctx, "key").Result() if err != nil { panic(err) } fmt.Println("key", val) val2, err := rdb.Get(ctx, "key2").Result() if err == redis.Nil { fmt.Println("key2 does not exist") } else if err != nil { panic(err) } else { fmt.Println("key2", val2) } // Output: key value // key2 does not exist }
通过在 Options 结构中添加 protocol 选项,可以修改以上内容来指定 RESP 协议的版本:
rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // no password set DB: 0, // use default DB Protocol: 3, // specify 2 for RESP 2 or 3 for RESP 3 })
2.3、Connecting via a redis url
Go-redis 还支持通过 redis uri 规范进行连接。下面的示例演示如何使用字符串轻松地配置连接,并遵循此规范:
import ( "context" "fmt" "github.com/redis/go-redis/v9" ) func ExampleClient() *redis.Client { url := "redis://user:password@localhost:6379/0?protocol=3" opts, err := redis.ParseURL(url) if err != nil { panic(err) } return redis.NewClient(opts) }
2.4、使用 TLS
需要手动设置 tls.conf:
rdb := redis.NewClient(&redis.Options{ TLSConfig: &tls.Config{ MinVersion: tls.VersionTLS12, ServerName: "you domain", //Certificates: []tls.Certificate{cert} }, })
如果你使用的是域名连接,且遇到了类似 x509: cannot validate certificate for xxx.xxx.xxx.xxx because it doesn't
contain any IP SANs的错误,应该在 ServerName 中指定你的域名:
rdb := redis.NewClient(&redis.Options{ TLSConfig: &tls.Config{ MinVersion: tls.VersionTLS12, ServerName: "你的域名", }, })
2.5、SSH 方式
使用 SSH 协议连接:
sshConfig := &ssh.ClientConfig{ User: "root", Auth: []ssh.AuthMethod{ssh.Password("password")}, HostKeyCallback: ssh.InsecureIgnoreHostKey(), Timeout: 15 * time.Second, } sshClient, err := ssh.Dial("tcp", "remoteIP:22", sshConfig) if err != nil { panic(err) } rdb := redis.NewClient(&redis.Options{ Addr: net.JoinHostPort("127.0.0.1", "6379"), Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) { return sshClient.Dial(network, addr) }, // SSH不支持超时设置,在这里禁用 ReadTimeout: -1, WriteTimeout: -1, })
2.6、Context 上下文
go-redis 支持 Context,你可以使用它控制超时或者传递一些数据, 也可以监控 go-redis 性能。
ctx := context.Background()
2.7、执行 Redis 命令
val, err := rdb.Get(ctx, "key").Result() fmt.Println(val)
get := rdb.Get(ctx, "key") fmt.Println(get.Val(), get.Err())
2.8、执行尚不支持的命令
可以使用 Do()
方法执行尚不支持或者任意命令:
val, err := rdb.Do(ctx, "get", "key").Result() if err != nil { if err == redis.Nil { fmt.Println("key does not exists") return } panic(err) } fmt.Println(val.(string))
三、Redis集群
import "github.com/redis/go-redis/v9" rdb := redis.NewClusterClient(&redis.ClusterOptions{ Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"}, })
err := rdb.ForEachShard(ctx, func(ctx context.Context, shard *redis.Client) error { return shard.Ping(ctx).Err() }) if err != nil { panic(err) }
只遍历主节点请使用: ForEachMaster, 只遍历从节点请使用: ForEachSlave
你也可以自定义的设置每个节点的初始化:
rdb := redis.NewClusterClient(&redis.ClusterOptions{ NewClient: func(opt *redis.Options) *redis.NewClient { user, pass := userPassForAddr(opt.Addr) opt.Username = user opt.Password = pass return redis.NewClient(opt) }, })