Wybrane aspekty serwera aplikacji Oracle9i

Część 3

Ewa Palarczyk
na podstawie Oracle9i Technical Whitepaper

W poprzednich dwóch częściach poświęconych Oracle 9i AS
omówione zostały wszystkie komponenty serwera (Oraclowe PLOUG’tki
sierpień i grudzień 2001). W tej części chciałabym zająć się tylko niektórymi
wybranymi elementami iAS’a.

Na początku przyjrzyjmy się kilku elementom składającym
się na iAS, które w znaczący sposób wpływają na skalowalność serwera
aplikacji. Dla przypomnienia, Oracle9i AS osiąga wysoką wydajność poprzez :

  • skalowanie sprzętu,

  • buforowanie stron, danych,

  • różnorodne architektury organizacyjne.

O ile zagadnienie skalowalności sprzętowej jest
zagadnieniem dość oczywistym (praca na różnorodnym sprzęcie i systemach
operacyjnych bez konieczności zmiany platformy programowej, czy potrzeby
przepisywania swoich aplikacji), o tyle nad skalowaniem danych warto zastanowić
się chwilę dłużej.

Oracle Database Cache

Na poniższym rysunku przedstawiono sposób funkcjonowania
Oracle Database Cache: wywoływany przez klientów bazy danych, wykonuje SQL
tylko do odczytu na buforowanych danych w środkowej warstwie. Aktualizacje są
automatycznie rozprzestrzeniane do specjalizowanych RDBMS.

Sposób funkcjonowania Oracle Database Cache
Rys. 1. Sposób funkcjonowania Oracle Database Cache

Na Rysunku 2 i 3 przedstawiono przykładowy scenariusz, w którym
wykorzystuje się Oracle Database Cache, dzięki czemu przetwarzanie danych
odbywa się w środkowej warstwie. Oracle Database Cache umożliwia pierwotnej
bazie danych obsługiwanie większej liczby użytkowników, jako że będzie obsługiwała
jedynie aktualizację danych i kilka zapytań o dane. Tym samym aplikacje
uzyskują lepszą wydajność dzięki zapytaniom kierowanym do lokalnego bufora
danych, zamiast bazy danych w sieci.

Dobrym przykładem aplikacji, która korzysta na pracy Oracle
Database Cache jest strona e-biznesu z danymi katalogu produktów. Taka strona
mogłaby być przykładowo księgarnią, która przechowuje bazę danych swoich
wszystkich książek, zawierającą tytuł, autora, recenzje i wiele innych
informacji. Dane są relatywnie statyczne i mogłyby być aktualizowane raz na
dzień lub raz na tydzień. Poniższy rysunek pokazuje podstawowy sposób, w
jaki strona może być skonstruowana bez użycia Oracle Database Cache.
Statyczna zawartość strony (np. strona powitalna, grafika) może być obsługiwana
bezpośrednio przez serwer HTTP na środkowej warstwie. Specjalizowana baza
danych trzyma wszystkie dane katalogu i musi nastąpić zapytanie do bazy w celu
spełnienia każdego dynamicznego żądania. Większość żądań skierowanych
do strony będzie zapytaniami dynamicznymi, ponieważ użytkownicy często
szukają książek według autora, tytułu, tematu, itp. To generuje żądania o
instancję bazy danych, reprezentowane na rysunku przez wiele dwukierunkowych
strzałek między serwerem HTTP a bazą. Przy wzroście liczby użytkowników,
liczba równoczesnych żądań do bazy danych znacząco wzrośnie. Tym samym, jeżeli
pojedyncza instancja bazy danych zacznie przy rosnącym obciążeniu odpowiadać
powoli, stanie się ona wąskim gardłem dla skalowalności systemu.

Brak Oracle Database Cache - statyczna zawartosć
obsługiwana ze srodkowej warstwy. Wszystkie zapytania o katalog sa wykonywane
bezpośrednio w bazie danych. Liczne prostokaty oznaczaja, że serwer HTTP może
pracować na wielu węzłach.
Rys. 2. Brak Oracle Database Cache – statyczna zawartość
obsługiwana ze środkowej warstwy. Wszystkie zapytania o katalog są wykonywane
bezpośrednio w bazie danych. Liczne prostokąty oznaczają, że serwer HTTP może
pracować na wielu węzłach.

Ograniczenia bazy danych przez procesor (CPU-bound) można
zlikwidować, rezygnując z przetwarzania zapytań na rzecz środkowej warstwy.
Jest to osiągnięte, jak pokazano na poniższym rysunku, dzięki buforowaniu
katalogu danych w Oracle Database Cache. Oznacza to, że wszystkie zapytania do
katalogu mogą być obsługiwane lokalnie, na węźle środkowej warstwy. Ta
architektura przynosi większą wydajność poprzez zmniejszenie liczby dróg w
dwie strony w sieci, wymaganych do spełnienia każdego zapytania o dane.
Pozwala to także osiągnąć większą skalowalność aplikacji dzięki
pozbyciu się części pracy wykonywanej w bazie danych. Tym samym baza
przestaje być wąskim gardłem.

Oracle Database Cache - wszystkie zapytania do
katalogu są wykonywane w srodkowej warstwie, redukujac obciażenie. Dane sa
buforowane na wielu węzłach srodkowej warstwy w celu uzyskania większej
skalowalnosci.
Rys. 3. Oracle Database Cache – wszystkie zapytania do
katalogu są wykonywane w środkowej warstwie, redukując obciążenie. Dane są
buforowane na wielu węzłach środkowej warstwy w celu uzyskania większej
skalowalności.
 

Rysunek 4 przedstawia podstawową architekturę Oracle
Database Cache. Każdy klient Oracle Call Interface (OCI) może oddziaływać na
istnienie Cache. Po nadejściu instrukcji SQL, OCI parsuje je i podaje dalej
kontekst (serwer i sesja), typ instrukcji (zapytanie, DML, PL/SQL itp.) oraz
instrukcję SQL do analizatora drogi SQL (SQL route analyzer – SRA). SRA
instruuje OCI czy kierować instrukcję lokalnie do Cache, czy zdalnie do
pierwotnej bazy danych. Jakiekolwiek żądanie, które nie jest zapytaniem tylko
do odczytu jest automatycznie kierowane do pierwotnego serwera. Kiedy SRA
otrzymuje zapytanie tylko do odczytu, używa algorytmu haszującego do
optymalizacji wykonywanego planu. Generowanie haszu z łańcucha SQL i
sprawdzanie go w tablicy haszowanej jest operacją bardzo szybką z bardzo małym
nadmiarem. Jeżeli hasz pokazuje, że instrukcja SQL nie była nigdy wcześniej
widziana, wtedy SRA będzie instruował OCI, jak kierować zapytaniem do Cache.

Architektura Oracle Database Cache
Rys. 4. Architektura Oracle Database Cache

Na powyższym rysunku Data Set Manager reprezentuje narzędzie
zarządzania Cache, za pomocą którego użytkownik konfiguruje właściwości
replikacji Cache.

Skalowalność aplikacji

Kolejnym aspektem, nad którym chciałabym się chwilę
zatrzymać, jest skalowalność aplikacji, z uwzględnieniem rodzaju aplikacji,
czyli typu stateless, stateful oraz dla aplikacji Java. Oracle9i AS obsługuje
transakcyjne aplikacje sieciowe typu stateless i stateful. Dla przypomnienia,
aplikacja typu stateless nie utrzymuje informacji stanu w swoim środowisku. Może
jednak utrzymywać te informacje w pamięci trwałej typu baza danych lub cookie
w przeglądarce. Idąc krokiem powyższego przykładu księgarni internetowej,
aplikacją typu stateless może być koszyk zakupów, który zapamiętuje
zawartość koszyka klienta w tabeli bazy danych. Za każdym razem, gdy klient
zadaje zapytanie, aplikacja otrzymuje informację stanu z trwałej pamięci,
przetwarza żądanie, aktualizuje bazę danych i wysyła odpowiedź do klienta.
Aplikacja sama w sobie nie przechowuje ścieżki koszyka zakupów pomiędzy następującymi
po sobie wywołaniami klienta (implementacja – skrypty CGI, serwlety Java itd.)

Na rysunku 5 pokazano zasadę działania aplikacji typu
stateless. Stan sesji klienta przechowywany jest w bazie danych, a nie w
konkretnym węźle. Dzięki czemu przy kolejnych żądaniach, klient może być
obsługiwany zarówno przez Węzeł A, jaki i Węzeł B, ponieważ oba mają
dostęp do stanu sesji w bazie danych.

Zasada działania aplikacji typu stateless
Rys. 5. Zasada działania aplikacji typu stateless 

W przeciwieństwie do aplikacji typu stateless, aplikacje
typu stateful utrzymują informację o stanie sesji w swoim środowisku
uruchamiania pomiędzy następującymi po sobie żądaniami klienta. Wracając
do naszego przykładu księgarni – koszyk zakupów zaimplementowany za
pomocą tego modelu przechowuje informacje o zakupach klienta, a nie przesyła
każdorazowo tej informacji do przeglądarki. Przykładowo serwlety Java
utrzymują stan sesji poprzez dołączenie informacji stanu do obiektu
HttpSession, który jest charakterystyczny dla sesji każdego użytkownika. Za
każdym razem, gdy użytkownik wysyła do serwera nowe żądanie HTTP, serwer wiąże
zapytanie z obiektem HttpSession dla tego użytkownika. Jak pokazano na poniższym
rysunku, stan sesji klienta przechowywany jest w Węźle A. Oznacza to, że aby
stan sesji był przy każdym następnym żądaniu dostępny, klient musi być każdorazowo
obsługiwany przez Węzeł A, nie może być obsługiwany przez Węzeł B, który
nie ma dostępu do informacji o stanie sesji.

Zasada działania aplikacji typu statefull
Rys. 6. Zasada działania aplikacji typu statefull 

Aplikacje mogą być pisane z myślą o konkretnym modelu
stateful lub stateless, a każdy z nich niesie odmienne korzyści. Obecnie
ogromy procent aplikacji internetowych stanowią implementacje wykorzystujące
model stateless. Jak pokazano na rysunku powyżej, aplikacje typu stateless
korzystają na tym, że większość żądań klienta może być obsługiwana
przez każdą instancję wielowątkowego serwera aplikacji. Może to czasami
owocować architekturą bardziej skalowalną i tolerancyjną na błędy. Z
drugiej strony, tworzenie aplikacji typu stateful jest często łatwiejsze.
Jednocześnie implementacja aplikacji typu stateful może się okazać w niektórych
przypadkach bardziej wydajna, zwłaszcza w aplikacjach, w których sesje klienta
składają się z podstawowej (niewielkiej) wielkości stanu i bardzo licznych
wywołań do serwera w krótkim okresie czasu. Podejście typu stateful pozwoli
uniknąć powtarzającego się ładowania stanu sesji przy każdym wywołaniu w
środowisku aplikacji.

Oracle9i AS oferuje skalowalność dla obydwu typów
aplikacji – stateless i stateful. Z punktu widzenia aplikacji Javy, poniższe
punkty dostarczają ogólną wskazówkę, gdzie powinno się uruchamiać Javę w
Oracle9i AS.

  • Aplikacje Javy typu stateless dobrze skalują w JDK JVM,

  • Aplikacje Javy typu stateful dobrze skalują w Oracle JVM.

Należy podkreślić, że obie JVM wspierają obydwa typy
aplikacji typu stateless i stateful, ale ich indywidualne architektury są
bardziej dopasowane do jednej lub drugiej, co wyjaśnię poniżej.

JDK JVM zapewnia wysoką wydajność w obsłudze wielu klientów
jednocześnie, co lepiej się sprawdza w wykonywaniu aplikacji Javy typu
stateless – aplikacje te, nie utrzymując stanu sesji, nie obciążają
nadmiernie VM.

Aplikacja typu stateless w JDK JVM - dodatkowi klienci nie wnosza
dodatkowego stanu do zarzadzania pomiędzy kolejnymi żadaniami. JDK JVM
sprawdza się dobrze w tym scenariuszu.
Rys. 7. Aplikacja typu stateless w JDK JVM – dodatkowi klienci nie wnoszą
dodatkowego stanu do zarządzania pomiędzy kolejnymi żądaniami. JDK JVM
sprawdza się dobrze w tym scenariuszu.

Aplikacje typu stateful natomiast zmuszają JDK JVM do równoczesnego
zarządzania pamięcią w sytuacji, gdy liczni użytkownicy mają dostęp do
pamięci. Takie zarządzanie stanem może hamować skalowalność JDK JVM.

Aplikacja typu stateful w JDK JVM - zarzadzanie pamięcia może
zwolnić wykonywanie tej aplikacji.
Rys. 8. Aplikacja typu stateful w JDK JVM – zarządzanie pamięcią może
zwolnić wykonywanie tej aplikacji.

Jak powiedziano wyżej, Oracle JVM wyjątkowo dobrze obsługuje
aplikacje typu stateful. Przy zapewnieniu odpowiedniej pojemności sprzętowej,
wydajność nie ulega zmniejszeniu. Dzieje się tak, ponieważ Oracle JVM
segreguje przestrzenie pamięci klientów – JVM może zbędne dane zbierać
oddzielnie w przestrzeni pamięci każdego użytkownika. Architektura ta pozwala
uniknąć równoczesnego zwalniania pamięci (garbage collection), które często
tworzy największe wąskie gardło skalowalności w uruchamianiu obszernych
aplikacji typu stateful na typowej JVM.

Architektura Oracle JVM - nie występuje równoczesne zwalnianie pamięci jako rezultat oddzielnych przestrzeni pamięci.
Rys. 9. Architektura Oracle JVM – nie występuje równoczesne zwalnianie pamięci
jako rezultat oddzielnych przestrzeni pamięci.

Równoważenie obciążenia

Kolejnym aspektem, na który chciałabym zwrócić uwagę,
jest równoważenie obciążenia w Oracle9i AS, które odbywa się aż na pięciu
poziomach. Sytuacja dotyczy zapytania HTTP klienta, które jest obsługiwane
przez Oracle JVM, łączy zatem równoważenie obciążenia dla serwera HTTP (w
ramach organizacji pojedynczego hosta lub licznych hostów) oraz Oracle JVM (również
pojedynczy i liczne hosty).



Obsługa zapytania HTTP klienta odbywa się w sposób następujący:

  1. Żądanie klienta HTTP przechodzi przez sieciowy load
    balancer.

  2. Pierwszy poziom równoważenia obciążenia pojawia się
    w momencie, gdy żądanie jest kierowane do jednego z węzłów serwera HTTP.
    Network load balancer może wybrać węzeł losowo, bądź wybrać węzeł
    najmniej obciążony.

  3. W węźle serwera HTTP procesy serwera przejmują obsługę
    żądań. Gotowy proces obsługuje żądanie.

  4. Można równoważyć obciążenie Oracle JVM przez
    wielokrotne procesy listenera. Listener zostaje wybrany losowo.

  5. Listener określa, który węzeł Oracle JVM ma
    najmniejsze obciążenie, a następnie, który dyspozytor na tym węźle
    jest najbardziej dostępny. Listener przekierowuje swojego klienta (proces
    serwera HTTP) do wybranego dyspozytora.

  6. Proces serwera HTTP bezpośrednio łączy się z określonym
    dysozytorem Oracle Database.

  7. Dyspozytor przyjmuje żądanie, które będzie obsługiwane
    przez proces współdzielonego serwera. Proces ten obsługuje żądanie, w
    momencie, gdy staje się dostępny.

Postaram się rozłożyć równoważenie obciążenia na
czynniki pierwsze, czyli przyjrzeć się funkcjonowaniu serwera HTTP i Oracle
JVM.

Dla przypomnienia: w przypadku Oracle HTTP Server na
pojedynczym hoście, wykorzystywany jest następujący mechanizm równoważenia
obciążenia: główny (master) proces serwera HTTP sam w sobie nie obsługuje
żądań klienta, ale tworzy i monitoruje grupę procesów potomnych. Mechanizm
działa w sposób następujący:

  1. Współdzielony jest jeden mutex przez wszystkie procesy
    potomne słuchające na tym samym gnieździe. Mutex jest mechanizmem
    wzajemnego wykluczania (MUTual EXclusion) służącym do chronienia danych
    dzielonych między wątkami przed równoczesnymi modyfikacjami. Mutex ma dwa
    możliwe stany: otwarty (nie zajęty przez żaden wątek) lub zajęty (przez
    jeden wątek). Mutex nie może posiadać więcej niż jednego wątku na raz
    (więcej na ten temat znajdziecie Państwo pod adresem: rainbow.mimuw.edu.pl/SO/Linux/Temat02/opis_mutex.html).

  2. Żądanie klienta obsługiwane jest przez proces potomny,
    który zawiera mutex. Żądanie trafia do procesu poprzez port 80.

  3. Mutex dostaje się do innego dostępnego procesu
    potomnego, jeszcze zanim zostanie obsłużone żądanie inicjujące.

  4. Kolejne żądanie klienta obsługiwane jest przez nowy
    proces potomny – ten, który aktualnie zawiera mutex.

W przypadku serwera HTTP pracującego na wielu hostach,
proces przebiega w ten sposób, że pierwsze zapytanie klienta wysyłane jest
przez Cisco Local Director do jednego z węzłów serwera HTTP. Kolejne
zapytania wysyłane są, również przez Cisco Local Director, do innego węzła
serwera.

Jeśli chodzi o Oracle JVM pracującą na jednym hoście, równoważenie
obciążenia wykorzystuje, przypominam, złożony mechanizm balansowania obciążenia,
który maksymalizuje wydajność poprzez zwiększanie skuteczności
wykorzystania procesów serwera. Mechanizm ten działa następująco:

Pierwsza część – równoważenie obciążenia przez
dyspozytory Oracle JVM:

  1. Proces PMON (Process Monitor) Oracle JVM sprawdza procesy
    wysyłające dyspozytorów i przesyła informacje o zaistniałym obciążeniu
    do listenera.

  2. Przy inicjalizacji połączenia klienta z JVM, łączy się
    on najpierw z procesem listenera.

  3. Listener, posiadający informacje o obciążeniu
    dyspozytorów, odpowiada przekierowując klienta do najmniej obciążonego
    procesu dyspozytora.

  4. Klient łączy się bezpośrednio z przypisanym mu
    przez listener dyspozytorem.

Druga część – równoważenie obciążenia dzielonych
procesów serwera:

  1. Dyspozytory, jeden po drugim (np. żądanie Dyspozytora
    A, a następnie Dyspozytora B), umieszczają żądania w kolejce żądań.

  2. Proces serwera staje się dostępny i obsługuje pierwsze
    żądanie z kolejki (tu: żądanie Dyspozytora A).

  3. Żądania w kolejce przesuwają się o poziom wyżej (żądanie
    Dyspozytora B, które było na miejscu drugim jest teraz na pierwszym).

  4. Gdy kolejny proces serwera staje się dostępny, bierze
    kolejne żądania z początku kolejki żądań (w tym wypadku żądanie
    Dyspozytora B, które znajduje się na pierwszym miejscu).

W przypadku Oracle JVM pracującego na wielu hostach, równoważenie
obciążenia odbywa się w ten sposób, że proces listenera przekierowuje żądanie
klienta do najmniej obciążonego dyspozytora, na najmniej obciążonym węźle.

ZAKOŃCZENIE

Podsumowując cały cykl o serwerze aplikacji, chciałabym
podkreślić, czym różni się iAS od wersji poprzednich. Oracle9i AS jest
wersją uaktualnioną OAS (Oracle Application Server), wcześniejszego serwera
aplikacji. Możliwe jest przeniesienie w prosty sposób najbardziej popularnych
komponentów OAS do nowej platformy. Użytkownicy OAS PL/SQL Cartridge nie
powinni mieć kłopotów w przejściu na używanie mod_plsql. Podobnie, nie
powinni mieć problemów ci użytkownicy, którzy pracują z wykorzystaniem
standardowych komponentów Javy ich (serwlety Javy, JSPs czy EJBs) przy
przenoszeniu na platformę Oracle9i AS. Jest kilka komponentów OAS, które nie
zostały zachowane w Oracle9i AS. Należą do nich JWeb, ECO, JCO, LiveHTML i
kartridże C.

Oracle9i AS jest także wyższą wersją dla wszystkich
pozostałych produktów Oracle środkowej warstwy, które zostały włączone w
Oracle9i AS. Owe wcześniejsze produkty obejmują między innymi Oracle Forms
Server, Oracle Reports Server, Oracle Discoverer Server.

Oracle9i Application Server jest nowym serwerem aplikacji środkowej
warstwy, który wspólnie z Oracle Database tworzy prostą, kompletną i
zintegrowaną platformę do uruchamiania wszystkich typów internetowych
aplikacji, włączając w to zarówno aplikacje J2EE jak też aplikacje typu
model-based. Oracle9i AS łączy siłę i niezawodność dojrzałej technologii
Oracle z mocą i łatwością nowych właściwości, takich jak Oracle Database
Cache czy serwer Oracle HTTP wspomagany przez Apache. Oracle9i AS oferuje wysoki
poziom skalowalności, dostępności i równoważenia obciążenia. Może być
organizowany w wiele różnych konfiguracji, co pozwala firmom reorganizować
swoje aplikacje dla lepszej pracy czy niezawodności bez potrzeby zmiany kodu
aplikacji.

Oracle9i AS zawiera najszerszą gamę usług środkowej
warstwy każdego producenta, wspiera rozwój aplikacji portalowych i
transakcyjnych, posiada elastyczną organizację, integrację przedsięwzięcia
i inteligencję biznesową – i to wszystko w jednym produkcie. Oracle9i AS umożliwia
zatem swoim klientom uruchamianie nowych i istniejących aplikacji w Internecie
szybko i po niskim koszcie, gdyż nie traci się tutaj czasu i pieniędzy na
integrację olbrzymiej ilości pojedynczych produktów z ofert różnych
producentów.