Zalety:
Zalety:
Global File System to nowatorskie podejście do budowy systemów plików rozproszonych:
Global File System był projektowany jako system dla linuxowych klastrów. Różni się on od standardowych systemów plików rozproszonych. Główne cechy architekrury GFS:
Przewaga architektury GFS nad innymi istniejącymi systemami plików rozproszonych:
GFS to klastrowy rozproszony system plików. Pierwotnie, w przeciwieństwie do komercyjnych systemów plików, GFS skupiał się głównie na zwiększeniu wydajności działania klastra składającego się z relatywnie małej liczby węzłów. Miał zapewnić lepsze działanie aplikacji przeprowadzających skomplikowane obliczenia naukowe. Obecnie architektura GFS jest w pełni skalowalna i może być użyta w heterogenicznych systemach, których klienci korzystają z różnych systemów operacyjnych
Architektura GFS często używana jest w środowisku, w którym klient GFS może eksportować dane otrzymane za pomocą GFS do komputerów nie podłączonych do SAN. W tej sytuacji klient GFS zachowuje się jak serwer dla klienta korzystającego np: z protokołu HTTP
Tego typu sytuacja przedstawiona została na poniższym rysunku:
System NSP(Network Storage Pool) zapewnia każdej maszynie zunifikowaną przestrzeń adresową, za pomocą której klient ma dostęp do wszystkich urządzeń z danymi, podłączonych do sieci. Driver NSP dokonuje translacji logicznej przestrzeni adresowej widocznej przez klienta na przestrzeń adresową każdego urządzenia. Komendy
Global File System organizuje systemy plików w wiele tak zwanych "resource groups" (RG). Można je traktować jako małe systemy plików. Każda grupa zawiera informacje podobne do tych w tradycyjnych superblokach. Pojedynczy plik może znajdować się w wielu RG. Możliwe jest też przenoszenie plików do różnych
GFS korzysta ze struktury dinode, zajmującej cały blok w systemie plików. Każdy dinode składa się z sekcji informacji oraz sekcji danych. Jeśli rozmiar pliku jest większy niż rozmiar sekcji danych, dinode zawiera tablicę wskaźników do bloków danych lub bloków pośrednich. Drzewa metadanych Global File System różnią się od tradycyjnych unixowych struktur. Drzewo inodów UFS (Unix File Systems) zawiera liście położone na różnej wysokości w drzewie. GFS natomiast całą sekcję danych traktuje jako składającą się ze wskaźników pośrednich tego samego typu. Oznacza to, że drzewo inodów ma liście położone na tej samej wysokości. Tradycyjne rozwiązanie unixowe oraz to stosowane w Global File System przedstawione zostały na rysunkach poniżej.
Na pierwszym rysunku pokazano klasyczną strukturę UFS:
...A teraz drzewo inodów w Global File System:
Spadkobiercą GFS stał się GFS2 - rozproszony 64-bitowy symetryczny klastrowy system. W pierwszej kolejności jest on przeznaczony dla omówionej wcześniej sieci SAN, w której każdy węzeł ma taki sam dostęp do danych. GFS2 powstał na początku 2005 roku w wyniku prac nad dalszym rozwojem GFS. Jego autorem był Ken Preslan. Po długim czasie modyfikacji i przeglądania kodu, system został zaakceptowany w wersji jądra linuxa 2.6.16. Poniżej zaprezentowano kilka rozwiązań przyjętych w GFS2:
Powodów do stosowania systemów opartych na technologii GFS jest wiele. Oto kilka z nich:
Podczas projektowania systemu plików dla potrzeb Google, musiano brać pod uwagę wiele problemów, z którymi musiał on sobie sprawnie radzić. W systemie przyjęto następujące założenia:
GFS udostępnia powszechny interfejs systemu plików. Pliki przechowywane są hierarchicznie w katalogach i identyfikowane przez swoje ścieżki. System wspiera typowe operacje na plikach jak: create, delete, open, close, read i write.
Ponadto GFS posiada operację snapshot oraz record append. Pierwsza z nich tworzy niskim kosztem kopię pliku lub całego drzewa katalogów. Druga pozwala wielu klientom jednoczesne dodawanie danych do tego samego pliku zapewniając atomowość operacji każdego klienta.
Pojedynczy klaster GFS składa się z jednego serwera głównego, tzw. mastera, i kilkuset, lub kilku tysięcy tzw. chunk-serwerów (lub blok-serwerów), czyli komputerów, które właśnie przechowują pliki. W danej chwili z systemu może korzystać wielu klientów, żądając dostępu do plików.

Typowe pliki trzymane na GFS'ie mają rozmiar od 100 megabajtów do kilkunastu gigabajtów. Aby więc efektywnie zarządzać dostępnym miejscem, GFS trzyma dane w 64-megabajtowych częściach (ang. chunk), co można porównać do bloków na normalnym systemie plików. Dla porównania, typowy rozmiar bloku na Linuxie to 4 kilobajty. Aby przechowywać 128 megabajtowy plik, GFS używa więc dwóch bloków. Jednak z drugiej strony 1 megowy plik zużywa jeden 64 megabajtowy blok co powoduje, że większość jego pozostanie wolna, ale ponieważ tak małe pliki w GFS'ie są bardzo, bardzo rzadkie, inżynierowie Google nie muszą się martwić zmarnowanym miejscem.
Każda część pliku jest identyfikowana przez unikalny 64 bitowy uchwyt pliku (ang. chunk handle), który jest przypisywany przez serwer główny w momencie jej tworzenia. Chunk-serwery przechowują dane na swoich lokalnych dyskach twardych (jako pliki w systemie Linux). Aby zapewnić niezawodność systemu, każdy chunk trzymany jest na wielu chunk-serwerach. Standardowo tworzone są trzy kopie plików, ale możliwe jest zdefiniowanie własnego poziomu replikowania.
Serwer główny przechowuje jedynie metadane zawierające nazwy plików, ich rozmiar i położenie w klastrze. Serwer główny monitoruje również blok serwery, w Google mówią, że sprawdza czy bije im serce (robi to za pomocą specjalnych instrukcji HeartBeat). W przypadku, gdy jeden z komputerów przestanie odpowiadać wówczas jest zgłaszany jako uszkodzony. Jest odpowiedzialny również, za zarządzanie osieroconymi fragmentami plików i migracją danych pomiędzy chunk-serwerami.
W momencie kiedy aplikacja próbuje odczytać dany plik, główny serwer zwraca jej dokładne adresy komputerów go przechowujących. Pomiędzy serwerem a klientami wysyłane są tylko metadane. Następnie aplikacja komunikuje się bezpośrednio z chunk-serwerem.
Chunk-serwery i klienci nie używają dodatkowej pamięci podręcznej cache do przechowywania danych z plików. Po stronie klienta zysk byłby niewielki, ponieważ większość aplikacji korzysta z danych które są zbyt duże żeby mogły zostać zapamiętane w pamięci cache (przechowywane są tylko metadane). Chunk-serwery nie potrzebują dodatkowego cachowania z uwagi na to, że korzystają ze swoich lokalnych dysków twardych, więc zwykłe buforowanie plików w Linuxie utrzymuje odpowiednie dane w pamięci.
Posiadanie głównego serwera ogromnie upraszcza projekt i umożliwia podejmowanie przez niego wielu decyzji związanych z zarządzaniem plikami przy wykorzystaniu globalnej wiedzy o systemie. Jednocześnie dostarcza problemów z minimalizowaniem jego udziału w operacjach zapisu i odczytu plików, aby serwer główny nie stał się wąskim gardłem całego systemu. Serwer nigdy bezpośrednio nie udostępnia danych. Klienci odpytują serwer, dostając informacje, z którym chunk-serwerem muszą się skomunikować. Metadane, które otrzymują są przez nich cachowane w celu ograniczenia połączeń z serwerem.
Komunikacja z serwerem jest przedstawiona na poprzednim rysunku. Na początku, korzystając z ustalonego rozmiaru chunk'a oraz offsetu, klient oblicza numer części pliku, który jest mu potrzebny (chunk index). Następnie odpytuje serwer główny, podając mu nazwę pliku i chunk index. Master przekazuje uchwyt do pliku (chunk handle) wraz z położeniem jego wszystkich kopii. Klient buforuje tą informację wykorzystując nazwę pliku i chunk index jako klucz. W kolejnym kroku, aplikacja wysyła żądanie jednej kopii fragmentu pliku (domyślnie najbliższej). Żądanie to zawiera uchwyt do pliku i przedział adresów z chunk'a. Późniejsze odczyty z tej części pliku nie wymagają już komunikacji klient - serwer (do momentu, gdy dane w buforze nie wygasną lub plik zostanie otwarty ponownie).
Wybór odpowiedniego rozmiaru chunk'a jest jedną z kluczowych decyzji w systemie. W przypadku GFS'a inżynierowie podjęli decyzję, ustalając jego rozmiar na 64MB, co jest dużo większe niż rozmiar bloku w typowym systemie plików. Opóźniona alokacja przestrzeni dyskowej pozwala unikać wewnętrznej fragmentacji plików.
Duży rozmiar chunk'a ma wiele zalet. Przede wszystkim pozwala zredukować liczbę niezbędnych interakcji z serwerem. Jest wielce prawdopodobne, że aplikacja kliencka będzie wykonywać wiele operacji na tym samym fragmencie pliku. Pozwala to zmniejszyć koszt utrzymywania ciągłego połączenia z chunk-serwerem. Kolejnym powodem jest zmniejszenie metadanych przechowywanych na serwerze (co pozwala na utrzymywanie ich w pamięci i przynosi dodatkowe korzyści).
Z drugiej strony, duży rozmiar bloku może spowodować w przypadku małych plików (np. mniejszych niż rozmiar chunk'a) duże obciążenie chunk-serwerów.
Projektując system brano pod uwagę minimalizowanie wpływu serwera głównego na wszystkie operacje w systemie.
Podczas działania systemu spotykamy się z operacjami, które modyfikują zawartość lub metadane dotyczące pliku, a właściwie konkretnego chunk'a (np. write, append). Każda taka zmiana musi zostać uwzględniona we wszystkich kopiach chunk'a. W GFS'ie odbywa się to za pomocą szeregowego przesyłania danych pomiędzy chunk-serwerami. Master wyznacza jeden z chunk-serwerów i oznacza go jako primary. Z tym serwerem komunikuje się klient i on jako pierwszy zapisze zmodyfikowaną wersję chunk'a. Pozostałe chunk-serwery otrzymują od serwera wyznaczonego jako primary polecenie zapisu nowej kopii tego chunk'a.
Prześledźmy teraz dokładnie proces komunikacji pomiędzy serwerami:

Dla przykładu, przesłanie 1MB danych do wszystkich kopii trwa około 80 ms.
GFS udostępnia atomową operację dopisywania do pliku (record append). W tradycyjnym zapisie klient specyfikuje offset, pod ktorym mają zostać zapisane dane. W przypadku dopisywania, klient podaje jedynie dane, które chce zapisać. GFS dopisuje je atomowo jako jeden sekwencyjny zapis danych pod offsetem, który jest wybierany przez system i zwracany klientowi. Operacja ta jest podobna to operacji zapisu do pliku otwartego z opcją O_APPEND w systemie Unix.
Przebieg operacji record append jest podobny do opisanego wcześniej procesu zapisu do pliku. Klient wysyła dane do wszystkich chunk-serwerów posiadających ostatnią część pliku. Następnie wysyła żądanie do serwera primary. Serwer ten sprawdza czy zapis do tego chunk'a może spowodować, że jego rozmiar przekroczy ograniczenie (64MB). W takim przypadku, bieżący chunk jest uzupełniany do maksymalnego rozmiaru i primary wysyła żądanie do pozostałych serwerów, aby postąpili tak samo. Następnie klient jest informowany, że musi ponowić zapis do pliku (do kolejnego chunk'a). Jeśli rekord, który ma zostać zapisany, mieści się w bieżącym chunk'u dane są zapisywane i postępowanie jest identyczne jak w przypadku zwykłego zapisu.
Operacja snapshot tworzy kopię pliku lub całego drzewa katalogów. Użytkownik, może szybko utworzyć nową gałąź będącą kopią ogromnego zbioru danych. Tworzenie ich, umożliwia szybkie przywrócenie wszystkich plików do zapisanego stanu. Kiedy master odbiera żądanie wykonania snapshot'a, wycofuje wszystkie oczekujące operacje korzystające z chunk'ów, które mamy skopiować. To wymusza na klientach, którzy chcą je zmodyfikować ponowną komunikację z masterem i daje mu możliwość wcześniejszego skopiowania danych. Na początku kopiowane są metadane dotyczące tych chunk'ów.
W momencie kiedy klient chce zapisać jakieś dane do pewnego chunk'a po wykonaniu snpashot'a wysyła żądanie do mastera. Serwer główny zauważa, że liczba referencji do tego chunk'a jest większa niż jeden i opóźnia odpowiedź klientowi. W tym czasie, serwer wysyła polecenie utworzenia kopii do wszystkich chunk-serwerów posiadających kopię chunk'a. Dopiero teraz klient otrzymuję odpowiedź.
Serwer główny wykonuje wiele operację związanych z zarządzaniem metadanymi, podejmuję decyzję o położeniu chunk'ów, tworzy je oraz koordynuje cały system, dba o spójność danych i wydajność systemu. W tej części bardziej szczegółowo zostaną omówione niektóre z czynności mastera.
Wiele operacji serwera zabiera dużo czasu (np. snapshot). Dlatego postanowiono umożliwić mu wykonywanie wielu operacji w tym samym czasie. Wymagało to założenia blokad.
Każda operacja mastera wymaga założenia pewnych blokad na drzewie katalogów. Jeśli chcemy mieć dostęp do danych o pliku /d1/d2/.../dn/leaf, muszą zostać założone blokady czytelników na katalogi /d1, /d1/d2, ..., /d1/d2/.../dn i następnie blokada pisarza lub czytelnika na całą ścieżkę /d1/d2/.../dn/leaf.
Przeanalizujmy przykładowy scenariusz. Chcemy utworzyć plik /home/user/foo podczas wykonywanej operacji snapshot katalogu /home/user do katalogu /save/user. Operacja snapshot wymaga założenia blokad czytelników na katalogi /home i /save oraz blokad pisarzy na /home/user i /save/user. Natomiast operacja tworzenia pliku będzie wymagała założenia blokady czytelników na /home i /home/user i blokady pisarza na /home/user/foo.
Po usunięciu pliku, GFS nie zwalnia natychmiast zasobów, które on zajmował. Czynność ta zostaje opóźniona i co pewien czas master zajmuje się odśmiecaniem danych, które on przechowuje i chunk-serwerów.
Kopie chunk'ów mogą stać się nieaktualne np. w przypadku nieudanego zapisu (nie wszystkie chunk-serwery zakończyły operację sukcesem). Wszystkie zmiany w plikach są wersjonowane, co umożliwia wykrycie nieaktualnego fragmentu pliku i zaktualizowanie go.
Przeanalizujmy wyniki kilku testów systemu GFS, żeby zilustrować problemy z jakimi borykają się inżynierowie w Google.
Badania zostały przeprowadzone na klastrze GFS złożonym z jednego mastera, dwóch jego kopii, 16 chunk-serwerów i 16 klientów. Jest to bardzo uproszczony klaster stworzony specjalnie dla testów. W rzeczywistości składa się on z wielu tysięcy chunk-serwerów i klientów.
Każda z maszyn posiada podwójny procesor PIII 1.4 GHz, 2GB pamięci, dwa dyski twarde 80GB 5400 rpm i karty sieciowej 100 Mbps (full-duplex). Sieć została zbudowana za pomocą switchy HP 2524. 19 maszyn serwerowych jest podłączona do jednego switcha, a do drugiego 16 maszyn klienckich. Switche połączone są za pomocą łącza o przepustowości 1Gbps.

Poprzednie testy były przeprowadzona na bardzo uproszczonym klastrze GFS'a. W Google działają klastry o następujących parametrach:

Transfery jakie uzyskano w powyższych konfiguracjach kształtują się następująco:

Inżynierowie z Google przeprowadzili eksperyment polegający na odłączeniu jednego chunk-serwera z klastra B, który przechowywał około 15000 chunk'ów (600GB danych). Wszystkie fragmenty zostały odzyskane w ciągu 23 minut.
The Google File System demonstruje jak za pomocą zwykłych komputerów PC uzyskać wydajność superkomputera, który potrafi sprawnie obsługiwać ogromne ilości danych. GFS jest cały czas rozwijany i usprawniany. Z wielkim sukcesem znalazł zastosowanie w Google i rozwiązał wszystkie stawiane przed nim problemy.