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集群

go-redis 支持 Redis Cluster 客户端,如下面示例,redis.ClusterClient 表示集群对象,对集群内每个 redis 节点使用 redis.Client 对象进行通信,每个 redis.Client 会拥有单独的连接池。
连接到 redis 集群示例,更多配置参数,请参照:https://redis.uptrace.dev/zh/guide/go-redis-option.html#redis-client
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)
            },
        })
  
posted @ 2024-03-20 10:04  左扬  阅读(52)  评论(0编辑  收藏  举报
levels of contents