简体   繁体   English

在Python中管理redis连接

[英]Managing redis connections in Python

I have gone through multiple questions on this topic and I'm still confused.I'm trying to find the optimal way to share a database connection between multiple Python modules. 我已经就这个主题经历了多个问题,我仍然感到困惑。我正在努力寻找在多个Python模块之间共享数据库连接的最佳方式。 I have seen the Borg pattern as well but can't see how it would be useful when we need to share a database connection. 我也看过Borg模式,但是当我们需要共享数据库连接时,它看不出它是如何有用的。

Here's what I have : I'm using Redis as my database and would like to share a redis connection between multiple modules. 这就是我所拥有的:我使用Redis作为我的数据库,并希望在多个模块之间共享redis连接。

Option 1: As suggested by Jared below, I could just create a redis connection and pass it everywhere. 选项1:正如下面的Jared所建议的那样,我可以创建一个redis连接并将其传递到任何地方。

class Crawler:
    def __init__(self, url_store):
        self._url_store = url_store


class UrlStore:
    def __init__(self, redis_client):
        self._redis_client = redis_client


if __name__ == '__main__':
    redis_client = redis.StrictRedis(host='localhost',
                                     port=6379,
                                     db=0,
                                     decode_responses=True)

    url_store = UrlStore(redis_client)
    c = Crawler(url_store)

Option 2: Wrap the redis connection in a class. 选项2:将redis连接包装在一个类中。

  class RedisConnection:
    client = redis.StrictRedis(host='localhost',
                               port=6379,
                               db=0,
                               decode_responses=True)


class Crawler:
    def __init__(self, url_store):
        self._url_store = url_store


class UrlStore:
    def __init__(self):
        self._redis_client = RedisConnection.client


if __name__ == '__main__':

    url_store = UrlStore()
    c = Crawler(url_store)

With Option 1, there's no need to worry about singleton etc , but I think we are leaking the database information everywhere. 使用选项1,不需要担心单例等,但我认为我们正在泄漏数据库信息。

Option 2 just doesn't feel elegant. 选项2只是感觉不优雅。

I think there is a bigger design question here ..which is ..should a database connection be "injected" wherever its needed ...or ..should it be accessed from a global/singleton/ shared state as needed ? 我认为这里有一个更大的设计问题..这应该是一个数据库连接被“注入”在需要的地方......或者......应该根据需要从全局/单例/共享状态访问它?

Just an Idea, Create a database instance pool. 只是一个想法,创建一个数据库实例池。 Say three/five. 说三/五。 And have a dbPool dictionary 并有一个dbPool字典

     dbPool = {client _inst1 = 0, client _inst2 = 0, client _inst3 = 0}

key -> db instance, value -> 0/1 (0- dbconn free, 1 dbconn inuse) key - > db instance,value - > 0/1(0-dbconn free,1 dbconn inuse)

And Whenever you needs a instance have a small thread safe fn: 并且每当你需要一个实例时都有一个小的线程安全fn:

def getThreadSafeConnection(self) :
    for dbConn, value in self.dbPool.items() :
        if value == 0 :
            self.lock() # lock
            self.dbPool[dbConn] = 1 # db cursor in use 
            self.unlock()
            return dbConn
    return createNewConn() // if no dbConn is free

Once your query executed reset the dbInstance Flag 执行查询后重置dbInstance标志

            self.lock()
            self.dbPool[dbConn] = 0 # db cursor is free
            self.unlock()

This will ensures proper query execution. 这将确保正确的查询执行。 If you feel more db hit may occur, then increase your dbPool size. 如果您觉得可能发生更多数据包命中,则增加dbPool大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM