问题来源

最近项目中用到tornado + mongodb + redis,之前写爬虫的时候用到过redis-py感觉简单容易上手,结合tornado使用就出现了连接池中连接失效重连耗时太久的问题。

代码例子如下:

import time

import redis

redis_setting = dict(

    host='127.0.0.1',

)

db = redis.Redis(connection_pool=redis.ConnectionPool(**redis_setting))

def do_with_redis():

    now = time.time()

    db.get('a')

    print(time.time() - now)

def do_something():

    do_with_redis()  # 第一次查询

    time.sleep(301)  # do something other,一些业务逻辑

    do_with_redis()  # 第二次查询

do_something()


得到的结果是:

第一次查询耗时0.018s左右

第二次查询耗时20.018s左右

查看了官方文档说redis连接默认20s超时,关键代码是client.py中669行。

当连接池中的socket已经失效,等待20s s.recv()没有响应,就会抛出异常走到671行,重连继续运行。

解决方案1(不完全)

把连接超时时间缩短,然后超时后断开重连

redis_setting = dict(

    host='127.0.0.1',

    socket_timeout=1,

    socket_connect_timeout=1,

    retry_on_timeout=True

)

但是这样还是需要忍受1s的时间

解决方案2(推荐)

让socket连接保持心跳,维持连接状态。找了一堆的socket资料,再读一遍源代码,终于发现还能这样用。

redis_setting = dict(

    host='127.0.0.1',

    socket_keepalive=True,

    socket_keepalive_options={socket.TCP_KEEPIDLE: 60, socket.TCP_KEEPINTVL: 30, socket.TCP_KEEPCNT: 3}

)

————————————————

版权声明:本文为CSDN博主「cau_eshao」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/dslkfajoaijfdoj/article/details/83692668