Redis: EOF erorrs from client

Created on 23 Aug 2018  路  5Comments  路  Source: go-redis/redis

Hi, guys!

I faced with the fully similar issue with this topic but in my case I'm not using a timeout option on the server (using a default zero value - that mean the server doesn't close a idle connections), and client using a default 5 min timeout. But some times (probably every 20-30 sec) in prod env client returns a EOF error. As I understood EOF appears in case when server has closed a connection, but client is still not OR when connection was closed by network devices between the client and server.
I've tried to set MaxRetries = 2, ReadTimeout = 15 sec but it was not helpful.

So, my questions is:

  • is it safety to store redis client in global variable and simultaneously use it in different request handles? Could it leads to overflow a pool? What would happen then? e.g.
var cacheProviderInstance CacheProvider
var cacheProviderInstanceOnce sync.Once

func GetCacheProvider() CacheProvider {
         cacheProviderInstanceOnce.Do(func() {
        cacheProviderInstance, _ = newRedisClient()
    })
        return cacheProviderInstance
}

func newRedisClient() (*redis.Client, error) {
    client := redis.NewClient(&redis.Options{
        Addr:       redisHost,
        Password:   edisPassword,
        DB:         redisDB,
        MaxRetries: 2,
    })

    if _, err := client.Ping().Result(); err != nil {
        client.Close() // is in necessary? could it leads to increasing of memory usage?
        return nil, err
    }
    return client, nil
}
  • what is the reasons of EOF error could be?
  • what is the suggested way to re-connect and to avoid fails for the initial request?

Thanks,
Mike

Most helpful comment

were you able to solve that?

https://github.com/levpay/surl/pull/3/files

All 5 comments

Make sure you are using latest version. Especially v6.13 has KeepAlive enabled by default. Perhaps you need to tweak keep-alive on Go/OS level. Also check following options:

  • CONFIG GET timeout
  • Options.IdleTimeout and Options.IdleCheckTimeout
  • Options.MaxRetries

But overall I would start with trying to isolate & reproduce this problem using small app. EOF every 30 seconds suggests you are doing something very wrong or network is very unreliable. I wonder what is the latency of PING command?

is it safety to store redis client in global variable and simultaneously use it in different request handles?

Yes, that is what you expected to do - create one instance and use it for the app lifetime.

Could it leads to overflow a pool? What would happen then? e.g.

When there are no connections in the pool app will wait for a free connection and return timeout after Options.PoolTimeout.

client.Close() // is in necessary? could it leads to increasing of memory usage?

Client is unusable after Close - you will get client is closed errors afterwards.

what is the suggested way to re-connect and to avoid fails for the initial request?

It should happen automatically - you don't need to handle it.

EOF sample

tool used: https://github.com/pedrolopesme/call-it
code used: https://github.com/levpay/surl
redis: github.com/go-redis/redis v6.15.1

eof

were you able to solve that?

were you able to solve that?

https://github.com/levpay/surl/pull/3/files

The following information might be useful for ones who use Redis HA by Google Click to Deploy (Redis over HAProxy)

    IdleTimeout:        time.Second * 25,
    IdleCheckFrequency: time.Second * 5,
Was this page helpful?
0 / 5 - 0 ratings

Related issues

chenweiyj picture chenweiyj  路  3Comments

mollylogue picture mollylogue  路  4Comments

zhangruiskyline picture zhangruiskyline  路  4Comments

zhangruiskyline picture zhangruiskyline  路  7Comments

patrickwhite256 picture patrickwhite256  路  7Comments