go-redis/cache

ring.go:320: ring shard state changed: Redis<:6379 db:10> is down

nicolasassi opened this issue · 4 comments

I'm having problems regarding connecting to redis on docker as seems in the title.

My go code stands as follows:

func NewRedis() (*Redis, error) {
	db, err := strconv.Atoi(os.Getenv("REDIS_DB"))
	if err != nil {
		return nil, fmt.Errorf("error connecting to redis %s:%s:%s: %v",
			os.Getenv("REDIS_ADDR"), os.Getenv("REDIS_PORT"), os.Getenv("REDIS_DB"), err)
	}
	options := redis.RingOptions{
		Addrs: map[string]string{
			os.Getenv("REDIS_ADDR"): fmt.Sprintf(":%s", os.Getenv("REDIS_PORT")),
		},
		DB: db,
	}
	ring := redis.NewRing(&options)
	return &Redis{cache: cache.New(&cache.Options{
		Redis:      ring,
		LocalCache: cache.NewTinyLFU(1000, time.Minute),
	})}, nil
}

my docker-compose responsible for redis:

version: '3.7'

networks:
  calliope:
    name: calliope
    driver: bridge

services:
  redis:
    container_name: redis-calliope
    image: redis:latest
    command: [ "redis-server", "--bind", "redis", "--port", "6379" ]
    ports:
      - 6379:6379
    networks:
      calliope:
        aliases:
          - redis

My docker-compose for the go service:

version: '3.7'

networks:
  calliope:
    name: calliope
    driver: bridge

services:
  calliope_text_analysis:
    container_name: calliope_text_analysis_local
    build:
      context: . # Use an image built from the specified dockerfile in the current directory.
      dockerfile: Dockerfile
      args:
        - ENV_FILE=env-local
    environment:
      GOOGLE_APPLICATION_CREDENTIALS: /tmp/keys/keyfile.json
    volumes:
      - ${GOOGLE_APPLICATION_CREDENTIALS}:/tmp/keys/keyfile.json:ro
    ports:
      - 8888:8888
    networks:
      - calliope

in addition to that, I'm able to connect normaly to redis when running my application out of docker connecting to redis inside the container. The problem only occurs when trying to connect when both sides are in containers

any idea about that? i met the same problem...

@bamstars ended up using redis instead of cache as I could not solve this problem...

@nicolasassi thank you for you kindly reply, i found this problem when deployed server app in a docker whatever deployed redis instance in either docker or local host. My current solution is using UniversalClient instead of Ring, it seems work well so far, code like below

// ring := redis.NewRing(&redis.RingOptions{
// Addrs: conf.AddrPort,
// Password: conf.Password,
// DB: conf.DB,
// })

rdb := redis.NewUniversalClient(&redis.UniversalOptions{
    Addrs:    conf.AddrPort,
    Password: conf.Password,
    DB:       conf.DB,
})

return cache.New(&cache.Options{
    Redis: rdb,
    LocalCache: cache.NewTinyLFU(
        conf.Size,
        time.Duration(conf.TtlInHours)*time.Hour),
})

Detail docs about UniversalClient and Cache can be found here
https://redis.uptrace.dev/guide/universal.html
https://redis.uptrace.dev/guide/caching.html