如果您的應用側主要使用Python語言,且資料庫連接建立頻繁(例如短串連情境)或串連數量較大(大於MySQL資料庫的串連數限制),您可以使用Python串連池DBUtils串連資料庫,降低串連建立頻率以減少資料庫主線程的開銷。
前提條件
應用伺服器已安裝Python環境且Python版本在3.7至3.12。
已將伺服器IP地址添加至RDS執行個體白名單中,詳情請參見設定IP白名單。
說明若您的應用程式部署在阿里雲ECS伺服器上,且ECS與RDS已實現內網互連(ECS與RDS執行個體的地區、VPC均相同),則無需設定IP白名單。
準備工作
安裝DBUtils:您需要通過以下命令在伺服器上安裝Python串連池DBUtils,本教程中DBUtils版本為3.1.0,更多版本及資訊請參見DBUtils。
pip install DBUtils==3.1.0安裝PyMySQL:您需要通過以下命令安裝PyMySQL,以支援伺服器串連資料庫。
pip install pymysql
使用DBUtils串連資料庫
匯入相關模組:在使用DBUtils串連資料庫前,您需要通過以下代碼匯入相關模組。
from dbutils.pooled_db import PooledDB import importlib import pymysql構建
DBUtilsDemo類:為了方便您後續的方法調用與管理,建議您建立一個DBUtilsDemo類,在__init__方法中設定串連池參數,並向該類中添加_connect與_close方法以便從串連池中擷取與歸還資料庫連接。class DBUtilsDemo: def __init__(self, url, user, password, database): db_config = { "host": url, "port": 3306, "user": user, "db": database, "password": password, "charset": "utf8", "connect_timeout": 3, "read_timeout": 10, "write_timeout": 10 } ''' DBUtils串連池常見參數的詳細說明請參見後文,以下為參數簡要說明: mincached: 池中閑置串連的初始數量(0表示啟動時不會建立串連)。 maxcached: 池中閑置串連的最大數量(0或None表示串連池大小沒有限制)。 maxshared: 共用串連的最大數量(0或None表示所有串連都是專用的)。 maxconnections: 一般允許的最大串連數量(0或None表示串連不受限制)。 blocking: 在超過最大串連數量時的行為。 maxusage: 單個串連的最大重用次數(0或None表示無限重用)。 ''' self.pooled = PooledDB(pymysql, maxcached=20, maxshared=0, maxconnections=100, maxusage=20, **db_config) # 從串連池擷取串連 def _connect(self): try: r = self.pooled.connection() return r except Exception as e: print("Failed to connect:" + str(e)) # 歸還串連到串連池 def _close(self, conn, stmt): if stmt: stmt.close() if conn: conn.close()在
__main__函數中初始化DBUtilsDemo類並串連資料庫:DBUtilsDemo類構造完成後,您可以在__main__函數中初始化該類,並擷取資料庫連接。if __name__ == '__main__': # RDS MySQL執行個體串連地址,需要根據伺服器情況選擇RDS內網/外網串連地址。 url = 'rm-bp**************.mysql.rds.aliyuncs.com' # 使用者名稱,根據實際情況做替換。 user = 'dbuser' # 密碼,根據實際情況做替換。 password = '****' # 串連的資料庫名稱,根據實際情況做替換。 database = 'dbtest' # 擷取串連池對象 poolUtils = DBUtilsDemo(url, user, password, database)
串連池常見參數配置
在使用DBUtils串連資料庫時,建議您根據下述內容為串連池設定合適的參數(在__init__方法調用的PooledDB函數中設定),使資料庫的運行更穩定高效。
為了最大程度地避免潛在的風險和不確定性,在將新的參數值用於生產環境前,建議您至少進行一輪完整的功能測試和效能測試,以確保系統穩定性和可靠性。
推薦配置的參數
推薦您在使用DBUtils串連池時設定以下參數,降低資料庫運行風險。
參數名 | 含義 | 預設值 | 推薦值 | 說明 |
maxcached | 池中閑置串連的最大數量。 | 0 | 20 |
|
maxusage | 單個串連的最大重用次數。 | None | 10~20 |
|
connect_timeout | 串連到資料庫的逾時時間(秒)。 | 10 | 3 |
|
read_timeout | 從資料庫讀取的逾時時間(秒)。 | None | 10~60 |
|
write_timeout | 寫入資料庫的逾時時間(秒)。 | None | 10~60 |
|
可選擇配置的參數
使用DBUtils串連池時,您可以選擇性地配置以下參數,提升資料庫效能。
參數名 | 含義 | 預設值 | 推薦值 | 說明 |
maxconnections | 串連池允許的最大串連數量。 | 0 | 100 |
|
保持預設配置的參數
對於以下常見的串連池參數,您可以選擇直接使用預設配置或根據自身需求調整參數。
參數名 | 含義 | 預設值 | 推薦值 | 說明 |
mincached | 池中閑置串連的初始數量。 | 0 | / |
|
maxshared | 共用串連的最大數量。 | 0 | / |
|
blocking | 超過最大串連數量時的處理方法。 | False | / |
|
setsession | 串連被建立時執行的 SQL 陳述式 | None | / | 該參數可以用來設定會話層級的參數或者執行其他初始化操作。 |
reset | 串連被放回串連池時,是否需要重設串連狀態。 | True | / |
|
failures | 資料庫連接失敗時的重連次數。 | None | / | / |
ping | 串連池在空閑串連時執行的心跳檢測操作。 | 1 | / | 該參數用來驗證串連可用性。 |
後續資料庫操作
您可以在DBUtilsDemo類中添加自訂方法處理讀寫請求,滿足對資料庫的操作需求。
讀請求處理
1. 添加自訂方法
您需要在DBUtilsDemo類中添加自訂方法處理資料庫讀請求,本文以查詢單條記錄與查詢多條記錄為例。
查詢單條記錄
def select_row(self, sql): connection = self._connect() statement = None try: statement = connection.cursor() statement.execute(sql) row = statement.fetchone() return row except Exception as e: print(e) finally: self._close(connection, statement)查詢多條記錄
def select_rows(self, sql): connection = self._connect() statement = None try: statement = connection.cursor() statement.execute(sql) rows = statement.fetchall() return rows except Exception as e: print(e) finally: self._close(connection, statement)
2. 調用自訂方法
您需要在__main__函數中調用該方法進行資料查詢。
if __name__ == '__main__':
# 配置串連參數並串連資料庫
url = 'rm-bp**************.mysql.rds.aliyuncs.com'
user = 'dbuser'
password = '****'
database = 'dbtest'
poolUtils = DBUtilsDemo(url, user, password, database)
# 查詢單條記錄
row = poolUtils.select_row("select * from tb where id = 'i001' limit 1")
print(row)
# 查詢多條記錄
rows = poolUtils.select_rows("select * from tb")
print(rows)寫請求處理
1. 添加自訂方法
您需要在DBUtilsDemo類中添加自訂方法處理資料庫寫請求(包括INSERT、UPDATE、DELETE、CREATE TABLE等命令),本文以帶參數寫請求與不帶參數寫請求為例。
帶參數寫請求處理
def upsert_data_prams(self, sql_upsert, params): connection = self._connect() statement = None try: statement = connection.cursor() statement.execute(sql_upsert, params) connection.commit() except Exception as e: print(e) finally: self._close(connection, statement)不帶參數寫請求處理
def upsert_data(self, sql_upsert): connection = self._connect() statement = None try: statement = connection.cursor() statement.execute(sql_upsert) connection.commit() except Exception as e: print(e) finally: self._close(connection, statement)
2. 調用自訂方法
您需要在__main__函數中調用該方法執行SQL語句。
if __name__ == '__main__':
# 配置串連參數並串連資料庫
url = 'rm-bp**************.mysql.rds.aliyuncs.com'
user = 'dbuser'
password = '****'
database = 'dbtest'
poolUtils = DBUtilsDemo(url, user, password, database)
# 不帶參數寫請求處理
poolUtils.upsert_data("insert into tb(id,name,address) values ('i001','n001','a001')")
# 帶參數寫請求處理
params = ['i002', 'n002', 'a002']
poolUtils.upsert_data_prams("insert into tb(id,name,address) values (%s,%s,%s)", params)相關文檔
Java串連池:使用Java串連池Druid串連資料庫
RDS MySQL資料庫代理中的串連池功能:RDS MySQL設定串連池