データベース接続プール
データベース接続プールはデータベース接続の割り当て、管理、解放を担当します。これにより、アプリケーションはデータベース接続を再確立するのではなく、既存のデータベース接続を再利用できます。アイドル時間が最大アイドル時間を超えたデータベース接続は解放して、データベースの接続が失敗する可能性があるため、アイドル時間が最大アイドル時間を超えている場合はデータベース接続を解放します。接続が解放されません データベース接続の欠落が原因です。このテクノロジーにより、データベース操作のパフォーマンスが大幅に向上します。
影響を与える要因
データベース接続プールが初期化されると、特定の数のデータベース接続が作成され、接続プールに配置されます。これらのデータベース接続の数は、データベース接続の最小数によって制限されます。これらのデータベース接続が使用されるかどうかに関係なく、接続プールには少なくともこの数の接続が常に保証されます。接続プール内のデータベース接続の最大数は、接続プールが占有することができる最大接続数を制限します。アプリケーションによって接続プールから要求された接続数が最大接続数を超えると、これらの要求は接続プールに追加されます。待機列。データベース接続プール内の接続の最小数と最大接続数の設定では、次の要素を考慮する必要があります。
- 最小接続数は接続プールによって保持されるデータベース接続であるため、アプリケーションが大量のデータベース接続を使用しない場合、大量のデータベース接続リソースが無駄になります。
- 最大接続数は、接続プールが適用できる最大接続数です。データベース接続要求がこの数を超えると、後続のデータベース接続要求が待機キューに追加され、後続のデータベース操作に影響します。
- 最小接続数と最大接続数の差 最小接続数と最大接続数の差が大きすぎる場合、最初の接続要求は有利になり、その後の接続要求は最小接続数を超えます。接続は、新しいデータベース接続を確立することと同じです。ただし、最小接続数を超えるこれらのデータベース接続は、使用後すぐに解放されず、再利用のために接続プールに配置されるか、アイドル タイムアウト後に解放されます。
原理
接続プールの基本的な考え方は、システムの初期化時にデータベース接続をオブジェクトとしてメモリに保存することです。ユーザーがデータベースにアクセスする必要がある場合、新しい接続を確立する代わりに、確立されたアイドル接続オブジェクトが取得されます。接続プールから。使用後、ユーザーは接続を閉じず、次のアクセス要求に備えて接続を接続プールに戻します。接続の確立と切断は、接続プール自体によって管理されます。同時に、接続プール内の接続の初期数、接続の上限と下限、各接続の最大使用回数、最大アイドル時間などを、パラメータを設定することによって制御することもできます。接続プール。独自の管理メカニズムを通じて、データベースの接続数や使用状況などを監視することもできます。
アドバンテージ
パフォーマンスの向上: データベース接続の作成と破棄は、コストのかかる操作です。接続プーリングは、一定数のデータベース接続を事前に作成し、それらをプール内に保持することで、接続の頻繁な作成と破棄を回避します。これにより、各リクエストに必要な時間が大幅に短縮され、システムのパフォーマンスが大幅に向上します。
リソース管理: 接続プールはデータベース接続を効果的に管理し、割り当てることができます。接続数を制限してリソースの過剰使用を防ぎ、データベース サーバーの過負荷を防ぎます。接続プーリングは接続の再利用も処理できるため、新しい接続を頻繁に作成する際のオーバーヘッドが軽減されます。
スケーラビリティ: 接続プールを使用すると、ニーズに応じて接続プールのサイズを調整できます。これにより、システムは負荷の変化に応じて接続数を自動的に拡大または縮小して、さまざまなニーズを満たすことができます。このスケーラビリティにより、システムは高い同時実行性と高トラフィックの状況にうまく対処できるようになります。
接続の再利用: 接続プールは、毎回新しい接続を作成するのではなく、接続を再利用できます。これにより、接続の確立と切断を頻繁に行うオーバーヘッドが回避され、データベース サーバーとの通信オーバーヘッドが軽減されます。接続を多重化することで、システム リソースをより効率的に使用できます。
エラー処理: 接続プールは、データベース接続エラーを処理するためのエラー処理メカニズムを提供できます。接続の状態を監視し、エラーが発生した場合には接続を再作成または修復します。このように、接続プールによりシステムの安定性と信頼性が向上します。
Pythonの実装
dbutils.pooled_db は、データベース接続プールの実装を提供する Python のライブラリです。このライブラリは、データベースと対話するアプリケーションのパフォーマンスを向上させるためにデータベース接続プールを管理および維持するために広く使用されています。
import pymysql
from dbutils.pooled_db import PooledDB
host = 'localhost'
port = 3306
user = 'root'
password = '123456'
database = 'evos_gr_version1'
class MySQLConnectionPool:
def __init__(self,):
self.pool = PooledDB(
creator=pymysql, # 使用链接数据库的模块
mincached=10, # 初始化时,链接池中至少创建的链接,0表示不创建
maxconnections=200, # 连接池允许的最大连接数,0和None表示不限制连接数
blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
host=host,
port=port,
user=user,
password=password,
database=database
)
def open(self):
self.conn = self.pool.connection()
self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor) # 表示读取的数据为字典类型
return self.conn, self.cursor
def close(self, cursor, conn):
cursor.close()
conn.close()
def select_one(self, sql, *args):
"""查询单条数据"""
conn, cursor = self.open()
cursor.execute(sql, args)
result = cursor.fetchone()
self.close(conn, cursor)
return result
def select_all(self, sql, *args):
"""查询多条数据"""
conn, cursor = self.open()
cursor.execute(sql, args)
result = cursor.fetchall()
self.close(conn, cursor)
return result
def insert_one(self, sql, *args):
"""插入单条数据"""
try:
self.execute(sql, args, isNeed=True)
except Exception as err:
return {
'result': False, 'err': err}
def insert_all(self, sql, datas):
"""插入多条批量插入"""
conn, cursor = self.open()
try:
cursor.executemany(sql, datas)
conn.commit()
return {
'result': True, 'id': int(cursor.lastrowid)}
except Exception as err:
conn.rollback()
return {
'result': False, 'err': err}
def update_one(self, sql, args):
"""更新数据"""
self.execute(sql, args, isNeed=True)
def delete_one(self, sql, *args):
"""删除数据"""
self.execute(sql, args, isNeed=True)
def execute(self, sql, args, isNeed=False):
"""
执行
:param isNeed 是否需要回滚
"""
conn, cursor = self.open()
if isNeed:
try:
cursor.execute(sql, args)
conn.commit()
except:
conn.rollback()
else:
cursor.execute(sql, args)
conn.commit()
self.close(conn, cursor)
接続する
mysql = MySQLConnectionPool()
1.挿入
sql_insert_one = "insert into `configuration` (`system`, blocksize, inodesize) values (%s,%s,%s)"
mysql.insert_one(sql_insert_one, ('ext4', '1024', 512))
datas = [
('ext4', '1024', 512),
('ext2', '1024', 256),
]
sql_insert_all = "insert into `configuration` (`system`, blocksize, inodesize) values (%s,%s,%s)"
mysql.insert_all(sql_insert_all, datas)
2.削除
sql_delete_one = "delete from `cofiguration` where `system`=%s "
mysql.delete_one(sql_delete_one, ('ext2',))
3. 変更
sql_update_one = "update `cofiguration` set blocksize=%s where `system`=%s"
mysql.update_one(sql_update_one, (1024, 'ext4'))
4. クエリ
sql_select_one = "select * from `cofiguration` where `system`=%s"
results = mysql.select_one(sql_select_one, ('ext4',))
print(results)
sql_select_all = "select * from `cofiguration` where `system`=%s"
results = mysql.select_all(sql_select_all, ('ext4',))
print(results)