4

I am using aredis to handle the connection pool. Following is how I instantiate redis connections in the main function -

redis_conn = await asyncio.ensure_future(get_redis_conn(redis_host,       loop))

Following is the co-routine definition -

async def get_redis_conn(host, loop):
    return StrictRedisCluster(startup_nodes=host, decode_responses=True, loop=loop, max_connections=96)

I am using sanic to run the web server. This is how I instantiate that -

app.run(host='0.0.0.0', port=port, after_start=after_start, workers=32)

Is my implementation wrong in some way? I can't figure out how redis reuses these connections?

John Moutafis
  • 22,254
  • 11
  • 68
  • 112
Sagar Grover
  • 65
  • 1
  • 9

3 Answers3

1

Since redis-cluster allows 10000 - 32 open connections to be made for each cluster. Now if you have 10 servers than each server cannot make more than 1000 open connection. So the issue probably for your case will be, for each server if you are having 50 workers, then the number of max connections in redis initialisation should not be more than 20. Try reducing this max connections per worker as it worked out perfectly for me.

Eg:
StrictRedisCluster(startup_nodes=host, decode_responses=True, loop=loop, max_connections=35)

So you need to reduce this max_connections limit per worker.

1

Use connection pool and increase the number of connections code

import redis

redis_pool = redis.ConnectionPool(host='127.0.0.1', port=6379, db=0)
conn = redis.Redis(connection_pool=redis_pool, max_connections=2 * 31)

http://www.chenxm.cc/article/1234.html

xin.chen
  • 964
  • 2
  • 8
  • 24
0

Although it is a bit hard to debug the issue without access to your code, what seems wrong to mee is the cluster connection initialization that you are using.

I will make a guess and say that your "main" method is used more times than 96 and that leads to the exception you are getting.

Try to establish your cluster connection only once for the entire app and pass it around with your app:

from sanic import Sanic 
from aredis import StrictRedisCluster    


app = Sanic(__name__)

@app.listener('before_server_start')
def init(app, loop):
    app.redis_conn = StrictRedisCluster(
        startup_nodes=HOST, decode_responses=True, loop=loop, max_connections=96
    )

@app.route("/")
async def test(request):
    return json.loads(await app.redis_conn.get(cache_key))


app.run(host='0.0.0.0', port=port, after_start=after_start, workers=32)


Essentially this is similar to my suggested solution here: How to use an aiohttp ClientSession with Sanic?
John Moutafis
  • 22,254
  • 11
  • 68
  • 112