28 KiB
28 KiB
Redis Services 连接指南
环境: juwan namespace
Redis 版本: 7.0.12
部署模式: RedisReplication + RedisSentinel
文档日期: 2026年2月22日
📋 目录
📊 Service 列表总览
当前集群中部署的 Redis 相关 Service:
| Service 名称 | 类型 | Cluster IP | 端口 | 用途 |
|---|---|---|---|---|
| user-redis | ClusterIP | 10.103.91.84 | 6379, 9121 | 通用访问 + 监控 |
| user-redis-additional | ClusterIP | 10.107.228.48 | 6379 | 额外访问入口 |
| user-redis-headless | ClusterIP(None) | None | 6379 | Pod 间直接访问 |
| user-redis-master ⭐ | ClusterIP | 10.97.120.76 | 6379 | 主节点访问 |
| user-redis-replica ⭐ | ClusterIP | 10.100.213.103 | 6379 | 从节点访问 |
| user-redis-sentinel-sentinel ⭐⭐⭐ | ClusterIP | 10.105.28.231 | 26379 | Sentinel 访问 |
| user-redis-sentinel-sentinel-additional | ClusterIP | 10.97.111.42 | 26379 | 额外 Sentinel 入口 |
| user-redis-sentinel-sentinel-headless | ClusterIP(None) | None | 26379 | Sentinel 间通信 |
图例:
- ⭐⭐⭐ 生产环境强烈推荐
- ⭐ 生产环境可用
- 无标记:特殊场景或内部使用
🔴 Redis 数据层 Service 详解
1. user-redis-master ⭐
基本信息
名称: user-redis-master
类型: ClusterIP
IP: 10.97.120.76
端口: 6379/TCP
DNS: user-redis-master.juwan.svc.cluster.local
功能特点
- 🎯 自动追踪当前 Redis 主节点
- ✅ 确保所有写操作到达主节点
- 🔄 故障转移后自动指向新主节点
- 💪 提供最强一致性保证
适用场景
- ✅ 所有写操作(SET, HSET, ZADD 等)
- ✅ 需要强一致性的读操作
- ✅ 事务操作(MULTI/EXEC)
- ❌ 不适合高并发读请求
连接示例
// Go - go-redis
rdb := redis.NewClient(&redis.Options{
Addr: "user-redis-master.juwan.svc.cluster.local:6379",
Password: os.Getenv("REDIS_PASSWORD"),
DB: 0,
})
// 写操作
err := rdb.Set(ctx, "user:1001", "John Doe", 0).Err()
# CLI 测试
kubectl run -it --rm redis-cli --image=redis:7.0.12 --restart=Never -n juwan -- \
redis-cli -h user-redis-master -a <password> SET test "hello"
2. user-redis-replica ⭐
基本信息
名称: user-redis-replica
类型: ClusterIP
IP: 10.100.213.103
端口: 6379/TCP
DNS: user-redis-replica.juwan.svc.cluster.local
功能特点
- 📖 负载均衡到所有从节点(当前 2 个)
- ⚡ 分散读请求,提升吞吐量
- 🕐 可能存在轻微的复制延迟(通常 < 100ms)
- 🚫 只读模式,写操作会失败
适用场景
- ✅ 高并发读请求
- ✅ 查询操作(GET, HGET, ZRANGE 等)
- ✅ 统计分析类查询
- ⚠️ 对数据实时性要求不高的场景
- ❌ 不能用于写操作
连接示例
// Go - 读写分离配置
masterClient := redis.NewClient(&redis.Options{
Addr: "user-redis-master.juwan.svc.cluster.local:6379",
Password: os.Getenv("REDIS_PASSWORD"),
})
replicaClient := redis.NewClient(&redis.Options{
Addr: "user-redis-replica.juwan.svc.cluster.local:6379",
Password: os.Getenv("REDIS_PASSWORD"),
ReadOnly: true,
})
// 写操作用 master
masterClient.Set(ctx, "counter", 100, 0)
// 读操作用 replica
val, err := replicaClient.Get(ctx, "counter").Result()
3. user-redis
基本信息
名称: user-redis
类型: ClusterIP
IP: 10.103.91.84
端口: 6379/TCP (Redis), 9121/TCP (Exporter)
DNS: user-redis.juwan.svc.cluster.local
功能特点
- 🔀 负载均衡到所有 Redis 节点(主 + 从)
- 📊 端口 9121 暴露 Prometheus 指标
- ⚠️ 写操作可能路由到从节点导致失败
适用场景
- ✅ Prometheus 监控抓取(端口 9121)
- ⚠️ 测试环境的简单访问
- ❌ 不推荐生产环境读写操作
监控配置
# Prometheus ServiceMonitor
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: redis-metrics
namespace: juwan
spec:
selector:
matchLabels:
app: redis
endpoints:
- port: redis-exporter
interval: 30s
path: /metrics
4. user-redis-additional
基本信息
名称: user-redis-additional
类型: ClusterIP
IP: 10.107.228.48
端口: 6379/TCP
功能特点
- 功能类似 user-redis
- 提供额外的访问入口
- 用于多租户或网络隔离场景
适用场景
- 特殊网络策略场景
- 多应用隔离访问
- 备用访问点
5. user-redis-headless
基本信息
名称: user-redis-headless
类型: ClusterIP (Headless - None)
端口: 6379/TCP
DNS:
- user-redis-0.user-redis-headless.juwan.svc.cluster.local
- user-redis-1.user-redis-headless.juwan.svc.cluster.local
- user-redis-2.user-redis-headless.juwan.svc.cluster.local
功能特点
- 🎯 直接返回所有 Pod IP,不做负载均衡
- 🔗 用于 StatefulSet Pod 间通信
- 📡 Redis 主从复制使用此服务发现
适用场景
- ✅ 内部复制通信
- ✅ 集群管理操作
- ✅ 需要直接访问特定 Pod
- ❌ 不适合应用层使用
直接访问示例
# 直接连接 user-redis-0
redis-cli -h user-redis-0.user-redis-headless.juwan.svc.cluster.local -a <password>
# DNS 解析会返回具体 Pod IP
nslookup user-redis-headless.juwan.svc.cluster.local
🟡 Sentinel 监控层 Service 详解
1. user-redis-sentinel-sentinel ⭐⭐⭐
基本信息
名称: user-redis-sentinel-sentinel
类型: ClusterIP
IP: 10.105.28.231
端口: 26379/TCP
DNS: user-redis-sentinel-sentinel.juwan.svc.cluster.local
功能特点
- 🛡️ 提供高可用 Redis 访问
- 🔄 自动发现主节点
- ⚡ 主节点故障时自动切换
- 📍 客户端自动跟踪主节点变化
Sentinel 架构
应用 → Sentinel Service → Sentinel 节点 (3个)
↓
监控 Redis 集群
↓
自动发现当前主节点位置
适用场景
- ✅✅✅ 生产环境强烈推荐
- ✅ 需要自动故障转移
- ✅ 高可用架构
- ✅ 无需手动处理主从切换
连接示例
// Go - go-redis Sentinel 模式
rdb := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: "mymaster",
SentinelAddrs: []string{
"user-redis-sentinel-sentinel.juwan.svc.cluster.local:26379",
},
Password: os.Getenv("REDIS_PASSWORD"),
DB: 0,
// 连接池配置
PoolSize: 10,
MinIdleConns: 5,
// 超时配置
DialTimeout: 5 * time.Second,
ReadTimeout: 3 * time.Second,
WriteTimeout: 3 * time.Second,
})
// 使用方式与普通客户端完全一致
err := rdb.Set(ctx, "key", "value", 0).Err()
val, err := rdb.Get(ctx, "key").Result()
# Python - redis-py Sentinel 模式
from redis.sentinel import Sentinel
sentinel = Sentinel([
('user-redis-sentinel-sentinel.juwan.svc.cluster.local', 26379)
], socket_timeout=0.5)
# 获取主节点(写)
master = sentinel.master_for('mymaster',
password=os.getenv('REDIS_PASSWORD'),
socket_timeout=0.5)
master.set('key', 'value')
# 获取从节点(读)
slave = sentinel.slave_for('mymaster',
password=os.getenv('REDIS_PASSWORD'),
socket_timeout=0.5)
value = slave.get('key')
# Spring Boot application.yml
spring:
redis:
sentinel:
master: mymaster
nodes:
- user-redis-sentinel-sentinel.juwan.svc.cluster.local:26379
password: ${REDIS_PASSWORD}
Sentinel 命令查询
# 查看主节点信息
kubectl exec -it user-redis-sentinel-sentinel-0 -n juwan -- \
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
# 查看所有监控的主节点
kubectl exec -it user-redis-sentinel-sentinel-0 -n juwan -- \
redis-cli -p 26379 SENTINEL masters
# 查看从节点列表
kubectl exec -it user-redis-sentinel-sentinel-0 -n juwan -- \
redis-cli -p 26379 SENTINEL slaves mymaster
# 查看 Sentinel 节点
kubectl exec -it user-redis-sentinel-sentinel-0 -n juwan -- \
redis-cli -p 26379 SENTINEL sentinels mymaster
2. user-redis-sentinel-sentinel-additional
基本信息
名称: user-redis-sentinel-sentinel-additional
类型: ClusterIP
IP: 10.97.111.42
端口: 26379/TCP
功能特点
- 功能同 user-redis-sentinel-sentinel
- 提供额外访问入口
- 用于多客户端分离
适用场景
- 多应用共享 Redis 时的访问隔离
- 网络策略要求
- 流量分离
3. user-redis-sentinel-sentinel-headless
基本信息
名称: user-redis-sentinel-sentinel-headless
类型: ClusterIP (Headless - None)
端口: 26379/TCP
功能特点
- Sentinel 节点间通信
- 选举和投票
- 状态同步
适用场景
- 内部使用,应用层无需关注
🔧 管理工具连接方式
使用 kubectl port-forward(推荐)
方式一:连接主节点
# 转发主节点服务到本地
kubectl port-forward -n juwan svc/user-redis-master 6379:6379
# 或直接转发到 Pod
kubectl port-forward -n juwan pod/user-redis-0 6379:6379
然后在管理工具中配置:
- Host: localhost
- Port: 6379
- Password: (见下方获取方法)
方式二:使用 LoadBalancer(生产不推荐)
# 临时暴露服务(仅用于调试)
apiVersion: v1
kind: Service
metadata:
name: redis-external
namespace: juwan
spec:
type: LoadBalancer
selector:
app: user-redis
ports:
- port: 6379
targetPort: 6379
获取 Redis 密码
# 方式一:直接输出
kubectl get secret user-redis -n juwan -o jsonpath='{.data.password}' | base64 -d
# 方式二:设置为环境变量
export REDIS_PASSWORD=$(kubectl get secret user-redis -n juwan -o jsonpath='{.data.password}' | base64 -d)
echo $REDIS_PASSWORD
# 方式三:保存到文件
kubectl get secret user-redis -n juwan -o jsonpath='{.data.password}' | base64 -d > redis-password.txt
常用管理工具配置
Redis Desktop Manager (RedisInsight)
Connection Name: juwan-user-redis
Host: localhost (使用 port-forward)
Port: 6379
Username: (留空)
Password: (从 Secret 获取)
redis-cli
# 在集群内访问
kubectl exec -it user-redis-0 -n juwan -- redis-cli -a <password>
# 从本地访问(需要 port-forward)
redis-cli -h localhost -p 6379 -a <password>
# 常用命令
INFO replication # 查看复制状态
INFO stats # 查看统计信息
CLUSTER INFO # 查看集群信息
KEYS * # 查看所有 key(生产谨慎使用)
💻 应用服务连接方式
方案一:Sentinel 模式(生产强烈推荐)⭐⭐⭐
优点
- ✅ 自动故障转移
- ✅ 高可用
- ✅ 无需手动切换
- ✅ 客户端自动重连
- ✅ 支持读写分离
Go-Zero 配置
配置文件 app/users/rpc/etc/pb.yaml
Name: pb.rpc
ListenOn: 0.0.0.0:9001
# Redis Sentinel 配置
Redis:
Type: sentinel
MasterName: mymaster
SentinelAddrs:
- user-redis-sentinel-sentinel.juwan.svc.cluster.local:26379
Pass: ${REDIS_PASSWORD} # 从环境变量读取
Etcd:
Hosts:
- etcd-service.juwan.svc.cluster.local:2379
Key: pb.rpc
Config 结构 app/users/rpc/internal/config/config.go
package config
import (
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/zrpc"
)
type Config struct {
zrpc.RpcServerConf
Redis redis.RedisConf
}
初始化 Redis app/users/rpc/internal/svc/serviceContext.go
package svc
import (
"github.com/zeromicro/go-zero/core/stores/redis"
"juwan-backend/app/users/rpc/internal/config"
)
type ServiceContext struct {
Config config.Config
Redis *redis.Redis
}
func NewServiceContext(c config.Config) *ServiceContext {
return &ServiceContext{
Config: c,
Redis: redis.MustNewRedis(c.Redis),
}
}
使用示例 app/users/rpc/internal/logic/getUsersByIdLogic.go
func (l *GetUsersByIdLogic) GetUsersById(in *pb.GetUsersByIdReq) (*pb.GetUsersByIdResp, error) {
// 尝试从缓存获取
cacheKey := fmt.Sprintf("user:%d", in.Id)
cached, err := l.svcCtx.Redis.Get(cacheKey)
if err == nil && cached != "" {
// 缓存命中
var user pb.User
json.Unmarshal([]byte(cached), &user)
return &pb.GetUsersByIdResp{User: &user}, nil
}
// 从数据库查询
user := l.fetchUserFromDB(in.Id)
// 写入缓存
userJSON, _ := json.Marshal(user)
l.svcCtx.Redis.Setex(cacheKey, string(userJSON), 3600) // 1小时过期
return &pb.GetUsersByIdResp{User: user}, nil
}
Go (原生 go-redis)
package main
import (
"context"
"github.com/redis/go-redis/v9"
"time"
)
func NewRedisClient() *redis.Client {
rdb := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: "mymaster",
SentinelAddrs: []string{
"user-redis-sentinel-sentinel.juwan.svc.cluster.local:26379",
},
Password: os.Getenv("REDIS_PASSWORD"),
DB: 0,
// 连接池配置
PoolSize: 10,
MinIdleConns: 5,
// 超时配置
DialTimeout: 5 * time.Second,
ReadTimeout: 3 * time.Second,
WriteTimeout: 3 * time.Second,
// 重试配置
MaxRetries: 3,
MinRetryBackoff: 8 * time.Millisecond,
MaxRetryBackoff: 512 * time.Millisecond,
})
// 测试连接
ctx := context.Background()
if err := rdb.Ping(ctx).Err(); err != nil {
panic(err)
}
return rdb
}
Python (redis-py)
from redis.sentinel import Sentinel
import os
# 初始化 Sentinel
sentinel = Sentinel([
('user-redis-sentinel-sentinel.juwan.svc.cluster.local', 26379)
], socket_timeout=5.0)
# 获取主节点连接(用于写操作)
master = sentinel.master_for(
'mymaster',
password=os.getenv('REDIS_PASSWORD'),
socket_timeout=3.0,
socket_connect_timeout=5.0,
socket_keepalive=True,
socket_keepalive_options={},
connection_pool_kwargs={
'max_connections': 50
}
)
# 获取从节点连接(用于读操作)
slave = sentinel.slave_for(
'mymaster',
password=os.getenv('REDIS_PASSWORD'),
socket_timeout=3.0
)
# 使用
master.set('key', 'value')
value = slave.get('key')
Java (Spring Data Redis)
# application.yml
spring:
redis:
timeout: 3000ms
password: ${REDIS_PASSWORD}
sentinel:
master: mymaster
nodes:
- user-redis-sentinel-sentinel.juwan.svc.cluster.local:26379
lettuce:
pool:
max-active: 10
max-idle: 5
min-idle: 2
max-wait: 3000ms
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(
RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}
方案二:主从分离模式 ⭐
优点
- ✅ 读写性能优化
- ✅ 配置清晰
- ⚠️ 需要手动处理故障
Go-Zero 配置
# app/users/rpc/etc/pb.yaml
Redis:
- Host: user-redis-master.juwan.svc.cluster.local:6379
Type: node
Pass: ${REDIS_PASSWORD}
- Host: user-redis-replica.juwan.svc.cluster.local:6379
Type: node
Pass: ${REDIS_PASSWORD}
代码示例
type ServiceContext struct {
Config config.Config
RedisMaster *redis.Redis // 写操作
RedisReplica *redis.Redis // 读操作
}
func NewServiceContext(c config.Config) *ServiceContext {
return &ServiceContext{
Config: c,
RedisMaster: redis.MustNewRedis(c.Redis[0]), // master
RedisReplica: redis.MustNewRedis(c.Redis[1]), // replica
}
}
// 写操作
l.svcCtx.RedisMaster.Set("key", "value")
// 读操作
val, _ := l.svcCtx.RedisReplica.Get("key")
方案三:简单模式(仅测试环境)
Redis:
Host: user-redis-master.juwan.svc.cluster.local:6379
Type: node
Pass: ${REDIS_PASSWORD}
Kubernetes Deployment 配置
# deploy/k8s/service/user/user-rpc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-rpc
namespace: juwan
spec:
template:
spec:
containers:
- name: user-rpc
image: user-rpc:v1
env:
# 数据库连接
- name: DB_URI
valueFrom:
secretKeyRef:
name: user-db-app
key: uri
# Redis 密码
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: user-redis
key: password
# 健康检查
readinessProbe:
tcpSocket:
port: 9001
initialDelaySeconds: 10
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 9001
initialDelaySeconds: 15
periodSeconds: 20
📊 连接方式对比
| 连接方式 | 优点 | 缺点 | 故障转移 | 读写分离 | 复杂度 | 推荐度 |
|---|---|---|---|---|---|---|
| Sentinel 模式 | 自动高可用,客户端自动切换 | 配置稍复杂 | ✅ 自动 | ✅ 支持 | 中 | ⭐⭐⭐⭐⭐ |
| 主从分离 | 性能优化,逻辑清晰 | 需手动处理故障 | ❌ 手动 | ✅ 支持 | 中 | ⭐⭐⭐ |
| 仅连 Master | 配置简单,强一致性 | 单点故障,读性能差 | ❌ 手动 | ❌ 不支持 | 低 | ⭐⭐ |
| 仅连 Replica | 读性能好 | 只读,不能写入 | ❌ 手动 | ✅ 仅读 | 低 | ⭐ |
| 连 user-redis | 极简单 | 性能差,不可靠 | ❌ 无 | ❌ 不支持 | 低 | ❌ |
🎯 最佳实践建议
生产环境(强烈推荐)
# 使用 Sentinel 模式
Redis:
Type: sentinel
MasterName: mymaster
SentinelAddrs:
- user-redis-sentinel-sentinel.juwan.svc.cluster.local:26379
Pass: ${REDIS_PASSWORD}
# 连接池配置
PoolSize: 10
MinIdleConns: 5
# 超时配置
DialTimeout: 5s
ReadTimeout: 3s
WriteTimeout: 3s
# 重试配置
MaxRetries: 3
理由
- ✅ 自动故障转移,RTO < 30秒
- ✅ 客户端无感知切换
- ✅ 无需人工介入
- ✅ 久经考验的成熟方案
开发/测试环境
# 简化配置,直连主节点
Redis:
Host: user-redis-master.juwan.svc.cluster.local:6379
Type: node
Pass: ${REDIS_PASSWORD}
或使用 port-forward:
kubectl port-forward -n juwan svc/user-redis-master 6379:6379
性能优化建议
1. 连接池配置
PoolSize: runtime.NumCPU() * 2, // CPU 数量的 2 倍
MinIdleConns: runtime.NumCPU(), // CPU 数量
MaxConnAge: 30 * time.Minute, // 连接最大存活时间
2. 超时配置
DialTimeout: 5 * time.Second, // 连接超时
ReadTimeout: 3 * time.Second, // 读超时
WriteTimeout: 3 * time.Second, // 写超时
PoolTimeout: 4 * time.Second, // 获取连接超时
3. 命令优化
// ❌ 避免:循环中多次调用
for i := 0; i < 1000; i++ {
rdb.Set(ctx, fmt.Sprintf("key:%d", i), i)
}
// ✅ 推荐:使用 Pipeline
pipe := rdb.Pipeline()
for i := 0; i < 1000; i++ {
pipe.Set(ctx, fmt.Sprintf("key:%d", i), i, 0)
}
pipe.Exec(ctx)
4. 缓存策略
// Cache-Aside Pattern
func GetUser(id int64) (*User, error) {
// 1. 先查缓存
cacheKey := fmt.Sprintf("user:%d", id)
cached, err := rdb.Get(ctx, cacheKey).Result()
if err == nil {
var user User
json.Unmarshal([]byte(cached), &user)
return &user, nil
}
// 2. 缓存未命中,查数据库
user := queryFromDB(id)
// 3. 写入缓存
userJSON, _ := json.Marshal(user)
rdb.Set(ctx, cacheKey, userJSON, 1*time.Hour)
return user, nil
}
监控配置
Prometheus 指标采集
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: redis-exporter
namespace: juwan
spec:
selector:
matchLabels:
app: user-redis
endpoints:
- port: redis-exporter # 端口 9121
interval: 30s
path: /metrics
关键指标监控
# 告警规则示例
groups:
- name: redis
rules:
# Redis 实例宕机
- alert: RedisDown
expr: redis_up == 0
for: 1m
annotations:
summary: "Redis instance down"
# 内存使用率过高
- alert: RedisMemoryHigh
expr: redis_memory_used_bytes / redis_memory_max_bytes > 0.9
for: 5m
annotations:
summary: "Redis memory usage > 90%"
# 连接数过高
- alert: RedisConnectionsHigh
expr: redis_connected_clients > 1000
for: 5m
annotations:
summary: "Redis connections > 1000"
安全建议
1. 密码管理
# 定期轮换密码
kubectl create secret generic user-redis \
--from-literal=password=$(openssl rand -base64 32) \
--dry-run=client -o yaml | kubectl apply -f -
# 重启 Redis Pods 使新密码生效
kubectl rollout restart statefulset/user-redis -n juwan
2. 网络策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: redis-access
namespace: juwan
spec:
podSelector:
matchLabels:
app: user-redis
policyTypes:
- Ingress
ingress:
# 只允许同命名空间的 user-rpc 访问
- from:
- podSelector:
matchLabels:
app: user-rpc
ports:
- protocol: TCP
port: 6379
3. TLS 加密(可选)
# Redis TLS 配置
apiVersion: redis.redis.opstreelabs.in/v1beta2
kind: RedisReplication
metadata:
name: user-redis
spec:
TLS:
enabled: true
secret:
secretName: redis-tls-cert
🔍 故障排查
1. 连接失败
症状
Error: dial tcp 10.97.120.76:6379: i/o timeout
排查步骤
# 1. 检查 Service 是否存在
kubectl get svc user-redis-master -n juwan
# 2. 检查 Endpoints
kubectl get endpoints user-redis-master -n juwan
# 3. 检查 Pod 状态
kubectl get pods -l app=user-redis -n juwan
# 4. 测试网络连通性
kubectl run -it --rm netshoot --image=nicolaka/netshoot --restart=Never -n juwan -- \
nc -zv user-redis-master 6379
# 5. 查看 Pod 日志
kubectl logs user-redis-0 -n juwan -c redis
2. 认证失败
症状
Error: NOAUTH Authentication required
解决方法
# 1. 确认 Secret 存在
kubectl get secret user-redis -n juwan
# 2. 验证密码
PASSWORD=$(kubectl get secret user-redis -n juwan -o jsonpath='{.data.password}' | base64 -d)
echo $PASSWORD
# 3. 测试连接
kubectl exec -it user-redis-0 -n juwan -- redis-cli -a $PASSWORD PING
3. 主从复制异常
症状
Warning: Redis replica lag is high
排查
# 在主节点执行
kubectl exec -it user-redis-0 -n juwan -- redis-cli -a <password> INFO replication
# 查看输出
# role:master
# connected_slaves:2
# slave0:ip=10.244.1.10,port=6379,state=online,offset=1234,lag=0
# slave1:ip=10.244.2.15,port=6379,state=online,offset=1234,lag=0
如果 lag 过大
# 检查网络延迟
kubectl exec -it user-redis-0 -n juwan -- ping user-redis-1
# 检查 Redis 性能
kubectl exec -it user-redis-0 -n juwan -- redis-cli -a <password> INFO stats
4. Sentinel 无法发现主节点
症状
Error: sentinel: no master found
排查
# 1. 检查 Sentinel 状态
kubectl exec -it user-redis-sentinel-sentinel-0 -n juwan -- \
redis-cli -p 26379 SENTINEL masters
# 2. 检查主节点地址
kubectl exec -it user-redis-sentinel-sentinel-0 -n juwan -- \
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
# 3. 查看 Sentinel 日志
kubectl logs user-redis-sentinel-sentinel-0 -n juwan
# 4. 手动触发故障转移(慎用)
kubectl exec -it user-redis-sentinel-sentinel-0 -n juwan -- \
redis-cli -p 26379 SENTINEL failover mymaster
5. 性能问题
慢查询分析
# 查看慢查询
kubectl exec -it user-redis-0 -n juwan -- \
redis-cli -a <password> SLOWLOG GET 10
# 设置慢查询阈值(10ms)
kubectl exec -it user-redis-0 -n juwan -- \
redis-cli -a <password> CONFIG SET slowlog-log-slower-than 10000
命令统计
# 查看命令统计
kubectl exec -it user-redis-0 -n juwan -- \
redis-cli -a <password> INFO commandstats
内存分析
# 查看内存使用
kubectl exec -it user-redis-0 -n juwan -- \
redis-cli -a <password> INFO memory
# 查看大 key
kubectl exec -it user-redis-0 -n juwan -- \
redis-cli -a <password> --bigkeys
📚 参考资源
官方文档
客户端库
- Go: github.com/redis/go-redis/v9
- Python: redis-py
- Java: Spring Data Redis
- Node.js: ioredis
监控工具
- RedisInsight
- Redis Exporter
- Grafana Dashboard: Redis Dashboard 11835
📝 更新日志
| 日期 | 版本 | 变更内容 |
|---|---|---|
| 2026-02-22 | 1.0 | 初始版本,包含完整的 Service 介绍和连接指南 |
文档维护者: DevOps Team
最后更新: 2026年2月22日
下一次审查: 2026年3月22日