go 连接redis集群

最近用redis shake做redis数据迁移,由于redis提供的客户端没有用于查看集群的工具,且我部署的redis集群是基于k8s来构建的,没有使用ingress做转发,所以只能在k8s内部访问集群,于是我先用go+gin框架编写了访问redis集群的代码,然后打成镜像,再部署到k8s中,创建一个svc类型为NodePort方便外部访问。

环境搭建完毕后,访问接口,发现连接redis集群失败,报错:

dial tcp: lookup redis-cluster-v2-0.redis-cluster-v2.redis: i/o timeout

我尝试在容器内部ping | telnet redis集群某一结点地址,发现网络是可通的,后面在代码中新增net.dail()去连接redis集群,报另一个错误:

 got 4 elements in cluster info address, expected 2 or 3

百度发现使用的go redis版本与redis的版本不一致造成的,

  • Redis 6.0及以下版本:选择Go-redis v8.0及以下版本。

  • Redis 7.0及以上版本:选择Go-redis v9.0及以上版本。

由于我部署的redis集群是7.0,但go redis使用的版本是 v8["github.com/go-redis/redis/v8"],于是修改go redis版本:

   "github.com/redis/go-redis/v9"

重新部署一遍就可以了,

go redis cluster 代码:

package client

import (
    "context"
    "github.com/BurntSushi/toml"
    "github.com/redis/go-redis/v9"
    "net"
    "redis-cluster-web/log"
)

type RedisClient struct {
    *redis.Client
    *redis.ClusterClient
}

type Conf struct {
    RedisConf `toml:"redis"`
}

type RedisConf struct {
    Addrs    []string `toml:"addrs"`
    Addr     string   `json:"addr"`
    Database int      `toml:"database"`
    Password string   `toml:"password"`
}

var RC RedisClient

func init() {
    RC.NewRedisClient()
    RC.NewRedisClusterClient()
}

func (r *RedisClient) NewRedisClient() {
    conf := Conf{}
    _, err := toml.DecodeFile("redis.toml", &conf)
    if err != nil {
        log.Error.Println("read redis conf err:", err)
        return
    }
    redisAddr := conf.Addr
    r.Client = redis.NewClient(&redis.Options{
        Addr:     redisAddr,
        Password: conf.Password,
    })
}
// 我把redis配置写在.toml的配置文件中
func (r *RedisClient) NewRedisClusterClient() {
    conf := Conf{}
    _, err := toml.DecodeFile("redis.toml", &conf)
    if err != nil {
        log.Error.Println("read redis conf err:", err)
        return
    }
    r.ClusterClient = redis.NewClusterClient(&redis.ClusterOptions{
        Addrs: conf.Addrs,
    })
    // 打印集群信息
    info := r.ClusterClient.ClusterInfo(context.Background())
    // 打印集群节点信息 
    nodes := r.ClusterClient.ClusterNodes(context.Background())
    log.Info.Println(info)
    log.Info.Println(nodes)
    // dial redis节点
    for _, addr := range conf.Addrs {
        _, err = net.Dial("tcp", addr)
        if err != nil {
            log.Error.Println(err)
        } else {
            log.Info.Println("dail ", addr, " success")
        }
    }
}

你可能感兴趣的:(golang,redis,缓存,数据库)