Redis Python客户端打开许多连接

2024-10-04 05:29:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用下面的代码来连接Redis服务器。 我看到大量的连接处于等待状态。怎么了?在

root@ubuntu:~$ netstat | grep :6479 | grep TIME_WAIT |wc -l
9061
root@ubuntu:~$ netstat | grep :6479 | grep ESTABLISHED |wc -l
7

我想用下面的代码在Redis服务器完成操作后关闭连接。但我发现了这个错误。

^{pr2}$

我得到了下面的错误

r_server.connection.disconnect()
AttributeError: 'Redis' object has no attribute 'connection'

对Redis操作完成后等待连接/关闭连接的巨大时间有什么想法? 代码:

import threading
from time import sleep
import time, datetime
import traceback
import CACHE_CONST
import json
import os

import MySQLdb
import redis

# Static methods to interact with the Redis cache server
class CacheUtil(object):

    # Log Errors
    @staticmethod
    def log_message(msg):
        log_file = None
        log_file = open (os.path.abspath(CACHE_CONST.REDIS_LOG_FILE), "a")
        print(msg)
        if (log_file):
            message = time.strftime("%d-%m-%Y %H:%M:%S")    
            message += " :: " + str(msg)
            log_file.write(message + "\n")

    @staticmethod
    def saveToCache(hashName, hashValue):
        r_server = CacheUtil.getRedisConnection()
        r_server.hmset(hashName, hashValue)
        CacheUtil.disconnectRedisConnection(r_server)

    @staticmethod
    def getTrackerDetailsByID(trackerId):
        trackerDetail = None
        r_server = None
        hashName = "tDetails:" + str(trackerId)
        try:
            if trackerId is not None:
                print("getTrackerDetailsByID ")
                r_server = CacheUtil.getRedisConnection()
                trackerDetail = r_server.hgetall(hashName)
            else:
                CacheUtil.log_message("getDetailsByID failed with empty trackerId ")
        except:
            CacheUtil.log_message("getDetailsByID failed, ll fetch from DB " + str(traceback.format_exc()))
        finally:
            CacheUtil.disconnectRedisConnection(r_server)
        return trackerDetail

    @staticmethod
    def getRedisConnection():
        print("Get Redis Connection on Util ")
        r_server = redis.Redis(host=CACHE_CONST.REDIS_SERVER_URL, port=CACHE_CONST.REDIS_SERVER_PORT, db=0, password=CACHE_CONST.REDIS_PASS_PHRASE, socket_connect_timeout=2, socket_timeout=2)
        return r_server;

    @staticmethod
    def disconnectRedisConnection(r_server):
        if r_server is not None and r_server:
            r_server.connection.disconnect()

Tags: importredisnonelogcachemessageserverdef
1条回答
网友
1楼 · 发布于 2024-10-04 05:29:18

实际上,当您调用redis.Redis()时,它将为您创建“client”,它有一个连接池,而不仅仅是一个连接。在

每次你发出命令redis.set公司()或其他方法,它将从其连接池中检索连接,并使用此连接发送此命令并等待答复。当请求完成后,它将连接放回连接池以供重用。所以您不需要自己管理连接。查看此https://github.com/andymccurdy/redis-py了解更多信息。在

就像这样:

import threading
from time import sleep
import time, datetime
import traceback
import CACHE_CONST
import json
import os

import MySQLdb
import redis
r_server = redis.Redis(host=CACHE_CONST.REDIS_SERVER_URL, port=CACHE_CONST.REDIS_SERVER_PORT, db=0, password=CACHE_CONST.REDIS_PASS_PHRASE, socket_connect_timeout=2, socket_timeout=2)

# Static methods to interact with the Redis cache server
class CacheUtil(object):

    # Log Errors
    @staticmethod
    def log_message(msg):
        log_file = None
        log_file = open (os.path.abspath(CACHE_CONST.REDIS_LOG_FILE), "a")
        print(msg)
        if (log_file):
            message = time.strftime("%d-%m-%Y %H:%M:%S")    
            message += " :: " + str(msg)
            log_file.write(message + "\n")

    @staticmethod
    def saveToCache(hashName, hashValue):
        r_server.hmset(hashName, hashValue)

    @staticmethod
    def getTrackerDetailsByID(trackerId):
        hashName = "tDetails:" + str(trackerId)
        try:
            if trackerId is not None:
                print("getTrackerDetailsByID ")
                trackerDetail = r_server.hgetall(hashName)
            else:
                CacheUtil.log_message("getDetailsByID failed with empty trackerId ")
        except:
            CacheUtil.log_message("getDetailsByID failed, ll fetch from DB " + str(traceback.format_exc()))
        return trackerDetail

更新

每次使用redis instance send命令时,都会调用此方法:

^{pr2}$

使用Redis完成操作后,您对长时间等待连接/关闭连接有何想法

enter image description here

这是关于TCP连接终止过程的图像。当客户端(发起方)发送服务器(接收方)的ACK时,它进入Time_WAIT状态。在

引自TCP/IP的文字说明第1卷:

When TCP performs an active close and sends the final ACK, that connection must stay in the TIME_WAIT state for twice the MSL. This lets TCP resend the final ACK in case it is lost. The final ACK is resent not because the TCP retransmits ACKs (they do not consume sequence numbers and are not retransmitted by TCP), but because the other side will retransmit its FIN (which does consume a sequence number). Indeed, TCP will always retransmit FINs until it receives a final ACK.

因此,它将处于TIME_WAIT状态四分钟,之后,它将自动关闭连接。由于您频繁地打开和关闭新的tcp连接,因此许多已关闭的连接将处于TIME_WAIT状态。在

还有一篇关于the purpose about TIME_WAIT的更详细的文章

相关问题 更多 >