You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GKE中多微服务能否共享单个Redis服务?问题排查求助

问题分析与解决方案

看起来你遇到的问题是K8s集群中跨微服务访问Redis时,写入的数据无法被读取,但同服务内读写正常。我们一步步来排查和解决:

首先,确认写入操作是否真的成功

你在compute-service中的Set代码没有检查错误,有可能写入操作根本没成功。先修改代码加入错误校验:

rClient := redis.NewClient(&redis.Options{
    Addr:     "redis-service:6379",
    Password: "", // no password set
    DB:       0,  // use default DB
})
err := rClient.Set("trump", "value", 0).Err()
if err != nil {
    log.Printf("Failed to set key: %v", err)
    // 这里可以加入错误处理逻辑
}

如果运行后出现错误,那问题出在写入环节,我们再针对性排查。

检查K8s资源的核心配置问题

1. Namespace是否一致

K8s的Service是命名空间级别的,如果你的redis-service、compute-service、web-service不在同一个Namespace下,redis-service:6379这个地址是无法解析的。

你可以用以下命令查看所有资源的Namespace:

kubectl get pods,services -A

如果确实分属不同Namespace,需要把Addr修改为:

Addr: "redis-service.<redis-namespace>.svc.cluster.local:6379",

替换<redis-namespace>为Redis所在的命名空间名称。

2. Redis容器的绑定模式问题

默认的Redis镜像(包括你用的k8s.gcr.io/redis:e2e)开启了保护模式(protected-mode yes),并且默认绑定127.0.0.1。这会导致只有容器内部的请求能访问Redis,其他Pod的请求会被拒绝。

解决方法是修改Redis Deployment的配置,让Redis绑定所有地址或者关闭保护模式:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: redis-service
spec:
  selector:
    matchLabels:
      app: redis-service
      role: master
      tier: backend
  replicas: 1
  template:
    metadata:
      labels:
        app: redis-service
        role: master
        tier: backend
    spec:
      containers:
      - name: redis-service
        image: k8s.gcr.io/redis:e2e
        # 添加启动命令,关闭保护模式或绑定0.0.0.0
        command: ["redis-server", "--protected-mode", "no"]
        # 或者用这个命令绑定所有地址:command: ["redis-server", "--bind", "0.0.0.0"]
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379

修改后重新部署Redis:

kubectl apply -f your-redis-deployment.yaml

验证Redis实例中的数据

在修改配置后,我们可以直接进入Redis Pod查看数据是否真的被写入:

  1. 找到Redis Pod的名称:
kubectl get pods -l app=redis-service
  1. 进入Pod并执行redis-cli:
kubectl exec -it <redis-pod-name> -- redis-cli
  1. 执行GET trump,如果能返回"value",说明写入成功,问题出在web-service的读取环节;如果返回(nil),说明写入环节有问题,回到第一步检查错误。

最后检查web-service的读取逻辑

确保web-service中的Redis客户端配置和compute-service完全一致,比如Addr、Password、DB都没有拼写错误。另外,推荐在读取时也加入更详细的错误判断:

val, err := rClient.Get("trump").Result()
if err != nil {
    if errors.Is(err, redis.Nil) {
        log.Println("Key does not exist")
    } else {
        log.Printf("Failed to get key: %v", err)
    }
} else {
    log.Printf("Got value: %s", val)
}
fmt.Fprintf(w, "Print Error: %v \n", err)
fmt.Fprintf(w, "Print Value: %s \n", val)

内容的提问来源于stack exchange,提问作者MATT SHALLOW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:22:52