1. Wstęp

Współczesne systemy przetwarzające informacje muszą spełniać ostre kryteria niezawodności i dostępności. Awarie różnych części składowych tych systemów -- oprogramowania, sprzętu, sieci -- powinny być przezroczyste dla użytkownika. Powszechnie stosowanym rozwiązaniem jest replikacja pewnych elementów systemu. Może ona zachodzić na poziomie sprzętowym (macierz dyskowa, drugi procesor), programowym (dodatkowe procesy) lub mieszanym (zapasowy serwer z drugą kopią danych).

Zajmiemy się szczegółowo ostatnim przypadkiem. System składa się z maszyny podstawowej, na której działają aktywne kopie serwerów, oraz z maszyn zapasowych, na których pracują pozostałe instancje serwerów replikujące zlecenia. W razie awarii maszyny podstawowej przetwarzanie zgłoszeń klientów przejmuje jedna z maszyn zapasowych. Ponieważ dostępność systemu ma dla nas kluczowe znaczenie, czas przełączania na maszynę zapasową powinien być możliwie jak najkrótszy. Kopie danych na wszystkich maszynach powinny być spójne. Jeżeli usługa udostępniana przez serwer na maszynie podstawowej zmienia zawartość danych, to taką zmianę powinno się jak najszybciej zreplikować na maszynie zapasowej.

Na ogół system informacyjny powinien umożliwiać równoległą pracę wielu użytkowników. Łatwą kontrolę nad dzielonymi zasobami zapewnia system transakcyjny. Udostępnienie transakcji jest zatem bardzo pożądane. Transakcje powinny być replikowane w czasie rzeczywistym na zapasowej bazie danych.

Efektywny algorytm replikacji z jednej strony nie może zbytnio pogarszać jakości usługi oferowanej przez system (co wyraża się czasem odpowiedzi systemu [3]), a z drugiej powodować, że czas przełączenia na maszynę zapasową będzie zbyt długi. Oznacza to, że uaktualnianie danych na maszynie zapasowej nie powinno być zbytnio opóźnione w stosunku do aktualizacji danych na maszynie podstawowej.

Dane w ramach systemu transakcyjnego mogą być replikowane na różnych poziomach. Istniejące bazy danych (takie jak Oracle8i [11], SQL Server i inne) replikują dane na poziomie logicznych zapisów i odczytów na dysk, ponieważ posiadają informacje o blokadach i zależnościach między transakcjami. Z tego powodu taka replikacja może być bardziej wydajna, ale odbywa się tylko w ramach bazy danych, nie jest więc ani przenośna, ani uniwersalna.

System, który udostępniałby replikację na poziomie transakcji, byłby przenośny, niezależny od środowiska i od konkretnej bazy danych. Jednym z takich systemów jest RTR (ang. Reliable Transaction Router [14]). Jest to system warstwy pośredniej między systemem operacyjnym a aplikacją użytkownika. Udostępnia on transakcyjne przesyłanie komunikatów w technologii klient-serwer. Zawiera wiele mechanizmów zwiększających stopień niezawodności. Między innymi umożliwia replikację danych w czasie rzeczywistym. Niestety zastosowany w nich algorytm charakteryzuje się niską wydajnością przy złych uwarunkowaniach (nawet niewielka liczba długich transakcji może powodować znaczne zwiększenie opóźnienia replikacji). Niedostatki tego algorytmu zainspirowały nas do zajęcia się problemem replikacji.

Zaprojektowaliśmy własne algorytmy replikacji, rozwijając pomysł grupowania transakcji pochodzący z systemu RTR. Trudno byłoby jednak ocenić ich skuteczność bez przeprowadzenia testów wydajnościowych. Dlatego zaprojektowaliśmy i zaimplementowaliśmy system, będący uproszczoną wersją systemu transakcyjnego, który umożliwia symulację algorytmów replikacji. Przeprowadziliśmy testy algorytmów w różnych warunkach -- zmienialiśmy obciążenie systemu oraz parametry wejściowe algorytmów. Na podstawie wyników testów znaleźliśmy algorytm, który można uznać za uniwersalny, aczkolwiek każdy z testowanych algorytmów ma swoje wady i zalety.

Drugi i trzeci rozdział naszej pracy zawierają krótkie wprowadzenie do systemów przetwarzania transakcyjnego (ang. transaction processing systems). Opisujemy problem replikacji i jego istniejące rozwiązania. Architekturę stworzonego przez nas symulatora przedstawiamy w rozdziale czwartym. Symulator stanowi uproszczony model rzeczywistego systemu transakcyjnego -- przyjęte uproszczenia omawiamy w tym samym rozdziale. Następny rozdział zawiera opis testowanych algorytmów i ich przewidywanego zachowania. W szóstym rozdziale omawiamy przeprowadzone testy i ich wyniki. Podsumowanie pracy znajduje sie w ostatnim rozdziale.



K. Kowalewski, R. Żmijewski
1999-12-17