帮你快速理解、总结文档立即下载

Go 连接示例

最近更新时间:2026-10-20 11:39:01
本文档已由 AI 辅助审校
我的收藏
本文介绍使用 Go 客户端通过代理模式和直连模式连接腾讯云分布式缓存数据库实例的示例。

准备工作

环境要求

Go 1.18及以上版本。
Go Modules 包管理。

安装客户端

推荐使用 go-redis 客户端(v9及以上版本):
go get github.com/redis/go-redis/v9

获取连接信息

2. 在实例列表中,单击目标实例 ID,进入实例详情页。
3. 在网络信息区域,获取实例的连接地址和端口号。
代理模式:获取 VIP 地址和端口(默认6379)。
直连模式:获取各分片节点地址和端口(默认6379)。
4. 在配置信息区域,获取实例的连接密码。代理模式与直连模式的认证方式不同:
代理模式:默认账号使用 实例 ID:密码 格式,自定义账号使用 用户名@密码 格式;免密认证实例无需密码。
直连模式:复用 Redis 原生 ACL 认证机制,不支持 用户名@密码 拼接格式,支持以下两种认证方式:
默认账号:仅需密码,即 AUTH password。
自定义账号:需同时指定账号名与密码,即 AUTH account password。

代理模式连接示例

代理模式下,客户端通过 Proxy 代理层提供的统一 VIP 地址连接实例,Proxy 自动处理请求路由和故障转移,客户端无需感知后端拓扑变化。

连接池示例(推荐)

package main

import (
"context"
"fmt"
"time"

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

func main() {
ctx := context.Background()

// 创建 Redis 客户端
rdb := redis.NewClient(&redis.Options{
Addr: "192.xx.xx.2:6379", // 实例 VIP 地址
Password: "crs-xxxx:密码", // 默认账号密码格式:实例ID:密码
DB: 0, // 数据库编号
PoolSize: 200, // 连接池大小
MinIdleConns: 50, // 最小空闲连接数
MaxIdleConns: 200, // 最大空闲连接数
DialTimeout: 2 * time.Second, // 连接超时
ReadTimeout: 2 * time.Second, // 读取超时
WriteTimeout: 2 * time.Second, // 写入超时
PoolTimeout: 3 * time.Second, // 连接池获取超时
ConnMaxIdleTime: 30 * time.Minute, // 空闲连接最大存活时间
})

// 测试连接
pong, err := rdb.Ping(ctx).Result()
if err != nil {
panic(fmt.Sprintf("Redis connection failed: %v", err))
}
fmt.Println("Redis connected:", pong)

// 写入数据
err = rdb.Set(ctx, "name", "腾讯云分布式缓存数据库", 0).Err()
if err != nil {
panic(err)
}

// 读取数据
val, err := rdb.Get(ctx, "name").Result()
if err != nil {
panic(err)
}
fmt.Println("get name:", val)

// 设置带过期时间的 Key
err = rdb.Set(ctx, "session:user123", "session_data", 3600*time.Second).Err()
if err != nil {
panic(err)
}

// 哈希操作
err = rdb.HSet(ctx, "user:1001", map[string]interface{}{
"name": "张三",
"age": "28",
}).Err()
if err != nil {
panic(err)
}

name, err := rdb.HGet(ctx, "user:1001", "name").Result()
if err != nil {
panic(err)
}
fmt.Println("user name:", name)

// 列表操作
err = rdb.LPush(ctx, "queue:tasks", "task1", "task2", "task3").Err()
if err != nil {
panic(err)
}

task, err := rdb.RPop(ctx, "queue:tasks").Result()
if err != nil {
panic(err)
}
fmt.Println("dequeued task:", task)

// Pipeline 批量操作
pipe := rdb.Pipeline()
pipe.Set(ctx, "key1", "value1", 0)
pipe.Set(ctx, "key2", "value2", 0)
pipe.Set(ctx, "key3", "value3", 0)
pipe.Get(ctx, "key1")
pipe.Get(ctx, "key2")
pipe.Get(ctx, "key3")
cmds, err := pipe.Exec(ctx)
if err != nil {
panic(err)
}
for _, cmd := range cmds {
fmt.Printf("pipeline result: %v\\n", cmd)
}

// 关闭连接
rdb.Close()
}

自定义账号连接示例

package main

import (
"context"
"fmt"
"time"

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

func main() {
ctx := context.Background()

rdb := redis.NewClient(&redis.Options{
Addr: "192.xx.xx.2:6379",
Password: "myuser@MyPassword", // 代理模式自定义账号:用户名@密码整体作为密码传入,不单独设置 Username(区别于直连模式 ACL 的账号名/密码分离传参)
DB: 0,
PoolSize: 200,
MinIdleConns: 50,
DialTimeout: 2 * time.Second,
ReadTimeout: 2 * time.Second,
WriteTimeout: 2 * time.Second,
})

pong, err := rdb.Ping(ctx).Result()
if err != nil {
panic(err)
}
fmt.Println("Redis connected:", pong)

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("get key:", val)

rdb.Close()
}

SSL 加密连接示例

package main

import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"os"
"time"

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

func main() {
ctx := context.Background()

// 加载 CA 证书
caCert, err := os.ReadFile("/path/to/ca.pem")
if err != nil {
panic(err)
}

caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)

// 配置 TLS
tlsConfig := &tls.Config{
RootCAs: caCertPool,
InsecureSkipVerify: false, // 验证服务端证书
}

rdb := redis.NewClient(&redis.Options{
Addr: "192.xx.xx.2:6379",
Password: "crs-xxxx:密码",
DB: 0,
PoolSize: 200,
MinIdleConns: 50,
DialTimeout: 2 * time.Second,
ReadTimeout: 2 * time.Second,
WriteTimeout: 2 * time.Second,
TLSConfig: tlsConfig,
})

pong, err := rdb.Ping(ctx).Result()
if err != nil {
panic(err)
}
fmt.Println("SSL Redis connected:", pong)

err = rdb.Set(ctx, "ssl_test", "encrypted_connection", 0).Err()
if err != nil {
panic(err)
}

val, err := rdb.Get(ctx, "ssl_test").Result()
if err != nil {
panic(err)
}
fmt.Println("ssl_test:", val)

rdb.Close()
}

直连模式连接示例

直连模式下,客户端使用 Redis Cluster 协议直接连接各分片节点,本地处理 MOVED/ASK 重定向,可直接使用社区标准的 Redis Cluster 客户端接入。
说明:
直连模式仅适用于集群架构实例。
需使用 go-redis 的 ClusterClient。
需在控制台开启直连模式并获取各分片节点的连接地址。
认证方式复用 Redis 原生 ACL 机制:默认账号仅传密码,自定义账号需分别传入账号名与密码,不支持 用户名@密码 拼接格式。
直连模式暂不支持 SSL 加密连接。

ClusterClient 基础连接示例

package main

import (
"context"
"fmt"
"time"

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

func main() {
ctx := context.Background()

// 创建集群客户端
rdc := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{
"192.xx.xx.2:6379", // 分片节点地址
"192.xx.xx.3:6379",
"192.xx.xx.4:6379",
},
Password: "password", // 直连模式默认账号仅传密码,不带实例 ID 前缀
PoolSize: 200, // 每个节点连接池大小
MinIdleConns: 50, // 每个节点最小空闲连接
MaxRedirects: 3, // 最大重定向次数
DialTimeout: 2 * time.Second,
ReadTimeout: 2 * time.Second,
WriteTimeout: 2 * time.Second,
PoolTimeout: 3 * time.Second,
RouteByLatency: false, // 是否按延迟路由
RouteRandomly: false, // 是否随机路由
})

// 测试连接
err := rdc.ForEachShard(ctx, func(ctx context.Context, shard *redis.Client) error {
return shard.Ping(ctx).Err()
})
if err != nil {
panic(fmt.Sprintf("Cluster connection failed: %v", err))
}
fmt.Println("Redis Cluster connected")

// 写入数据(客户端自动路由到正确的分片)
err = rdc.Set(ctx, "cluster:key1", "value1", 0).Err()
if err != nil {
panic(err)
}
err = rdc.Set(ctx, "cluster:key2", "value2", 0).Err()
if err != nil {
panic(err)
}
err = rdc.Set(ctx, "cluster:key3", "value3", 0).Err()
if err != nil {
panic(err)
}

// 读取数据
val1, err := rdc.Get(ctx, "cluster:key1").Result()
if err != nil {
panic(err)
}
fmt.Println("key1:", val1)

val2, err := rdc.Get(ctx, "cluster:key2").Result()
if err != nil {
panic(err)
}
fmt.Println("key2:", val2)

// 哈希操作
err = rdc.HSet(ctx, "user:{1001}", map[string]interface{}{
"name": "张三",
"age": "28",
}).Err()
if err != nil {
panic(err)
}

name, err := rdc.HGet(ctx, "user:{1001}", "name").Result()
if err != nil {
panic(err)
}
fmt.Println("user name:", name)

// 使用 Hash Tag 确保相关 Key 路由到同一分片
err = rdc.Set(ctx, "{order:1001}:status", "paid", 0).Err()
if err != nil {
panic(err)
}
err = rdc.Set(ctx, "{order:1001}:amount", "99.00", 0).Err()
if err != nil {
panic(err)
}
err = rdc.Set(ctx, "{order:1001}:time", "2025-01-01 10:00:00", 0).Err()
if err != nil {
panic(err)
}

status, err := rdc.Get(ctx, "{order:1001}:status").Result()
if err != nil {
panic(err)
}
fmt.Println("order status:", status)

// Pipeline 操作(同一 Hash Tag 的 Key)
pipe := rdc.Pipeline()
pipe.Set(ctx, "{batch}:k1", "v1", 0)
pipe.Set(ctx, "{batch}:k2", "v2", 0)
pipe.Set(ctx, "{batch}:k3", "v3", 0)
pipe.Get(ctx, "{batch}:k1")
pipe.Get(ctx, "{batch}:k2")
pipe.Get(ctx, "{batch}:k3")
cmds, err := pipe.Exec(ctx)
if err != nil {
panic(err)
}
for _, cmd := range cmds {
fmt.Printf("pipeline: %v\\n", cmd)
}

// 关闭连接
rdc.Close()
}

自定义账号(ACL)连接示例

直连模式复用 Redis 原生 ACL 认证机制,使用自定义账号时需分别传入账号名与密码,不支持 用户名@密码 拼接格式。
package main

import (
"context"
"fmt"
"time"

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

func main() {
ctx := context.Background()

// ===== ACL 认证机制:账号名与密码是两个独立字段 =====
// 直连模式的多账号能力基于 Redis 原生 ACL:控制台创建的每个自定义账号
// 都是一个独立的 ACL user,认证时客户端向节点发送 AUTH <account> <password>。
// 因此需将 Username 与 Password 分别传入(等价于执行 AUTH account password),
// 不要写成代理模式的 "myuser@MyPassword" 拼接格式。
rdc := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{
"192.xx.xx.2:6379",
"192.xx.xx.3:6379",
"192.xx.xx.4:6379",
},
Username: "myuser", // ACL 账号名 → AUTH account
Password: "MyPassword", // 账号密码 → AUTH password(纯密码,无需拼接)
PoolSize: 200,
MinIdleConns: 50,
MaxRedirects: 3,
DialTimeout: 2 * time.Second,
ReadTimeout: 2 * time.Second,
WriteTimeout: 2 * time.Second,
})

err := rdc.Set(ctx, "key", "value", 0).Err()
if err != nil {
panic(err)
}

val, err := rdc.Get(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Println("get key:", val)

rdc.Close()
}

连接参数说明

参数
说明
推荐值
Addr
实例连接地址。代理模式为 VIP 地址,直连模式为分片节点地址
-
Password
认证密码
默认账号格式:实例 ID:密码
PoolSize
连接池大小(Cluster 模式下为每个节点的连接数)
200
MinIdleConns
最小空闲连接数
50
DialTimeout
连接超时
2 秒
ReadTimeout
读取超时
2 秒
WriteTimeout
写入超时
2 秒
PoolTimeout
连接池获取超时
3 秒
MaxRedirects
最大重定向次数(Cluster 模式)
3

常见问题

连接超时

确认客户端所在 CVM 与分布式缓存数据库实例在同一 VPC 内。
确认安全组规则已放通对应端口。
确认连接地址和端口正确。

认证失败

代理模式:默认账号使用 实例 ID:密码,自定义账号使用 用户名@密码。
直连模式:复用 Redis ACL 认证,默认账号仅传密码(AUTH password),自定义账号需分别传入账号名与密码(AUTH account password),不支持 用户名@密码 拼接格式。
确认密码中无特殊字符导致解析异常。

直连模式 MOVED 错误

确认使用 NewClusterClient 而非 NewClient。
确认已在控制台开启直连模式。
确认 Addrs 地址为分片节点地址而非 VIP 地址。

连接池耗尽

检查 PoolSize 是否设置合理。
确认 PoolTimeout 设置合理,避免长时间阻塞。
检查业务代码中是否有连接泄漏(未正确关闭)。