python redis之连接池的原理
2021-01-26 07:13
标签:end 目的 instance osi cep 大连 sel move options 通常情况下, 当我们需要做redis操作时, 会创建一个连接, 并基于这个连接进行redis操作, 操作完成后, 释放连接, 一般情况下, 这是没问题的, 但当并发量比较高的时候, 频繁的连接创建和释放对性能会有较高的影响 于是, 连接池就发挥作用了 连接池的原理是, 通过预先创建多个连接, 当进行redis操作时, 直接获取已经创建的连接进行操作, 而且操作完成后, 不会释放, 用于后续的其他redis操作 这样就达到了避免频繁的redis连接创建和释放的目的, 从而提高性能了 那么, 在redis-py中, 他是怎么进行连接池管理的呢 首先看下如何进行连接池操作的 当redis.ConnectionPool 实例化的时候, 做了什么 这个连接池的实例化其实未做任何真实的redis连接, 仅仅是设置最大连接数, 连接参数和连接类 StrictRedis 实例化的时候, 又做了什么 以上仅保留了关键部分代码 可以看出, 使用StrictRedis 即使不创建连接池, 他也会自己创建 到这里, 我们还没有看到什么redis连接真实发生 继续 下一步就是 我们继续看看 终于, 在这我们看到到了连接创建 这里调用的是 如果有可用的连接, 获取可用的链接, 如果没有, 创建一个 终于, 我们看到了, 在这里创建了连接 在ConnectionPool的实例中, 有两个list, 依次是 分别表示 上面是往 这个还是在 连接池对象调用 至此, 我们把连接池的管理流程走了一遍, ConnectionPool通过管理 python redis之连接池的原理 标签:end 目的 instance osi cep 大连 sel move options 原文地址:https://www.cnblogs.com/jiangxiaobo/p/12856575.html什么是连接池
原理
连接池使用
rdp = redis.ConnectionPool(host=‘127.0.0.1‘, port=6379, password=‘xxxxx‘)
rdc = redis.StrictRedis(connection_pool=rdp)
rdc.set(‘name‘, ‘Yi_Zhi_Yu‘)
rdc.get(‘name‘)
原理解析
def __init__(self, connection_class=Connection, max_connections=None,
**connection_kwargs):
max_connections = max_connections or 2 ** 31
if not isinstance(max_connections, (int, long)) or max_connections
def __init__(self, ...connection_pool=None...):
if not connection_pool:
...
connection_pool = ConnectionPool(**kwargs)
self.connection_pool = connection_pool
set
操作了, 很明显, 这个时候一定会发生redis连接(要不然怎么set)def set(self, name, value, ex=None, px=None, nx=False, xx=False):
...
return self.execute_command(‘SET‘, *pieces)
execute_command
def execute_command(self, *args, **options):
"Execute a command and return a parsed response"
pool = self.connection_pool
command_name = args[0]
connection = pool.get_connection(command_name, **options)
try:
connection.send_command(*args)
return self.parse_response(connection, command_name, **options)
except (ConnectionError, TimeoutError) as e:
connection.disconnect()
if not connection.retry_on_timeout and isinstance(e, TimeoutError):
raise
connection.send_command(*args)
return self.parse_response(connection, command_name, **options)
finally:
pool.release(connection)
connection = pool.get_connection(command_name, **options)
ConnectionPool
的get_connectiondef get_connection(self, command_name, *keys, **options):
"Get a connection from the pool"
self._checkpid()
try:
connection = self._available_connections.pop()
except IndexError:
connection = self.make_connection()
self._in_use_connections.add(connection)
return connection
def make_connection(self):
"Create a new connection"
if self._created_connections >= self.max_connections:
raise ConnectionError("Too many connections")
self._created_connections += 1
return self.connection_class(**self.connection_kwargs)
_available_connections
, _in_use_connections
,可用的连接集合
和正在使用的连接集合
, 在上面的get_connection
中, 我们可以看到获取连接的过程是
_in_use_connections
里添加连接的, 这种连接表示正在使用中, 那是什么时候将正在使用的连接放回到可用连接列表中的呢execute_command
里, 我们可以看到在执行redis操作时, 在finally
部分, 会执行一下pool.release(connection)
release
方法, 将连接从_in_use_connections
放回 _available_connections
, 这样后续的连接获取就能再次使用这个连接了release
方法如下 def release(self, connection):
"Releases the connection back to the pool"
self._checkpid()
if connection.pid != self.pid:
return
self._in_use_connections.remove(connection)
self._available_connections.append(connection)
总结
可用连接列表
(_available_connections
) 和 正在使用的连接列表
从而实现连接池管理
上一篇:Python 文件的使用
文章标题:python redis之连接池的原理
文章链接:http://soscw.com/index.php/essay/47158.html