日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python连接池原理_python redis之连接池的原理

發布時間:2024/10/8 python 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python连接池原理_python redis之连接池的原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

python redis之連接池的原理

什么是連接池

通常情況下, 當我們需要做redis操作時, 會創建一個連接, 并基于這個連接進行redis操作, 操作完成后, 釋放連接,

一般情況下, 這是沒問題的, 但當并發量比較高的時候, 頻繁的連接創建和釋放對性能會有較高的影響

于是, 連接池就發揮作用了

連接池的原理是, 通過預先創建多個連接, 當進行redis操作時, 直接獲取已經創建的連接進行操作, 而且操作完成后, 不會釋放, 用于后續的其他redis操作

這樣就達到了避免頻繁的redis連接創建和釋放的目的, 從而提高性能了

原理

那么, 在redis-py中, 他是怎么進行連接池管理的呢

連接池使用

首先看下如何進行連接池操作的

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')

原理解析

當redis.ConnectionPool 實例化的時候, 做了什么

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 <0:raise ValueError('"max_connections" must be a positive integer')

self.connection_class=connection_class

self.connection_kwargs=connection_kwargs

self.max_connections= max_connections

這個連接池的實例化其實未做任何真實的redis連接, 僅僅是設置最大連接數, 連接參數和連接類

StrictRedis 實例化的時候, 又做了什么

def __init__(self, ...connection_pool=None...):if notconnection_pool:

...

connection_pool= ConnectionPool(**kwargs)

self.connection_pool= connection_pool

以上僅保留了關鍵部分代碼

可以看出, 使用StrictRedis 即使不創建連接池, 他也會自己創建

到這里, 我們還沒有看到什么redis連接真實發生

繼續

下一步就是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 andisinstance(e, TimeoutError):raiseconnection.send_command(*args)return self.parse_response(connection, command_name, **options)finally:

pool.release(connection)

終于, 在這我們看到到了連接創建

connection = pool.get_connection(command_name, **options)

這里調用的是ConnectionPool的get_connection

def get_connection(self, command_name, *keys, **options):"Get a connection from the pool"self._checkpid()try:

connection=self._available_connections.pop()exceptIndexError:

connection=self.make_connection()

self._in_use_connections.add(connection)return connection

如果有可用的連接, 獲取可用的鏈接, 如果沒有, 創建一個

defmake_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)

終于, 我們看到了, 在這里創建了連接

在ConnectionPool的實例中, 有兩個list, 依次是_available_connections,?_in_use_connections,

分別表示可用的連接集合和正在使用的連接集合, 在上面的get_connection中, 我們可以看到獲取連接的過程是

從可用連接集合嘗試獲取連接,

如果獲取不到, 重新創建連接

將獲取到的連接添加到正在使用的連接集合

上面是往_in_use_connections里添加連接的, 這種連接表示正在使用中, 那是什么時候將正在使用的連接放回到可用連接列表中的呢

這個還是在execute_command里, 我們可以看到在執行redis操作時, 在finally部分, 會執行一下

pool.release(connection)

連接池對象調用release方法, 將連接從_in_use_connections?放回?_available_connections, 這樣后續的連接獲取就能再次使用這個連接了

release?方法如下

defrelease(self, connection):"Releases the connection back to the pool"self._checkpid()if connection.pid !=self.pid:returnself._in_use_connections.remove(connection)

self._available_connections.append(connection)

總結

至此, 我們把連接池的管理流程走了一遍, ConnectionPool通過管理可用連接列表(_available_connections) 和?正在使用的連接列表從而實現連接池管理

總結

以上是生活随笔為你收集整理的python连接池原理_python redis之连接池的原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。