Valid HTML 4.01!

Rozproszone systemy plików

Spis treści


Literatura


Wstęp

DFS (ang. Distributed File System) stanowi rozproszoną implementację klasycznego modelu systemu plików z podziałem czasu, w którym wielu użytkowników współdzieli pliki i zasoby pamięciowe.

DFS zarządza zbiorami rozproszonych urządzeń pamięci.


Nazewnictwo i przezroczystość:


Schematy tworzenia nazw


Semantyka współdzielenia pliku

Synchronizacja przy dostępnie do współdzielonego pliku jest prosta, gdy plik jest przechowywany na centralnym serwerze. Problemem jest jednak wydajność. Jeśli w celu poprawienia wydajności pozwala się klientom na tworzenie lokalnych kopii plików lub ich części, to pojawia się problem z zachowaniem standardowej uniksowej semantyki współdzielenia pliku.


Zdalny dostęp do plików


Porównanie obsługi zdalnej i pamięci podręcznej


Stanowy (ang. stateful) serwer plików


Bezstanowy (ang. stateless) serwer plików


Różnice między serwerem stanowym i bezstanowym


Tworzenie kopii pliku (ang. file replication)


Wprowadzenie do NFS

Produkt firmy Sun Microsystem wprowadzony do użytku w 1985 roku (wersja 2.0). Wersję 3.0 udostępniono w roku 1994. To ona właśnie będzie omawiana na wykładzie. Wersja ta jest obecnie intensywnie modyfikowana, nowa wersja 4.0 doczekała się już przykładowej implementacji, ale na razie na rynku nadal dominuje wersja 3.0.

Bardzo rozpowszechniony, standard w sieciach lokalnych.

Od początku firma Sun upowszechniła definicje podstawowych interfejsów oraz, na zasadzie licencji, kod źródłowy, dzięki czemu system jest teraz dostarczany przez wielu wytwórców.

Każdy komputer w sieci może działać zarówno jako klient, jak i sewer NFS. Często jednak rolę serwerów pełnią dedykowane maszyny.

System jest adaptowalny do różnych architektur i rozwiązań sprzętowych i do różnych systemów operacyjnych: prawie wszystkie aktualnie używane wersje systemu UNIX, Mach, DEC VMS, Novell Netware, MS-DOS i inne.

Cele projektowe systemu NFS i stopień ich urzeczywistnienia:

  1. Przezroczystość dostępu

    Interfejs klienta systemu NFS jest identyczny z interfejsem lokalnego systemu operacyjnego. Istniejące programy mogą bez żadnych zmian w kodzie działać na zdalnych plikach.

  2. Przezroczystość położenia

    Klient montuje zdalne pliki w lokalnej strukturze katalogów, określając tym samym sieciową przestrzeń nazw (można montować tylko pliki eksportowane z serwera). Decyzja o położeniu pliku w tej strukturze należy do klienta, może więc być różna w różnych systemach lokalnych (NFS nie wymusza jednolitej ogólnosieciowej przestrzeni nazw). Można osiągnąć przezroczystość położenia ustalając jednolitą przestrzeń nazw budowaną przez odpowiednie pliki konfiguracyjne u każdego klienta.

  3. Przezroczystość awarii

    Sewer NFS jest serwerem bezstanowym, a większość operacji to operacje idempotentne (powtarzalne). Dzięki temu sytuacje awaryjne w odniesieniu do plików zdalnych są postrzegane przez klienta jak awarie plików lokalnych (następuje czasowe zawieszenie usług). Awaria klienta nie ma wpływu na działanie żadnego serwera.

  4. Przezroczystość wydajności

    Buforowanie po stronie serwera (proste: standardowy mechanizm podręcznej pamięci buforowej) i po stronie klienta (złożone: buforowane bloki zdalnych plików i atrybuty plików). Moduły klienta i serwera są instalowane w jądrze systemu UNIX.

  5. Przezroczystość wędrówki

    W każdym kliencie działa proces odpowiedzialny za montowanie zdalnych plików w lokalnej przestrzeni nazw. Zwykle montowanie odbywa się podczas inicjalnego ładowania systemu. Można przenosić pliki między serwerami, ale trzeba wtedy oddzielnie uaktualniać tablice montowania u każdego klienta. Nie ma więc pełnej przezroczystości wędrówki.

    Można także stosować automontowanie, czyli montowanie na żądanie z dynamicznym wyborem serwera, na którym zlokalizowano jedną z kopii pliku z prawami tylko do czytania.

Nie zrealizowane wymagania:

  1. Przezroczystość zwielokrotniania

    NFS nie zapewnia zwielokrotniania plików. Oddzielnym zbiorem usług jest NIS (Network Information Service - kiedyś yellow pages), który umożliwia zwielokrotnianie baz danych odpowiadających standardowym plikom konfiguracyjnym systemu UNIX (jak /etc/hosts, /etc/services itp.)

  2. Przezroczystość współbieżności

    W systemie UNIX jest możliwe zakładanie blokad na pliki, w NFS-ie serwer jest bezstanowy, więc implementacja zakładania blokad jest trudna. W NFS wersji 4.0 wprowadzono możliwość zdalnego korzystania z pomocniczego zakładania blokad na poziomie rekordów (ang. advisory record-level locks).

  3. Skalowalność

    Ograniczona skalowalność. Liczba klientów jednocześnie korzystających z dzielonego pliku jest ograniczona wydajnością serwera dostarczającego plik (który może się stać wąskim gardłem). Wynika z braku zwielokrotniania.


Implementacja NFS (w systemie UNIX)

Architektura systemu NFS

Rysunek: Architektura systemu NFS (źródło: Brown, Distributed Programming)

Składowe systemu po stronie klienta:

  1. Proces klienta poziomu użytkownika
  2. Klient NFS. Działa w jądrze systemu
  3. Demon blokowych operacji wejścia-wyjścia biod (kilka instancji).

Składowe systemu po stronie serwera:

  1. Serwer NFS. Działa w jądrze systemu.
  2. Demon nfsd (kilka instancji).
  3. Demon montowania mountd (jedna instancja)

Protokół NFS działa w oparciu o RPC. Zlecenia klientów z poziomu użytkownika są tłumaczone na operacje protokołu NFS i przekazywane siecią do serwera.

Interfejs RPC dostarczany przez serwer NFS (fh=file handle=uchwyt pliku):


  lookup(dirfh, name) -> fh, attr  // odnajduje JEDNOCZŁONOWĄ nazwę
  create(dirfh, name, attr) -> newfh, attr
  remove(dirfh, name) -> status
  getattr(fh) -> attr
  read(fh, offset, count) -> attr, data
  write(fh, offset, count, data) -> attr
  . . . 

Jeśli klient posługuje się nazwą ścieżkową, to trzeba wykonać wiele zapytań lookup - dlaczego?

  1. analiza nazwy jest wykonywana po stronie klienta - dopuszczalne są więc schematy nazw pochodzące z różnych systemów
  2. ścieżka może obejmować kilka systemów plików, więc podczas analizy nazwy może dochodzić do przekraczania punktów zamontowania

Rysunek: Obsługa operacji read() (źródło: Brown, Distributed Programming)

Wynik każdego kroku tłumaczenia nazwy ścieżkowej jest przechowywany w pamięci podręcznej (po stronie klienta).


Wirtualny system plików

VFS

Rysunek: Wirtualny system plików (źródło: Brown, Distributed Programming)

Jest to zewnętrzna warstwa uniksowej implementacji systemu plików, pozwalająca na ujednolicenie dostępu do różnych systemów plików, w tym zdalnych.

Identyfikator pliku w systemie NFS nosi nazwę uchwytu pliku (ang. file handle) i składa się z:

  1. identyfikatora systemu plików,
  2. numeru i-węzła pliku,
  3. numeru generacji i-węzła - potrzebny ze względu na recyklowanie numerów i-węzłów po usunięciu pliku.

Każdemu plikowi odpowiada w VFS jeden v-węzeł. W przypadku pliku lokalnego zawiera on dowiązanie do i-węzła, a w przypadku pliku zdalnego - uchwyt tego pliku.


Klient

Moduł klienta emuluje dokładnie semantykę elementarnych operacji standardowego systemu plików UNIX i jest zintegrowany z jądrem systemu, dzięki czemu:

  1. programy użytkowników mają dostęp do plików systemu UNIX bez powtórnej kompilacji czy ładowania,
  2. wszystkie procesy z poziomu użytkownika korzystają z jednej dzielonej podręcznej pamięci buforowej zarówno przy dostępie zdalnym, jak i lokalnym,
  3. w jądrze jest przechowywany klucz szyfrowania używany do ochrony identyfikatorów użytkowników przekazywanych serwerowi.

Serwer

Moduł serwera systemu NFS jest zintegrowany z jądrem systemu operacyjnego ze względów wydajnościowych.


Kontrola dostępu i sprawdzanie tożsamości

Serwer jest bezstanowy, dlatego musi przy każdym żądaniu sprawdzać tożsamość użytkownika. Protokół RPC wymaga od klienta przesyłania informacji dotyczącej tożsamości. Dane te są porównywane z prawami dostępu do pliku.

Od NFS wersji 4.0 w protokole RPC można szyfrować informację o tożsamości użytkownika.


Montowanie

Montowaniem plików na zlecenie klienta zajmuje się demon mountd, wykonywany na poziomie użytkownika, po stronie serwera. Montowany plik musi być eksportowany po stronie serwera (eksportowane pliki są opisane w pliku /etc/exports).

(źródło: Tanenbaum, van Steen, Systemy rozproszone i paradygmaty)

Serwer NFS może sam zamontować u siebie katalogi wyeksportowane przez inne serwery. Nie może jednak eksportować tych zewnętrznych katalogów do swoich klientów. Oznacza to, że jeśli klient odwoła się do takiego punktu zamontowania na serwerze, to odczyta jego oryginalną zawartość, a nie korzeń zamontowanego w danym katalogu system plików.

(źródło: Tanenbaum, van Steen, Systemy rozproszone i paradygmaty)

Do montowania służy wersja standardowego uniksowego polecenie mount, w której podaje się nazwę zdalnego komputera, nazwę ścieżki zdalnego katalogu i nazwę lokalnego katalogu. Proces wykonujący polecenie mount komunikuje się z demonem mountd na zdalnym komputerze za pomocą protokołu zdalnego montowania i otrzymuje uchwyt katalogu głównego zdalnego systemu plików. Zwykle montowanie odbywa się podczas inicjalnego ładowania systemu, na podstawie skryptu /etc/rc.

Montowanie sztywne: jeśli zdalny komputer jest niedostępny, to moduł klienta ponawia zamówienie aż do skutku.

Montowanie miękkie: jeśli zdalny komputer jest niedostępny, to moduł klienta po kilku próbach wykonania operacji zgłasza błąd procesom z poziomu użytkownika.

Automonter to proces z poziomu użytkownika, który utrzymuje tablicę punktów zamontowania i z każdym kojarzy jeden lub więcej serwerów NFS. Zachowuje się jak lokalny serwer NFS w maszynie klienta. Otrzymawszy zamówienie lookup odnajduje potrzebny system plików w swojej tablicy i wysyła próbne zamówienie do każdego serwera. Zamontuje system plików serwera, który odpowie pierwszy. Zamontowany system plików jest łączony z punktem zamontowania za pomocą dowiązania symbolicznego. Po pewnym okresie nieaktywności demontuje zdalny system plików.

Pozwala to na pewne tolerowanie uszkodzeń i równoważenie obciążenia.


Pamięć podręczna serwera

Standardowo systemy uniksowe utrzymują w pamięci głównej podręczną pulę buforów wejścia-wyjścia (podręczna pamięć buforowa), zapewniają czytanie z wyprzedzeniem i opóźniony zapis. W ustalonych odstępach czasu (zwykle 30 sekund) wykonywana jest operacja sync, która odsyła zmienione bufory na dysk.

Serwery NFS korzystają z tej podręcznej pamięci buforowej na swojej maszynie lokalnej, z tym, że operacje pisania są realizowane natychmiast (ang. write-through) - awaria serwera mogłaby spowodować utratę danych niezauważalną po stronie klienta.


Pamięć podręczna klienta

Po stronie klienta są buforowane zarówno bloki danych (w podręcznej pamięci buforowej), jak i atrybuty (w r-węźle). Może to powodować kłopoty z utrzymaniem zgodności danych. Wykonanie po stronie klienta operacji pisania nie powoduje natychmiastowego uaktualnienia pozostałych kopii. Z blokami plików pamięta się czas ostatniej modyfikacji pliku na serwerze. Co jakiś czas klient prosi serwer o podanie czasu modyfikacji i w przypadku, gdy jest on nowszy, to unieważnia wszystkie przechowywane w pamięci podręcznej bloki pliku.

Sprawdzenie ważności wykonuje się przy każdym otwarciu pliku i kontakcie z serwerem w celu sprowadzenia nowego bloku pliku. Domyślnie zakłada się, że bloki zwykłych plików pozostają ważne przez 3 sekundy, bloki katalogów przez 30 sekund, a atrybuty przez 60 sekund (wartości ustalane podczas montowania zdalnego systemu plików).

Za czytanie z wyprzedzeniem i opóźnione pisanie odpowiada biodemon. Jest on powiadamiany o każdej operacji czytania i inicjuje czytanie następnego bloku. Operacje pisania powodują oznaczenie bloków jako brudnych i są kierowane asynchronicznie do wysłania do serwera. Dokładniej, stosuje się asynchroniczny zapis PEŁNYCH bloków i opóźniony zapis CZĘŚCIOWO wypełnionych bloków. Bloki katalogów są przesyłane po każdej modyfikacji.


Wydajność

NFS wymaga synchronicznego wykonania operacji zapisu po stronie serwera. Oznacza to zmiany zarówno atrybutów pliku, jak i jego treści. Wszelkie operacje zapisu są więc kosztowne.

Stosunkowo słabą wydajność operacji write można poprawić stosując po stronie serwera zasilaną z baterii nieulotną pamięć RAM (NVRAM - od ang. non-volatile RAM). Umieszcza się ją w jednostce sterującej dysku serwera. Serwer potwierdza więc operację pisania po wysłaniu danych na NVRAM, czyli szybciej.

Pobieranie atrybutów pliku wymaga jednego RPC na plik. Polecenia takie jak ls -l wykonane na katalogu mogą generować dużą liczbę żądań RPC.

Jeśli serwer nie odpowiada na żądanie wystarczająco szybko, to klient retransmituje komunikat. To jeszcze bardziej zmniejsza wydajność


Odstępstwa od uniksowej semantyki plików

Protokół NFS jest bezstanowy, a więc po stronie serwera nie przechowuje się informacji o otwartych plikach. Prowadzi to do kilku niezgodności z uniksową semantyką plików.

  1. Prawa dostępu do otwartego pliku

    W systemie UNIX prawa dostępu do pliku sprawdza się podczas otwierania pliku (NIE podczas operacji czytania/pisania). Załóżmy, że po otwarciu pliku do pisania, właściciel pliku zmieni prawa dostępu na tylko-do-czytania. W UNIX-ie użytkownik może kontynuować pisanie aż do momentu zamknięcia pliku. W NFS prawa do wykonania operacji sprawdza się przy każdym odczycie/zapisie.

  2. Usuwanie otwartych plików

    Jeśli proces usuwa plik otwarty przez inny proces, to jądro zaznacza plik do usunięcia i usuwa odpowiadającą mu pozycję z katalogu macierzystego. Żaden nowy proces nie może teraz otworzyć pliku, ale procesy, które zrobiły to wcześniej mogą z niego korzystać aż do zamknięcia. Dopiero gdy ostatni taki proces wykona close, system fizycznie usunie plik. Korzysta się z tego przy implementacji plików tymczasowych.

    W NFS próbuje się obejść problem modyfikując kod po stronie klienta. Gdy klient wykryje próbę usunięcia otwartego pliku, zmienia ją na rename (wybierając jakąś nietypową nazwę). Po zamknięciu pliku klient wykonuje remove.

    Rozwiązanie sprawdza się, gdy proces, który otworzył plik działa na tej samej maszynie co proces, który plik usuwa. Nie ma się jak chronić przed usuwaniem plików na innych klientach lub na serwerze.

  3. Żądania czytania i pisania

    W UNIX-ie operacja read i write powoduje założenie blokady na v-węzeł na początku operacji wejścia-wyjścia. Operacje te są więc atomowe. Jeśli w mniej więcej tym samym czasie zostaną zgłoszone dwie operacje pisania, to jądro wykona je po kolei, w pewnym porządku (najpierw jedną, a po jej zakończeniu drugą). Oznacza to, że plik NIE MOŻE się zmienić PODCZAS czytania.

    W przypadku pliku zdalnego jądro po stronie klienta szereguje współbieżne żądania dostępu do pliku pochodzące od dwóch procesów na tej samej maszynie. Jeśli jednak procesy wykonują się na różnych maszynach, to ich żądania trafiają do serwera niezależnie. Operacja read i write może przekładać się na KILKA żądań RPC (maksymalny rozmiar komunikatu wynosi 8K bajtów) i serwer nie zakłada blokad między żądaniami.


Janina Mincer-Daszkiewicz