Search code examples
gokubernetesmicroservicesprometheus

Multiple replicas accessing a cache in kubernetes


One statistic for Prometheus logging is the duration of service calls but I want to measure the time over multiple calls of the same service.

So I figured to create a map of string to time.Time

type SomeService struct {
    durations map[string]time.Time
}

On first entry the current time is stored for that account id

durations[GetId()] = time.Now()

And then in the end…in another call…the total time is stored.

startTime := c.durations[id]
duration, _ := c.durationStat.GetMetricWith(prometheus.Labels{"type": duration})
duration.Set(time.Now().Sub(startTime).Seconds())
delete(c.durations, id)

This works when there is only one replica but it breaks down in a Kubernetes cluster right? The next call might come in on another endpoint? How do you cache values in microservices so that every replica can access them?


Solution

  • Finally found this:

    https://kubernetes.io/docs/concepts/services-networking/service

    You can configure the service to have the same ip address always go to the same pod by setting service.spec.sessionAffinity to “ClientIP” the default is “None”

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
    spec:
      sessionAffinity: ClientIP
      selector:
        app: MyApp
    

    This way you can safely cache simple values in memory!