天天看点

Go 使用三方 Redis 包操作 Redis

01

概念

Redis 是一个基于内存的非关系型数据库,在项目开发中使用非常广泛,Go 语言操作 Redis 需要使用三方包,我们选择支持 Redis 集群和 Redis 哨兵的 go-redis 包来讲述 Go 语言如何操作 Redis。

go-redis 包需要使用支持 Modules 的 Go 版本,并且使用导入版本控制。所以需要确保初始化 go module,命令如下所示。

初始化

go mod init package_name           

复制

安装 go-redis

go get github.com/go-redis/redis/v8           

复制

02

Redis 单机

Redis 单机连接

方式 1:

rdb := redis.NewClient(&redis.Options{
    Addr:     "localhost:6379",
    Password: "", // no password set
    DB:       0,  // use default DB
})           

复制

go-redis 包提供 NewClient 函数,传入一个指定 Redis 服务器信息的结构体类型的参数,返回一个指向该 Redis 服务器的客户端 *Client。

查看传入参数的结构体完整字段:

type Options struct {
    Network            string
    Addr               string
    Dialer             func(ctx context.Context, network string, addr string) (net.Conn, error)
    OnConnect          func(ctx context.Context, cn *Conn) error
    Username           string
    Password           string
    DB                 int
    MaxRetries         int
    MinRetryBackoff    time.Duration
    MaxRetryBackoff    time.Duration
    DialTimeout        time.Duration
    ReadTimeout        time.Duration
    WriteTimeout       time.Duration
    PoolSize           int
    MinIdleConns       int
    MaxConnAge         time.Duration
    PoolTimeout        time.Duration
    IdleTimeout        time.Duration
    IdleCheckFrequency time.Duration
    readOnly           bool
    TLSConfig          *tls.Config
    Limiter            Limiter
}           

复制

方式 2:

opt, err := redis.ParseURL("redis://localhost:6379/<db>")
if err != nil {
    panic(err)
}

rdb := redis.NewClient(opt)           

复制

go-redis 包提供 ParseURL 函数,传入参数为字符串类型的连接字符串,返回一个 NewClient 函数接收的参数 *Options。

02

Redis 集群

Redis 集群连接

rdb := redis.NewClusterClient(&redis.ClusterOptions{
    Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},

    // To route commands by latency or randomly, enable one of the following.
    //RouteByLatency: true,
    //RouteRandomly: true,
})           

复制

go-redis 包提供 NewClusterClient 函数,传入一个指定 Redis 集群服务器信息的结构体类型的参数,返回一个 Redis 集群的客户端 *ClusterClient。

查看传入参数结构体的完整字段:

type ClusterOptions struct {
    Addrs              []string
    NewClient          func(opt *Options) *Client
    MaxRedirects       int
    ReadOnly           bool
    RouteByLatency     bool
    RouteRandomly      bool
    ClusterSlots       func(context.Context) ([]ClusterSlot, error)
    Dialer             func(ctx context.Context, network string, addr string) (net.Conn, error)
    OnConnect          func(ctx context.Context, cn *Conn) error
    Username           string
    Password           string
    MaxRetries         int
    MinRetryBackoff    time.Duration
    MaxRetryBackoff    time.Duration
    DialTimeout        time.Duration
    ReadTimeout        time.Duration
    WriteTimeout       time.Duration
    PoolSize           int
    MinIdleConns       int
    MaxConnAge         time.Duration
    PoolTimeout        time.Duration
    IdleTimeout        time.Duration
    IdleCheckFrequency time.Duration
    TLSConfig          *tls.Config
}           

复制

03

Redis 哨兵

Redis 哨兵模式连接

rdb := redis.NewFailoverClient(&redis.FailoverOptions{
    MasterName:    "master-name",
    SentinelAddrs: []string{":9126", ":9127", ":9128"},
})           

复制

使用 NewFailoverClusterClient 函数可以将只读命令路由到从 Redis 服务器。

rdb := redis.NewFailoverClusterClient(&redis.FailoverOptions{
    MasterName:    "master-name",
    SentinelAddrs: []string{":9126", ":9127", ":9128"},

    // To route commands by latency or randomly, enable one of the following.
    //RouteByLatency: true,
    //RouteRandomly: true,
})           

复制

连接 Redis 哨兵服务器

sentinel := redis.NewSentinelClient(&redis.Options{
    Addr: ":9126",
})

addr, err := sentinel.GetMasterAddrByName(ctx, "master-name").Result()           

复制

04

Redis 命令

执行 Redis 命令

方式 1:直接获取结果集

var ctx = context.Background()
val, err := rdb.Get(ctx, "key").Result()
if err != nil {
    if err == redis.Nil {
        fmt.Println("key does not exists")
        return
    }
    panic(err)
}
fmt.Println(val)           

复制

方式 2:单独访问 Err() 和 Val() 获取相应的值。

var ctx = context.Background()
get := rdb.Get(ctx, "key")
if err := get.Err(); err != nil {
    if err == redis.Nil {
        fmt.Println("key does not exists")
        return
    }
    panic(err)
}
fmt.Println(get.Val())           

复制

方式 3:执行任意命令

var ctx = context.Background()
get := rdb.Do(ctx, "get", "key")
if err := get.Err(); err != nil {
    if err == redis.Nil {
        fmt.Println("key does not exists")
        return
    }
    panic(err)
}
fmt.Println(get.Val().(string))           

复制

更多特定类型的取值方法:

// Shortcut for get.Val().(string) with error handling.
s, err := get.Text()
num, err := get.Int()
num, err := get.Int64()
num, err := get.Uint64()
num, err := get.Float32()
num, err := get.Float64()
flag, err := get.Bool()           

复制

需要注意的是,第一个参数需要传入 context.Context 类型的参数,作为传入请求的顶级上下文。