Transparent Application Failover (TAF) Glasklar für

Transcription

Transparent Application Failover (TAF) Glasklar für
Donnerstag, 10. November 2005
16h00, Variohalle 1
DB-Entwicklung
Transparent Application Failover (TAF)
Glasklar für Applikationsentwickler?
Peter Welkenbach, Urs Meier
Trivadis
Zürich, Basel, Bern, Baden, Lausanne, Stuttgart,
München, Freiburg i.Br., Frankfurt, Hamburg, Düsseldorf
Schlüsselworte:
Transparent Failover, TAF, Real Application Server, RAC, Command Pattern, Application Server, Persistenz
Framework, Fast Application Notification, FAN, Fast Connection Failover, FAF, Connection Pooling,
Connection Cache, .NET, ODP, Java, JDBC, Spring
Einleitung
Oracle Real Application Clusters (RAC) sind ein strategischer Vorteil von Oracle gegenüber Konkurrenzprodukten und erfreuen sich nicht zuletzt wegen verbesserten Lizenzbedingungen in Oracle 10g immer
grösserer Beliebtheit. Transparentes Wechseln einer Session auf einen anderen Knoten im Fall eines
Knotenausfalls ist eines der Features von RAC, welches diese Option attraktiv macht. Doch was braucht
es in der Applikationsprogrammierung, damit eine Applikation vollständig TAF-tauglich wird? TAF ist
nämlich nicht so ganz transparent wie der Name vermuten lässt. Nebst Transaktions-Rollback bei schreibenden Transaktionen gehen auch PL/SQL Package State, Global Temporary Tables, Session-Settings usw.
ohne besondere Vorkehrungen beim Knotenwechsel verloren. In diesem Vortrag zeigen wir, was eine
Applikation "wissen" muss, um im Failover-Fall auch schreibende Transaktionen zu meistern. Der Zuhörer
sieht wie jeweils eine Java und .NET Applikation – basierend auf einem Command Design Pattern – mit
dem Transparent Application Failover (TAF) umgeht und z.B. auch das Connection Pooling bewältigt.
TAF Grundlagen
Transparent Failover (TAF) ist eine Oracle Net Client Feature, welche bei Instance Crash die Client
Connection auf einen anderen verfügbaren Knoten umleitet. TAF kann mit unterschiedlichen Konfigurationen genutzt werden. Entscheidend ist einzig die Zeit, wie lange es dauert, bis die Failover-Instance
(Datenbank) verfügbar ist. Zusammen mit Real Application Cluster (RAC) von Oracle ist TAF eine optimale Verbindung, da mit RAC mindestens eine Instance ständig verfügbar ist.
Die Oracle Net Konfiguration in Client tnsnames.ora bestimmt, wie TAF funktioniert. Wichtig sind die
Einträge unter FAILOVER_MODE
TYPE = SELECT
Diese Konfiguration erlaubt SELECT Befehle transparent, also ohne Zutun der Applikation, nach einem
Failover weiter zu führen. Oracle berechnet dazu einen eindeutigen Hash-Wert und führt die Query auf
der neuen Instanz nur fort, wenn dieser Hash-Wert vor und nach dem Failover identisch ist. Die Applikation merkt ausser dem Zeitverlust (die Query muss neu gestartet werden) nichts vom Failover. In diesem Fall ist TAF wirklich transparent.
Bei schreibenden Transaktionen kann nicht einfach ein Hash-Wert berechnet und weiter gearbeitet werden. Laufende Transaktionen werden beim Failover automatisch zurück gefahren (Rollback) und müssen
neu gestartet werden.
Die Applikation muss also eine robuste Fehlerbehandlung zur Verfügung stellen und die „verlorene“
Transaktion neu starten. TAF ist also nicht wirklich transparent und unterschiedliche Settings (z.B.
Session Settings, PL/SQL Package State und Global Temporary Tables) werden beim Failover von Oracle
nicht von einer Instance auf die andere übernommen.
Eine weitere Schwierigkeit ist die Fehlerunterscheidung. Zum Beispiel kann der Fehler ORA-3113 (End of
Communication Channel) nicht nur nach einem TAF vorkommen. Wie also weiss die Applikation, ob
nach einem ORA-3113 ein Wiederanlauf der Transaktion sinnvoll ist oder nicht.
TAF Callback
TAF hilft hier mit einem speziellen Event (Callback).
Sowohl Java wie .NET unterstützen eine Anmeldung am TAF Event. Das heisst, die Applikation wir bei
einem TAF benachrichtigt und die Applikation kann sogar wählen, welche Routine (Methode) in der
Applikation bei einem TAF ausgeführt werden soll (Function Callback).
TAF meldet folgende Events:
> FO_BEGIN
» Verlorene Connection wurde gefunden, Failover startet
> FO_END
» Erfolgreiches Failover-Ende
> FO_ABORT
» Failover war nicht erfolgreich, keine Wiederholung möglich
> FO_REAUTH
» Benutzer wurde reauthentisiert
> FO_ERROR
» Failover war temporär nicht erfolgreich, gibt der Applikation die Möglichkeit der Fehlerbehandlung
und eines Wiederholungs-Versuchs
> FO_RETRY
» Versuch Failover zu Wiederholen
> FO_EVENT_UNKNOW
» Bad Failover Event
Im Gegensatz zu üblichen Events (Function Callback), welche sofort ausgelöst werden, werden die TAF
Events nur ausgelöst, wenn auch die physische Connection angesprochen wird.
In unseren Tests gelang es nicht einer offenen, nicht verwendeten (idle) Connection den TAF Event zu
melden, in dem die entsprechenden tcp ip Settings wie keep alive verändert wurden. Der Eintrag (ENABLE
= BROKEN) im tnsnames.ora änderte ebenfalls nichts.
Das heisst, die Applikation hat keinen Vorteil die Connection offen zu halten. Die entspricht dem üblichen und empfohlenen Verhalten von Connection Pooling auf dem Application Server.
Connection Pooling ändert aber auch nichts an der Tatsache, dass laufende Transaktionen, die von einem
TAF betroffen sind, neu gestartet werden müssen.
Die Applikation muss bei schreibenden Transaktionen explizit auf TAF reagieren. Wo liegt nun der Vorteil von TAF gegenüber einer manuellen „Connection Recovery“ mit Close (bei Problem) und Re-Open
der Connection.
Database
DB-Entwicklung
18. Deutsche ORACLE-Anwenderkonferenz
1. Das Objekt in der Applikation bleibt geöffnet und konsistent. Es müssen keine Objekt Referenzen neu
aufgebaut werden. Nur die physische (externe) Connection wird von Oracle ersetzt.
2. Die Applikation könnte zwar ein Close im Fehlerfall machen. Der Zeitpunkt des Re-Open der Connection ist jedoch undefiniert. Zusammen mit dem TAF Event kann die Applikation genau zum richtigen
Zeitpunkt (FO_END) die Connection neu öffnen. So bleiben dem Server unzählige Open-Versuche seitens der Clients erspart. Gerade in grösseren, Performance kritischen Umgebungen mit RAC kann dies
wichtig sein.
3. Mit modernen Service orientierten Architekturen (SOA) kann die Fehlerbehandlung nicht davon ausgehen, dass ein Benutzer interaktiv auf Fehler reagieren kann. Der Service läuft stabiler mit TAF und
ohne Rückfrage.
Entkopplung der TAF Abhängigkeiten
Offensichtlich ist TAF bei schreibenden Transaktionen nicht wirklich transparent und die Applikation
muss auf den TAF Event reagieren und die Transaktion zum richtigen Zeitpunkt (nach erfolgreichem TAF)
neu aufsetzen.
Natürlich möchte man nun nicht in jeder Applikation diese Logik wieder neu programmieren und die
Applikation TAF abhängig machen. Viel mehr sollte eine robuste Applikation mit und ohne TAF funktionieren und zusammen mit TAF eine höhere Verfügbarkeit erreichen.
Eine einfache Möglichkeit die Applikation von der TAF Logik zu entkoppeln bietet das Command Design
Pattern. Beim Command Design Pattern werden die Befehle mit einem einfachen Interface (Do und evtl.
noch Undo) gekapselt.
Command Pattern sind in der UI-Programmierung üblich. Es genügt also das Command Pattern um eine
weitere Eigenschaft „Bin ich ein TAF Command, das nach TAF wiederholt werden muss?“ zu erweitern.
In einem TAF-Command steckt normalerweise gerade ein Datenbank-Befehl.
Da TAF-Commands das normale Command Design Pattern implementieren, können TAF-Commands
auch dem normalen UndoManager zur Verwaltung übergeben werden. Das heisst, der UndoManager verwaltet vom Objekte vom Typ Command (z.B. Interface ICommand), egal ob es sich dabei um UI-Commands oder um TAF-Commands handelt.
Da das Command-Pattern einfache (z.B. UPDATE) oder komplexe (z.B. Aufruf einer Facade oder eines
Session-Bean in Java) kapseln kann, können auch bestehende Applikation relativ einfach TAF fähig
gemacht werden.
Die genaue Erklärung des bekannten Command Pattern sprengt den Rahmen dieses Vortrags. Es genügt
zu wissen, dass jeder Befehl (z.B. ein Click auf einen Button oder ein Update in die Datenbank) mit dem
Command Pattern implementiert und via einem UndoManager verwaltet werden kann.
TAF mit Frameworks
Die Registrierung des TAF Events verlangt den Zugriff auf die Oracle Connection. Bei eigenen Frameworks
ist dies weniger problematisch. Was aber, wenn Standard Frameworks oder Standard Persistenz Manager
zum Einsatz kommen?
Wichtig erscheint es, dass man diese Oracle spezifischen Features generisch in eine Applikationsarchitektur einbinden kann, sodass die gleichen Business-relevanten Komponenten auch gegen andere Datenbanken oder auch ohne RAC wieder verwendet werden können.
Moderne Metaframeworks, wie z.B. das Spring-Framework (http://www.springframework.org) erlauben
durch die Implementierung des Inversion Of Control Patterns (auch Dependency Injection genannt)
einen eleganten Weg dies einfach zu bewerkstelligen. Gleichzeitig bietet sich durch den feingranularen
Komponentenansatz die Möglichkeit das Applikationsdesign übersichtlich mittels UML2 zu beschreiben.
TAF mit JDBC setzt auf dem Oracle OCI Layer auf. Dazu muss in Java das Interface OracleOCIFailover
implementiert werden. Die Klasse kann dann auf den TAF Event reagieren.
Der Code zeigt wie zusammen mit dem bekannten Spring Framework das Connection Objekt angesprochen werden kann. Über eine Spezialisierung der DriverManagerDataSource kann das Connection Objekt
frei gegeben und der TAF Event registriert werden.
In der Beispiel Applikation wird der Event über ein Singleton ausgetauscht. Der Vorteil des Singleton
beruht auf der Tatsache, dass das Event Handling zentral, also losgelöst von jeder Applikation, gemacht
werden kann. Das Singleton ist nicht, wie man zunächst annehmen könnte, Performance kritisch. Der
Event läuft nämlich im gleichen Thread wie der Aufrufer ab.
Database
DB-Entwicklung
18. Deutsche ORACLE-Anwenderkonferenz
Connection Cache, FAN und FCF
Oracle RAC bietet seit dem Relase 10g die Möglichkeit, dass sich Applikationen an Events (ähnlich zum
TAF Event) anmelden. Der Server meldet diverse Events, wenn sich der Status einer Cluster Componente
ändert. Dies wird Fast Application Notification (FAN) genannt. FAN kann über integrierte Clients (JDBC,
ODP.NET, OCI) oder über die Oracle Notification Services (ONS) Client seitig angesprochen werden.
JDBC ist seit Release 10g mit dem JDBC Version 3.0 Standard kompatibel und unterstützt FAN seit 10g
Release 1.
Fast Connection Failover (FCF) basiert auf FAN und löst das Problem von „toten“ Connections im
Connection Pool. Bei FCF werden bei Instance Crash alle Connections im Pool direkt auf eine andere verfügbare RAC Instanz gewechselt. Dies hat den Vorteil, dass die Applikation immer gültige Connections
aus dem Connection Pool bekommt.
Für laufende Transaktionen ändert FCF gegenüber TAF jedoch nichts. Laufende Transaktionen werden
abgebrochen und müssen neu gestartet werden.
Logische und physikalische Connection im Pool
Der Connection Cache unterscheidet physikalische und logische Connections:
Logische Connections sind Proxies auf physikalische Connections
So können physikalische Connections manipuliert werden, ohne die Applikation zu beeinflussen.
Der Cache gibt immer nur die Proxies zurück
Logische Connections implementieren die gleichen Interfaces wie physikalische Connections.
Transparenter Zugriff auf den JDBC Connection Cache:
Die Applikation erhält Connections über OracleDataSource APIs
Ist Caching eingeschaltet, dann werden alle Connection-Anfragen vom Connection Cache beantwortet.
Mit OracleConnection.close() wird die physikalische Connection in den Cache zurückgegeben.
Einzelner Cache per OracleDataSource Instanz:
Ist Caching eingeschaltet, dann hat jede OracleDataSource genau einen zugeordneten Cache
Alle Connections die durch diese DataSource geholt werden, gelangen wieder in den Cache
Wenn eine Connection angefragt wird so returniert der Cache entweder eine bestehende oder erstellt eine
neue mit der genau gleichen Authentisierungs-Information.
Heterogene Benutzernamen und Passwörter per Cache:
Alle Connections einer Datasource werden im gleichen Cache vorgehalten, unabhängig welche Usernamen und Passwörter die Connection wünscht
Unterstützung von JDBC 3.0 Connection Caching, inklusive Support für multiple Benutzernamen.
Property-basierte Konfiguration
Cache Properties bestimmen das Verhalten des Caches, z.B. Timeout, Anzahl der Connections.
Es handelt sich um Labels, deren Semantik durch die Applikation definiert werden, nicht durch den
Caching-Mechanismus.
Applikationen können somit bestimmte Connection-Objekte aus dem Cache holen.
Beispiel: conn = ods.getConnection(“SCOTT”, “TIGER”);
Kernaussagen
TAF ist für lesende Transkationen wirklich transparent. Für schreibende Transaktionen muss die Applikation jedoch angepasst werden. Design Pattern helfen diese Anpassungen auf ein Minimum zu beschränken. Am Beispiel Command Pattern wurde gezeigt, dass die Applikation nach einen TAF sehr einfach alle
Oracle Befehle wiederholen kann, welche auf der neuen Instance erneut ausgeführt werden müssen.
Bestehende Applikation können mit vernünftigem Aufwand TAF fähig gemacht.
TAF eignet sich auch in Zusammenarbeit mit Frameworks und Persistenz Managern. Test Implementationen zusammen mit dem Spring Framework haben gezeigt, dass über einfache Erweiterungen die TAF
Logik ebenfalls bestens von der Applikation getrennt werden kann.
TAF kann also sehr einfach „transparent“ gemacht werden. Zusammen mit RAC von Oracle ist dies eine
mächtige Option für die Verfügbarkeit.
Kontaktadresse:
Peter Welkenbach
Ferdinand-Stuttmann-Str. 13
D- 65428 Rüsselsheim (Frankfurt)
Telefon:
Fax:
E-Mail
Internet:
+49-6142-210 18 0
+49-6142-210 18 29
[email protected]
www.trivadis.com
Database
DB-Entwicklung
18. Deutsche ORACLE-Anwenderkonferenz