Redis 连不上先确认服务是否运行并监听 127.0.0.1,Go 客户端改用 "127.0.0.1:6379" 避免 IPv6 解析问题,设超时参数防卡死;调试优先选 go-redis/v9,注意 Set 过期时间单位为 time.Duration、避免 ctx 提前取消,并用 redis-cli monitor 和 context.Background() 快速定位问题。

redis.Dial() 连不上本地 Redis 怎么办
默认用 redis.Dial("tcp", "localhost:6379") 却报 dial tcp [::1]:6379: connect: connection refused,大概率是 Redis 没在跑,或者监听地址不对。
先确认 Redis 进程是否启动:redis-cli ping 返回 PONG 才算活;如果失败,Mac 用 brew services start redis,Linux 用 sudo systemctl start redis。
再检查 Redis 配置:打开 redis.conf,确认 bind 包含 127.0.0.1(不是只写 ::1),且 protected-mode no 在调试时可临时关闭(上线必须关回去)。
- Go 里别写
"localhost"—— DNS 解析可能走 IPv6,改用"127.0.0.1:6379" - 连接超时建议显式设:
redis.DialConnectTimeout(5 * time.Second) - 用
redis.DialReadTimeout和redis.DialWriteTimeout避免卡死
用 redigo 还是 go-redis?选哪个更省事
redigo 是老牌、轻量、函数式风格强;go-redis 功能全、API 面向对象、自动重连、支持哨兵和集群,但二进制体积略大。
立即学习“go语言免费学习笔记(深入)”;
调试阶段优先选 go-redis/redis/v9:它默认开启连接池、自带健康检查、错误信息更直白(比如 redis: nil 表示 key 不存在,redis: connection closed 才是真断连)。
- redigo 的
Do()要自己处理类型断言和 error,容易漏判redis.ErrNil - go-redis 的
Get(ctx, key).Result()返回(string, error),错误类型明确,适合快速验证逻辑 - 调试时加日志:用
redis.WithContext(context.WithValue(ctx, "trace_id", id))方便追踪请求链路
为什么 Set() 成功但 Get() 返回空?
最常见原因是 key 过期时间单位传错:go-redis 的 Set(ctx, key, val, 10) 中第三个参数是 time.Duration,传整数 10 是 10 纳秒,不是秒 —— 必须写 10 * time.Second。
另一个隐蔽点是上下文取消:如果 ctx 带了 timeout 或 deadline,且操作耗时超限,Get() 会直接返回 context.DeadlineExceeded,看起来像“没存进去”。
- 调试时统一用
context.Background(),排除 ctx 干扰 - 用
redis-cli monitor实时看命令是否真发到服务端 - 检查 key 是否被其他进程覆盖或误删 ——
EXISTS key和TTL key要一起查
调试时怎么看到真实 Redis 命令和响应
go-redis 不内置 wire log,但可以通过中间件或包装 Conn 实现。最简单的是启用 redigo 的 redis.DialReadTimeout + redis.DialWriteTimeout 后,配合 redis-cli --latency 观察延迟毛刺。
真正要抓原始命令,推荐在 client 初始化时加钩子:
opt := &redis.Options{
Addr: "127.0.0.1:6379",
// ...
}
client := redis.NewClient(opt)
client.AddQueryHook(&loggingHook{}) // 自定义结构体实现 Hook 接口
这个 loggingHook 只需实现 ProcessHook 方法,就能打印每条命令的 name、args、duration 和 error。
- 别依赖
fmt.Printf打印 redis.Conn.RawConn() —— 它是底层 net.Conn,读写是缓冲的,直接读会破坏协议 - redigo 的
Do()返回值第一个 interface{} 是响应体,类型取决于命令,redis.String(reply, err)才安全取字符串 - 线上禁用所有日志钩子,调试完记得删掉或用 build tag 控制
调试 Redis 最容易卡在“以为连上了,其实没连上”或者“以为存进去了,其实秒过期了”。把 redis-cli monitor 和 context.Background() 当成默认配置,比调半天连接参数更省时间。










