Otevření databázového připojení je nákladná operace a sdružování připojení se používá k udržení databázových připojení otevřených, aby je bylo možné znovu použít. Tím se vyhnete opakovanému otevírání síťových relací, ověřování a kontrole autorizace. Sdružování udržuje připojení aktivní, takže když je později požádáno o připojení, použije se jedno z aktivních, místo aby bylo nutné je vytvářet od začátku.
Sdružování připojení
Sdružování připojení se stalo jednou z nejběžnějších metod zpracování databázových připojení před požadavkem dotazu. Obvykle si myslíme, že připojení k databázi je rychlé, ale není tomu tak, zvláště když se připojuje velký počet klientů. Bez sdružování připojení by připojení trvalo požadavku až 35–50 ms, ale 1–2 ms, pokud je použito sdružování připojení. Sdružování připojení tedy předběžně přiděluje databázová připojení a poté je recykluje, když se připojují noví klienti
Důvody pro sdružování připojení
- Aby nedošlo k selhání serveru. PostgreSQL servery jsou omezeny na počet klientů, které obsluhují současně v závislosti na parametru paměti. Pokud je toto číslo překročeno, skončíte se zhroucením serveru. Při sdružování připojení používají klienti stanovený počet připojení.
- Usnadnit zpracování dotazů. Normálně jsou databázové požadavky prováděny sériovým způsobem s kritériem první dovnitř, první ven. S velkým počtem klientů by dosažení tohoto procesu trvalo věky. Přístup by proto měl spočívat v vytvoření jediného spojení s propojenými požadavky, které lze provádět současně, nikoli každý najednou.
- Zlepšete zabezpečení. Připojení často zahrnuje handshake, který může trvat v průměru 25-35 ms, během kterého je navázáno SSL, jsou kontrolována hesla a sdílení konfiguračních informací. Veškerá tato práce pro každého připojeného uživatele bude mít za následek rozsáhlé využití paměti. Při sdružování připojení se však počet připojení snižuje, čímž se šetří paměť.
Typy sdružování připojení
V zásadě existují dva typy sdružování připojení, existuje však třetí typ řešení, které funguje jako strategie sdružování připojení známá jako trvalá připojení.
Trvalé sdružování připojení
Tento přístup má v úmyslu ponechat počáteční připojení aktivní od okamžiku jeho zahájení. Neobsahuje plně funkce sdružování připojení, ale dostatečně dobře na to, aby poskytoval nějaké nepřetržité připojení. Je to docela užitečné pro malou sadu klientských připojení, jejichž režie se může pohybovat mezi 25-50 ms. Omezení tohoto přístupu spočívá v tom, že je omezen na počet připojení k databázi, přičemž obvykle jedno připojení na jeden záznam k serveru.
Framework Connection Pooling
Sdružování připojení k frameworku probíhá na aplikační úrovni, kdy se při každém spuštění skriptu serveru vytvoří fond připojení pro zpracování požadavků na dotazy, které dorazí později.
Samostatné sdružování připojení
Pro každé připojení k databázi se používá režijní paměť mezi 5 až 10 MB, aby bylo možné uspokojit požadavek na dotaz. To není úplně dobré pro velké množství spojení. Použití sdružování připojení rámce může být omezeno tímto počtem připojení, protože může dojít k velkému využití paměti. Rozhodli jsme se proto používat samostatný fond připojení, který je nakonfigurován v souladu s relacemi, výpisy a transakcemi Postgres. Hlavní výhoda spojená s tímto přístupem je:minimální režijní náklady kolem 2 kb na každé připojení.
Když vytvoříte třídu sdružování připojení, měla by splňovat následující faktory pro zvýšení výkonu databáze:
- Předběžně přidělte připojení
- Dohlížet na spojení, která jsou k dispozici
- Přiřadit nová připojení
- Počkejte, až bude dostupné připojení
- Uzavřete spojení
Předběžné přidělení připojení
Zajištění více připojení předem usnadní zpracování požadavků v okamžiku, kdy byla aplikace spuštěna. Pokud je například váš server vyvinutý v jazyce Java, můžete použít vektory k uložení dostupných nečinných připojení pomocí níže uvedeného kódu.
availableConnections = new Vector(connections);
busyConnections = new Vector();
for(int i=0; i<connections; i++) {
availableConnections.addElement(makeNewConnection());
}
Dohled nad dostupnými připojeními
Třída by měla být schopna zkontrolovat jakékoli nečinné připojení v seznamu obsazených připojení a vrátit jej. To se v zásadě provádí za účelem opětovného použití připojení nebo uzavření připojení, která se nepoužívají. Někdy připojení vyprší, a proto je při navracení připojení docela důležité zkontrolovat, zda je stále otevřené. Pokud ne, budete muset toto připojení zrušit a proces opakovat. Když je připojení zahozeno, otevře se slot, který lze použít ke zpracování nového připojení po dosažení limitu. Toho lze dosáhnout pomocí
public synchronized Connection getConnection() throws SQLException {
if (!availableConnections.isEmpty()) { Connection existingConnection =
(Connection)availableConnections.lastElement(); int lastIndex = availableConnections.size() - 1; availableConnections.removeElementAt(lastIndex); if (existingConnection.isClosed()) {
notifyAll(); // Freed up a spot for anybody waiting.
return(getConnection()); // Repeat process. } else {
busyConnections.addElement(existingConnection);
return(existingConnection); }
} }
Přiřazení nového připojení
Měli byste být schopni spustit vlákno na pozadí pro přiřazení nového připojení, pokud není k dispozici žádná nečinnost a pokud je téměř dosaženo limitu připojení.
if ((totalConnections() < maxConnections) && !connectionPending) { // Pending = connecting in bg
makeBackgroundConnection(); }
try {
wait(); // Give up lock and suspend self.
} catch(InterruptedException ie) {} return(getConnection()); // Try again.
Čekání na nové připojení
Pokud neexistuje žádné nečinné připojení a bylo dosaženo limitu připojení, konfigurace by měla být schopna čekat na nové připojení, aby bylo k dispozici bez neustálého sdružování. Můžeme tak učinit pomocí metody čekání, která poskytuje zámek synchronizace vlákna a pozastaví vlákno, dokud nebude poskytnuto upozornění.
try {
wait();
} catch(InterruptedException ie) {}
return(getConnection());
Pro dobrou aplikační etiku by klienti neměli čekat v reálném čase na připojení, spíše vyvoláte výjimku, když připojení chybí, s kódem níže:
throw new SQLException("Connection limit reached");
Uzavření připojení
Když se spojení shromažďují nesmysly, měli byste je raději zavřít, než to dělat explicitně. Pokud však chcete explicitní přístup k uzavření připojení, můžete použít:
public synchronized void closeAllConnections() {
// The closeConnections method loops down Vector, calling // close and ignoring any exceptions thrown. closeConnections(availableConnections); availableConnections = new Vector(); closeConnections(busyConnections);
busyConnections = new Vector();
}
Závěr
Sdružování připojení pro PostgreSQL nám pomáhá snížit počet zdrojů potřebných pro připojení k databázi a zvyšuje rychlost připojení k databázi. Toho je dosaženo sdružováním připojení k DB, udržováním těchto připojení a následným snížením počtu připojení, která musí být otevřena.