在Python中使用Redis连接池的正确方法 [英] Correct Way of using Redis Connection Pool in Python

查看:2592
本文介绍了在Python中使用Redis连接池的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两个不同的模块 foo.py bar.py 应该如何从Redis连接池中获得连接?换句话说,我们应该如何构建应用程序?

How should two different modules foo.py and bar.py get a connection from a Redis connection pool? In other words, how should we structure the app?

我相信目标是只有一个连接池,所有模块都可以从中获得连接。

I believe the goal is to have just a single connection pool for all modules to get a connection from.

第一季度:在我的示例中,两个模块是否都从同一连接池获得连接?

Q1: In my example, does both modules get a connection from the same connection pool?

第二季度:是否可以在 RedisClient.py 中创建RedisClient实例,然后将该实例导入其他2个模块中?还是有更好的方法?

Q2: Is it Ok to create the RedisClient instance in RedisClient.py, then import the instance into the other 2 modules? Or is there a better way?

第三季度: conn 的延迟加载吗?实例变量实际上有用吗?

Q3: Is lazy loading of the conn instance variable actually useful?

RedisClient.py

import redis

class RedisClient(object):

    def __init__(self):
        self.pool = redis.ConnectionPool(host = HOST, port = PORT, password = PASSWORD)

    @property
    def conn(self):
        if not hasattr(self, '_conn'):
            self.getConnection()
        return self._conn

    def getConnection(self):
        self._conn = redis.Redis(connection_pool = self.pool)

redisClient = RedisClient()

foo.py

from RedisClient import redisClient

species = 'lion'
key = 'zoo:{0}'.format(species)
data = redisClient.conn.hmget(key, 'age', 'weight')
print(data)

bar.py

from RedisClient import redisClient

print(redisClient.conn.ping())






还是更好?


Or is this better?

RedisClient.py

import redis

class RedisClient(object):

    def __init__(self):
        self.pool = redis.ConnectionPool(host = HOST, port = PORT, password = PASSWORD)

    def getConnection(self):
        return redis.Redis(connection_pool = self.pool)

redisClient = RedisClient()

foo.py

from RedisClient import redisClient

species = 'lion'
key = 'zoo:{0}'.format(species)
data = redisClient.getConnection().hmget(key, 'age', 'weight')
print(data)

bar.py

from RedisClient import redisClient

print(redisClient.getConnection().ping())


推荐答案

A1:是的,他们使用相同的连接池。

A1: Yes, they use the same connection pool.

A2:这不是一个好习惯。由于您无法控制此实例的初始化。

A2: This isn't a good practice. As you cannot control the initialization of this instance. An alternative could be use singleton.

import redis


class Singleton(type):
    """
    An metaclass for singleton purpose. Every singleton class should inherit from this class by 'metaclass=Singleton'.
    """
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class RedisClient(object):

    def __init__(self):
        self.pool = redis.ConnectionPool(host = HOST, port = PORT, password = PASSWORD)

    @property
    def conn(self):
        if not hasattr(self, '_conn'):
            self.getConnection()
        return self._conn

    def getConnection(self):
        self._conn = redis.Redis(connection_pool = self.pool)

然后 RedisClient 将是一个单例类。不管您调用 client = RedisClient()多少次,您都会得到相同的对象。

Then RedisClient will be a singleton class. Not matter how many times you call client = RedisClient(), you will get the same object.

所以您可以像这样使用它:

So you can use it like:

from RedisClient import RedisClient

client = RedisClient()
species = 'lion'
key = 'zoo:{0}'.format(species)
data = client.conn.hmget(key, 'age', 'weight')
print(data)

第一次调用 client = RedisClient()实际上将初始化该实例。

And the first time you call client = RedisClient() will actually initialize this instance.

或者您可能希望根据不同的参数获取不同的实例:

Or you may want to get different instance based on different arguments:

class Singleton(type):
    """
    An metaclass for singleton purpose. Every singleton class should inherit from this class by 'metaclass=Singleton'.
    """
    _instances = {}

    def __call__(cls, *args, **kwargs):
        key = (args, tuple(sorted(kwargs.items())))
        if cls not in cls._instances:
            cls._instances[cls] = {}
        if key not in cls._instances[cls]:
            cls._instances[cls][key] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls][key]

这篇关于在Python中使用Redis连接池的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆