Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A kapcsolati pooling javítja az alkalmazás teljesítményét azáltal, hogy adatbázis-kapcsolatokat újrahasznosítanak, ahelyett, hogy minden kéréshez újakat hoznának létre. A kapcsolat megnyitása több időigényes lépést igényel:
- Az illesztőprogram hálózati aljmentet hoz létre.
- A sofőr befejezi a TLS kézfogást.
- Az illesztőprogram hitelesíti a szervert.
- Az illesztőprogram érvényesíti a kapcsolati paramétereket.
A kapcsolat pooling nyitva tartja a kapcsolatokat és újrahasznosítható, így az alkalmazásodnak nem kell minden kérésnél ismételnie ezeket a lépéseket.
Alapértelmezett viselkedés
A kapcsolat-összevonás alapértelmezetten engedélyezett, amikor létrehozod az első kapcsolatot. Az alapértelmezett beállítások a következők:
| Setting | Alapértelmezett érték | Leírás |
|---|---|---|
max_size |
100 | Maximális kapcsolatok egyedi kapcsolati karakterlánc szerint. |
idle_timeout |
600 másodperc (10 perc) | Az inaktív kapcsolatok lezárása előtti másodpercek száma. |
import mssql_python
# Pooling is automatically enabled with defaults
conn = mssql_python.connect(connection_string)
Kapcsolat-összevonás konfigurálása
Konfiguráld a poolinget, mielőtt bármilyen kapcsolatot létrehoznál:
import mssql_python
# Configure custom pool settings
mssql_python.pooling(max_size=50, idle_timeout=300)
# Now create connections
conn = mssql_python.connect(connection_string)
Parameters
A pooling() függvény a következő paramétereket fogadja el:
| Paraméter | Típus | Default | Leírás |
|---|---|---|---|
max_size |
int | 100 | Kapcsolati karakterlánconként az összevont kapcsolatok maximális száma. |
idle_timeout |
int | 600 | Másodpercekkel azelőtt, hogy az üres kapcsolatokat kilakoltatják a medencéből. |
enabled |
bool | True | Engedélyezd vagy tiltsd ki a poolingolást. |
A kapcsolat-újrafelhasználás letiltása
A kapcsolat-összevonás letiltásához hívja meg a(z) pooling() elemet a(z) enabled=False paraméterrel a kapcsolatok létrehozása előtt:
import mssql_python
mssql_python.pooling(enabled=False)
# Connections are now created and destroyed per use
conn = mssql_python.connect(connection_string)
Megjegyzés:
Állítsd be a pooling konfigurációt, mielőtt bármilyen kapcsolatot létrehoznál. A pooling() hívás kapcsolatok létrehozása után nem hatásos.
Hogyan működik a pooling
Kapcsolati lánc izolálása
Minden egyedi kapcsolati karakterlánc saját független poolt tart fenn. A poolok nem osztoznak meg különböző kapcsolódási láncok között:
# These use separate pools
conn1 = mssql_python.connect("Server=<server1>;Database=<database1>;...")
conn2 = mssql_python.connect("Server=<server2>;Database=<database2>;...")
Identitásizoláció
A legtöbb tokenalapú hitelesítési módszernél a meghajtó elkülönítve kezeli a kapcsolatkészleteket a kapcsolatot megnyitó Microsoft Entra-identitás alapján, így egy adott rendszerbiztonsági névvel hitelesített kapcsolatot nem ad át olyan hívónak, amely egy másik rendszerbiztonsági nevet használ. A kivétel a következő táblázat első sora, ahol a kulcs önmagában a kapcsolati karakterlánc.
A pool kulcs a hitelesítési módszertől függ:
| Authentication | Medence kulcs |
|---|---|
SQL hitelesítés, megbízható kapcsolatok, szolgáltatáselvek, Windows integrált hitelesítés, és ActiveDirectoryInteractive Windows használata |
Csak kapcsolási lánc |
| Felügyelt identitás | Kapcsolati lánc, valamint az ügyfélazonosító vagy a rendszer által hozzárendelt identitás |
| Eszközkód hitelesítés és interaktív hitelesítés más platformokon, mint a Windows | Kapcsolati lánc, valamint a bejelentkezett fiók |
DefaultAzureCredential, egy egyedi token_provider, és nyers hozzáférési tokenek |
Kapcsolati sztring, valamint a token kivonata |
Mivel a token hash része az utolsó csoport kulcsának, minden különálló token saját készletet kap. Egy hosszú életű jogosultság, amely gyorsítótározott tokent ad vissza, továbbra is egy poolt használ újra. Az illesztőprogram lustán nyeri vissza az üres identitáskészleteket, ahogy a későbbi pool műveletek futnak, nem pedig háttérszál révén.
A driver csak akkor szerez tokeneket, amikor új kapcsolatot kell nyitnia, így egy pool találat nem szerez tokent.
Az illesztőprogram frissíti a kapcsolatpoolban lévő azon kapcsolatokat, amelyek tokenje a lejárat előtt 5 percen belül van, mielőtt a kapcsolatot átadná, így a hosszú életű kapcsolatpoolok nem adnak vissza olyan kapcsolatokat, amelyek hamarosan meghibásodnának.
Kapcsolati életciklus
Lekérés (kapcsolat létrehozása):
- A medence eltávolítja az elavult (alapjárati lejárt) csatlakozásokat.
- A pool megpróbálja újrahasznosítani egy meglévő kapcsolatot:
- Ellenőrzi, hogy a kapcsolat él-e.
- Visszaállítja a kapcsolati állapotot.
- Ha mindkét ellenőrzés sikeres, visszaadja a kapcsolatot.
- Ha nincs újrahasználható kapcsolat, és a pool alatt
max_sizevan, az illesztőprogram új kapcsolatot hoz létre. - Ha a pool tele van és nincs érvényes kapcsolat, a meghajtó hibát okoz.
Felszabadítás (a kapcsolat visszaadása):
- Ha a medencében van kapacitás, akkor a kapcsolatot újrahasznosítja el.
- Ha a kapcsolatkészlet eléri a
max_sizeértéket, az illesztőprogram azonnal lezárja a kapcsolatot.
Kapcsolati egészségellenőrzések
Az illesztőprogram ellenőrzi a kapcsolat állapotát, mielőtt újra felhasználná a kapcsolatkészletből származó kapcsolatot.
- Élő ellenőrzés: Biztosítja, hogy a hálózati kapcsolat továbbra is érvényes.
- Reset ellenőrzés: Visszaállítja a session állapotot (izolációs szint, beállítások) a tiszta újrahasználathoz.
Ha bármelyik próba sikertelen, a pool eldobja a kapcsolatot, és új kapcsolatot hoz létre.
Automatikus takarítás
-
Tétlenségi időkorlát: Az illesztőprogram lezárja azokat a kapcsolatokat, amelyeket a
idle_timeoutértéknél hosszabb ideig nem használnak. -
Folyamatkilépés: Egy
atexitkezelő lezárja az összes felosztott kapcsolatot, amikor a Python folyamat kilép.
Bevált gyakorlatok
Méretezd megfelelően a medencédet
Igazítsa a készlet méretét az alkalmazás egyidejűségi igényeihez.
# For a web application with 20 concurrent requests
mssql_python.pooling(max_size=25) # Slightly more than expected concurrency
Használj kontextuskezelőket
A kontextuskezelők biztosítják, hogy a kapcsolatok megfelelően visszakerüljenek a kapcsolatpoolba.
with mssql_python.connect(connection_string) as conn:
cursor = conn.cursor()
cursor.execute("SELECT TOP 5 Name, ListPrice FROM Production.Product")
rows = cursor.fetchall()
# Connection returned to pool
Tartsd a kapcsolati láncokat konzisztens
A kapcsolódási láncok különböző paraméterei külön poolokat hoznak létre.
# These create THREE separate pools (inefficient)
conn1 = mssql_python.connect("Server=<server>;Database=<database>;Encrypt=yes;")
conn2 = mssql_python.connect("SERVER=<server>;DATABASE=<database>;ENCRYPT=yes;") # Different case
conn3 = mssql_python.connect("Server=<server>;Database=<database>;Encrypt=yes;", timeout=30) # Extra parameter
# Use a constant connection string instead
CONNECTION_STRING = "Server=<server>;Database=<database>;Encrypt=yes;"
conn1 = mssql_python.connect(CONNECTION_STRING)
conn2 = mssql_python.connect(CONNECTION_STRING) # Same pool
Vegye figyelembe az Azure SQL kapcsolati korlátait
Azure SQL Database a szolgáltatási szint alapján érvényesíti a kapcsolati korlátokat. A következő értékek közelítőek; Nézd meg a linkelt dokumentációt a jelenlegi korlátokról:
| Szolgáltatási szint | Maximális egyidejű kapcsolatok száma |
|---|---|
| Alapszintű | 30 |
| Standard S0-S2 | 60-120 |
| Standard S3 és későbbi verziók | 200 |
| prémium | 500 |
Állítsd be az max_size értéket ezen korlátok alá.
# For Azure SQL Standard S2 (120 limit)
mssql_python.pooling(max_size=100) # Leave headroom
Állítsa be az üresjárati időkorlátot a számítási feladathoz
- Gyakori kapcsolatok: Hosszabb értéket használjunk, hogy melegen
idle_timeoutkapcsolatokat. -
Szórványos kapcsolatok: Rövidebb
idle_timeoutértéket használj az erőforrások felszabadítására.
# High-frequency API: keep connections warm
mssql_python.pooling(idle_timeout=1800) # 30 minutes
# Batch job running every hour: release between runs
mssql_python.pooling(idle_timeout=60) # 1 minute
Limitations
A jelenlegi megvalósításnak vannak korlátai más meghajtókhoz képest:
| Feature | Status |
|---|---|
ClearPool() / ClearAllPools() |
Nem érhető el |
| Készletstatisztikák/figyelés | Nem érhető el |
| Kapcsolatonkénti pool felülbírálása | Nem érhető el |
| Minimális medence méret | Nem konfigurálható. |
Példa: Webalkalmazási minta
A következő Flask-példa bemutatja, hogyan történik a kapcsolatok készletezése a kérések között a háttérben:
import mssql_python
from flask import Flask, g
app = Flask(__name__)
# Configure pooling at startup
mssql_python.pooling(max_size=20, idle_timeout=300)
def get_db():
if 'db' not in g:
g.db = mssql_python.connect(app.config['DATABASE_URL'])
return g.db
@app.teardown_appcontext
def close_db(error):
db = g.pop('db', None)
if db is not None:
db.close() # Returns to pool
@app.route('/products')
def list_products():
conn = get_db()
cursor = conn.cursor()
cursor.execute("SELECT TOP 5 Name, ListPrice FROM Production.Product")
return cursor.fetchall()
Ismerd fel a medence kimerültséget
Amikor az összes csatlakozás a medencében használatban van, és új kapcsolatot kérsz, olyan tüneteket látsz, mint például:
- A kapcsolatok megakadnak vagy időtúllépnek, miközben egy szabad kapcsolatra várnak.
- Az alkalmazás áteresztőképessége hirtelen csökken terhelés alatt.
- A memóriahasználat nő, ahogy az illezőprogram olyan kapcsolatokat hoz létre, amelyeket nem tud újrahasznosítani.
Gyakori okok:
- A csatlakozásokat nem viszik vissza a medencébe. Mindig zárd le a kapcsolatokat, ha végeztél, vagy használj kontextuskezelőket. A le nem zárt kapcsolat lefoglalva marad.
- A medence mérete túl kicsi a munkaterheléshez. Ha 50 egyidejű kérésed van, de
max_size=20, akkor 30 kérés várakozik. - A hosszú ideig futó lekérdezések lefoglalják a kapcsolatokat. Bontsd szét a hosszú műveleteket, vagy használj dedikált kapcsolatokat kötött munkahoz.
A javítás módja:
# 1. Always use context managers to guarantee return
with mssql_python.connect(connection_string) as conn:
cursor = conn.cursor()
cursor.execute("SELECT ...")
rows = cursor.fetchall()
# Connection returned to pool here, even if an exception occurs
# 2. Size the pool to match your concurrency
mssql_python.pooling(max_size=50) # Match or slightly exceed expected concurrent connections
# 3. Reduce idle timeout if connections go stale
mssql_python.pooling(idle_timeout=120)