Podstawy ZFS: pamięć masowa i wydajność

Podstawy ZFS: pamięć masowa i wydajność

Tej wiosny omówiliśmy już kilka tematów wprowadzających, na przykład jak sprawdzić prędkość dysków и co to jest RAID. W drugim z nich obiecaliśmy nawet kontynuować badanie wydajności różnych topologii wielodyskowych w ZFS. Jest to system plików nowej generacji, który jest obecnie wdrażany wszędzie: od Apple do Ubuntu.

Cóż, dzisiaj jest najlepszy dzień na zapoznanie się z ZFS, dociekliwych czytelników. Po prostu wiedz, że w skromnej opinii programisty OpenZFS, Matta Ahrensa, „to naprawdę trudne”.

Ale zanim przejdziemy do liczb – i obiecuję, że dla wszystkich opcji ośmiodyskowej konfiguracji ZFS, musimy porozmawiać o jak Ogólnie rzecz biorąc, ZFS przechowuje dane na dysku.

Zpool, vdev i urządzenie

Podstawy ZFS: pamięć masowa i wydajność
Ten pełny diagram puli obejmuje trzy pomocnicze vdev, po jednym z każdej klasy i cztery dla RAIDz2

Podstawy ZFS: pamięć masowa i wydajność
Zwykle nie ma powodu, aby tworzyć pulę niedopasowanych typów i rozmiarów vdev - ale nic nie stoi na przeszkodzie, aby to zrobić, jeśli chcesz.

Aby naprawdę zrozumieć system plików ZFS, musisz przyjrzeć się jego rzeczywistej strukturze. Po pierwsze, ZFS łączy tradycyjne poziomy zarządzania woluminami i systemem plików. Po drugie, wykorzystuje transakcyjny mechanizm kopiowania przy zapisie. Te cechy oznaczają, że system jest strukturalnie bardzo różny od konwencjonalnych systemów plików i macierzy RAID. Pierwszym zestawem podstawowych bloków konstrukcyjnych do zrozumienia jest pula pamięci masowej (zpool), urządzenie wirtualne (vdev) i urządzenie rzeczywiste (device).

zpool

Pula pamięci zpool jest najwyższą strukturą ZFS. Każda pula zawiera jedno lub więcej urządzeń wirtualnych. Z kolei każde z nich zawiera jedno lub więcej rzeczywistych urządzeń (urządzeń). Pule wirtualne to samodzielne bloki. Jeden komputer fizyczny może zawierać dwie lub więcej oddzielnych pul, ale każda z nich jest całkowicie niezależna od pozostałych. Pule nie mogą udostępniać urządzeń wirtualnych.

Nadmiarowość ZFS jest na poziomie urządzenia wirtualnego, a nie na poziomie puli. Nie ma absolutnie żadnej redundancji na poziomie puli - jeśli jakikolwiek dysk vdev lub specjalny vdev zostanie utracony, cała pula zostanie utracona wraz z nim.

Nowoczesne pule pamięci masowej mogą przetrwać utratę pamięci podręcznej lub dziennika urządzenia wirtualnego — chociaż mogą utracić niewielką ilość brudnych danych, jeśli utracą dziennik vdev podczas przerwy w dostawie prądu lub awarii systemu.

Istnieje powszechne błędne przekonanie, że „paski danych” ZFS są zapisywane w całej puli. To nie jest prawda. Zpool wcale nie jest zabawny RAID0, jest raczej zabawny JBOD ze złożonym mechanizmem dystrybucji zmiennych.

W większości rekordy są rozdzielane między dostępne urządzenia wirtualne zgodnie z dostępną wolną przestrzenią, więc teoretycznie wszystkie zostaną wypełnione w tym samym czasie. W późniejszych wersjach ZFS brane jest pod uwagę bieżące użycie (wykorzystanie) vdev - jeśli jedno urządzenie wirtualne jest znacznie bardziej obciążone niż inne (na przykład z powodu obciążenia odczytu), zostanie ono tymczasowo pominięte do zapisu, pomimo posiadania najwyższego wolnego współczynnik przestrzeni.

Mechanizm wykrywania wykorzystania wbudowany w nowoczesne metody alokacji zapisu ZFS może zmniejszyć opóźnienia i zwiększyć przepustowość w okresach niezwykle wysokiego obciążenia - ale tak nie jest wolna karta na mimowolnym mieszaniu wolnych dysków twardych i szybkich dysków SSD w jednej puli. Taka nierówna pula będzie nadal działać z prędkością najwolniejszego urządzenia, czyli tak, jakby była w całości złożona z takich urządzeń.

wdew

Każda pula pamięci składa się z co najmniej jednego urządzenia wirtualnego (urządzenie wirtualne, vdev). Z kolei każdy vdev zawiera jedno lub więcej rzeczywistych urządzeń. Większość urządzeń wirtualnych jest używana do prostego przechowywania danych, ale istnieje kilka klas pomocniczych vdev, w tym CACHE, LOG i SPECIAL. Każdy z tych typów vdev może mieć jedną z pięciu topologii: pojedyncze urządzenie (single-device), RAIDz1, RAIDz2, RAIDz3 lub mirror (mirror).

RAIDz1, RAIDz2 i RAIDz3 to specjalne odmiany tego, co weterani nazwaliby RAID z podwójną (diagonalną) parzystością. 1, 2 i 3 odnoszą się do liczby bloków parzystości przydzielonych dla każdego paska danych. Zamiast oddzielnych dysków dla parzystości, urządzenia wirtualne RAIDz rozdzielają tę parzystość na pół równomiernie na dyskach. Macierz RAIDz może stracić tyle dysków, ile ma bloków parzystości; jeśli straci kolejną, ulegnie awarii i zabierze ze sobą pulę pamięci.

W lustrzanych urządzeniach wirtualnych (mirror vdev) każdy blok jest przechowywany na każdym urządzeniu w vdev. Chociaż najpopularniejsze są lustra dwuszerokie, w jednym lustrze może znajdować się dowolna liczba urządzeń — w dużych instalacjach często stosuje się lustra potrójne, aby poprawić wydajność odczytu i odporność na błędy. Serwer lustrzany vdev może przetrwać każdą awarię, o ile przynajmniej jedno urządzenie w vdev nadal działa.

Pojedyncze vdevy są z natury niebezpieczne. Takie urządzenie wirtualne nie przetrwa ani jednej awarii - a jeśli zostanie użyte jako magazyn lub specjalny vdev, to jego awaria doprowadzi do zniszczenia całej puli. Bądź tutaj bardzo, bardzo ostrożny.

CACHE, LOG i SPECIAL VA mogą być tworzone przy użyciu dowolnej z powyższych topologii – ale pamiętaj, że utrata SPECJALNEGO VA oznacza utratę puli, dlatego wysoce zalecana jest nadmiarowa topologia.

urządzenie

Jest to prawdopodobnie najłatwiejszy do zrozumienia termin w ZFS - to dosłownie blokowe urządzenie o swobodnym dostępie. Pamiętaj, że urządzenia wirtualne składają się z pojedynczych urządzeń, podczas gdy pula składa się z urządzeń wirtualnych.

Dyski - magnetyczne lub półprzewodnikowe - to najpowszechniejsze urządzenia blokowe, które są używane jako elementy składowe vdev. Jednak każde urządzenie z deskryptorem w /dev wystarczy, więc całe sprzętowe macierze RAID mogą być używane jako oddzielne urządzenia.

Prosty plik raw jest jednym z najważniejszych alternatywnych urządzeń blokowych, z których można zbudować vdev. Pule testowe z rzadkie pliki to bardzo wygodny sposób sprawdzania poleceń puli i sprawdzania, ile miejsca jest dostępne w puli lub urządzeniu wirtualnym o danej topologii.

Podstawy ZFS: pamięć masowa i wydajność
Możesz utworzyć pulę testową z rzadkich plików w zaledwie kilka sekund - ale nie zapomnij później usunąć całej puli i jej komponentów

Powiedzmy, że chcesz postawić serwer na ośmiu dyskach i planujesz używać dysków 10 TB (~9300 GiB) - ale nie jesteś pewien, która topologia najlepiej odpowiada Twoim potrzebom. W powyższym przykładzie budujemy pulę testową z plików rozrzedzonych w ciągu kilku sekund — i teraz wiemy, że vdev RAIDz2 składający się z ośmiu dysków 10 TB zapewnia 50 TiB użytecznej pojemności.

Kolejną specjalną klasą urządzeń jest SPARE (zapas). Urządzenia wymieniane podczas pracy, w przeciwieństwie do zwykłych urządzeń, należą do całej puli, a nie do pojedynczego urządzenia wirtualnego. Jeśli vdev w puli ulegnie awarii, a urządzenie zapasowe jest podłączone do puli i jest dostępne, automatycznie dołączy do vdev, którego dotyczy problem.

Po połączeniu się z vdev, którego dotyczy problem, zapasowe urządzenie zaczyna otrzymywać kopie lub rekonstrukcje danych, które powinny znajdować się na brakującym urządzeniu. W tradycyjnym RAID nazywa się to odbudową, podczas gdy w ZFS nazywa się to resilveringiem.

Należy pamiętać, że urządzenia zapasowe nie zastępują na stałe urządzeń uszkodzonych. Jest to tylko tymczasowa wymiana mająca na celu skrócenie czasu degradacji vdev. Gdy administrator wymieni uszkodzony vdev, redundancja zostanie przywrócona na tym stałym urządzeniu, a SPARE zostanie odłączony od vdev i przywrócony do pracy jako zapasowy dla całej puli.

Zbiory danych, bloki i sektory

Następny zestaw bloków konstrukcyjnych do zrozumienia w naszej podróży ZFS dotyczy mniej sprzętu, a więcej tego, jak same dane są zorganizowane i przechowywane. Pomijamy tutaj kilka poziomów – takich jak metaslab – aby nie zaśmiecać szczegółów, jednocześnie zachowując zrozumienie ogólnej struktury.

Zbiór danych (zbiór danych)

Podstawy ZFS: pamięć masowa i wydajność
Kiedy po raz pierwszy tworzymy zestaw danych, pokazuje on całą dostępną przestrzeń w puli. Następnie ustalamy limit - i zmieniamy punkt montowania. Magia!

Podstawy ZFS: pamięć masowa i wydajność
Zvol jest w większości tylko zbiorem danych pozbawionym warstwy systemu plików, którą tutaj zastępujemy zupełnie normalnym systemem plików ext4.

Zestaw danych ZFS jest mniej więcej taki sam, jak standardowy montowany system plików. Podobnie jak zwykły system plików, na pierwszy rzut oka wygląda jak „tylko kolejny folder”. Ale podobnie jak zwykłe montowalne systemy plików, każdy zestaw danych ZFS ma swój własny zestaw podstawowych właściwości.

Po pierwsze, zestaw danych może mieć przypisany limit. Jeśli ustawione zfs set quota=100G poolname/datasetname, wtedy nie będziesz mógł pisać do zamontowanego folderu /poolname/datasetname ponad 100 GiB.

Zauważ obecność - i brak - ukośników na początku każdej linii? Każdy zestaw danych ma swoje miejsce zarówno w hierarchii ZFS, jak i hierarchii montowania systemu. W hierarchii ZFS nie ma wiodącego ukośnika — zaczynasz od nazwy puli, a następnie ścieżki z jednego zestawu danych do następnego. Na przykład, pool/parent/child dla zestawu danych o nazwie child pod nadrzędnym zbiorem danych parent w puli o kreatywnej nazwie pool.

Domyślnie punkt montowania zestawu danych będzie odpowiednikiem jego nazwy w hierarchii ZFS, z wiodącym ukośnikiem - nazwa puli pool zamontowana jako /pool, zestaw danych parent zamontowany w /pool/parenti podrzędny zestaw danych child zamontowany w /pool/parent/child. Można jednak zmienić punkt instalacji zestawu danych w systemie.

Jeśli określimy zfs set mountpoint=/lol pool/parent/child, a następnie zestaw danych pool/parent/child zamontowany w systemie jako /lol.

Oprócz zbiorów danych należy wspomnieć o woluminach (zvols). Wolumin jest mniej więcej taki sam jak zestaw danych, z tą różnicą, że w rzeczywistości nie ma systemu plików — to tylko urządzenie blokowe. Możesz na przykład stworzyć zvol Z imieniem mypool/myzvol, następnie sformatuj go za pomocą systemu plików ext4, a następnie zamontuj ten system plików - masz teraz system plików ext4, ale ze wszystkimi funkcjami bezpieczeństwa ZFS! Może się to wydawać głupie na pojedynczym komputerze, ale ma o wiele większy sens jako backend podczas eksportowania urządzenia iSCSI.

bloki

Podstawy ZFS: pamięć masowa i wydajność
Plik jest reprezentowany przez jeden lub więcej bloków. Każdy blok jest przechowywany na jednym urządzeniu wirtualnym. Rozmiar bloku jest zwykle równy parametrowi rozmiar rekordu, ale można go zredukować do 2^zmianajeśli zawiera metadane lub mały plik.

Podstawy ZFS: pamięć masowa i wydajność
My naprawdę naprawdę nie żartuję na temat ogromnej utraty wydajności, jeśli ustawisz zbyt małe przesunięcie

W puli ZFS wszystkie dane, w tym metadane, są przechowywane w blokach. Maksymalny rozmiar bloku dla każdego zestawu danych jest zdefiniowany we właściwości recordsize (rekordowy rozmiar). Rozmiar rekordu można zmienić, ale nie spowoduje to zmiany rozmiaru ani lokalizacji żadnych bloków, które zostały już zapisane w zbiorze danych — ma to wpływ tylko na nowe bloki w miarę ich zapisywania.

O ile nie określono inaczej, bieżący domyślny rozmiar rekordu to 128 KiB. Jest to rodzaj trudnego kompromisu, w którym wydajność nie jest idealna, ale w większości przypadków nie jest też straszna. Recordsize można ustawić na dowolną wartość od 4K do 1M (przy zaawansowanych ustawieniach recordsize można zainstalować jeszcze więcej, ale rzadko jest to dobry pomysł).

Każdy blok odnosi się do danych tylko jednego pliku - nie można upchnąć dwóch różnych plików w jednym bloku. Każdy plik składa się z jednego lub więcej bloków, w zależności od rozmiaru. Jeśli rozmiar pliku jest mniejszy niż rozmiar rekordu, zostanie on zapisany w mniejszym bloku - na przykład blok z plikiem 2 KiB zajmie tylko jeden sektor 4 KiB na dysku.

Jeśli plik jest wystarczająco duży i wymaga kilku bloków, wszystkie rekordy z tym plikiem będą miały rozmiar recordsize - w tym ostatni wpis, którego główna część może być niewykorzystane miejsce.

zvols nie mają właściwości recordsize — zamiast tego mają równoważną właściwość volblocksize.

Sektory

Ostatnim, najbardziej podstawowym budulcem jest sektor. Jest to najmniejsza jednostka fizyczna, którą można zapisać lub odczytać z urządzenia podstawowego. Przez kilka dziesięcioleci większość dysków korzystała z sektorów 512-bajtowych. Ostatnio większość dysków jest skonfigurowana na sektory 4 KiB, a niektóre - zwłaszcza dyski SSD - mają sektory 8 KiB lub nawet więcej.

System ZFS ma właściwość, która pozwala ręcznie ustawić rozmiar sektora. Ta nieruchomość ashift. Nieco mylące, ashift jest potęgą dwójki. Na przykład, ashift=9 oznacza rozmiar sektora 2^9 lub 512 bajtów.

ZFS wysyła zapytanie do systemu operacyjnego o szczegółowe informacje o każdym urządzeniu blokowym, gdy jest ono dodawane do nowego vdev, i teoretycznie automatycznie instaluje odpowiednio ashift na podstawie tych informacji. Niestety, wiele dysków kłamie na temat rozmiaru sektora, aby zachować zgodność z systemem Windows XP (który nie był w stanie zrozumieć dysków z innymi rozmiarami sektorów).

Oznacza to, że zdecydowanie zaleca się, aby administrator ZFS znał rzeczywisty rozmiar sektora swoich urządzeń i ręcznie go ustawiał ashift. Jeśli ashift jest ustawiony zbyt nisko, liczba operacji odczytu/zapisu wzrasta astronomicznie. Tak więc zapisanie 512-bajtowych „sektorów” do rzeczywistego sektora 4 KiB oznacza konieczność zapisania pierwszego „sektora”, następnie odczytania sektora 4 KiB, zmodyfikowania go drugim „sektorem” 512 bajtów, zapisania go z powrotem do nowego Sektor 4 KiB itd. dla każdego wpisu.

W realnym świecie taka kara uderza w dyski SSD Samsunga EVO, za co ashift=13, ale te dyski SSD kłamią na temat rozmiaru sektora, dlatego ustawieniem domyślnym jest ashift=9. Jeśli doświadczony administrator systemu nie zmieni tego ustawienia, to ten dysk SSD działa wolniej konwencjonalny magnetyczny dysk twardy.

Dla porównania za duży rozmiar ashift praktycznie nie ma kary. Nie ma rzeczywistego spadku wydajności, a wzrost niewykorzystanej przestrzeni jest nieskończenie mały (lub zerowy przy włączonej kompresji). Dlatego zdecydowanie zalecamy zainstalowanie nawet tych dysków, które używają sektorów 512-bajtowych ashift=12 lub ashift=13z ufnością patrzeć w przyszłość.

Właściwość ashift jest ustawiany dla każdego urządzenia wirtualnego vdev i nie na basen, jak wielu błędnie myśli - i nie zmienia się po instalacji. Jeśli przypadkowo trafisz ashift kiedy dodajesz nowy vdev do puli, nieodwracalnie zanieczyszczasz tę pulę urządzeniem o niskiej wydajności i zwykle nie ma innego wyjścia, jak tylko zniszczyć pulę i zacząć od nowa. Nawet usunięcie vdev nie uchroni cię przed zepsutą konfiguracją ashift!

Mechanizm kopiowania przy zapisie

Podstawy ZFS: pamięć masowa i wydajność
Jeśli zwykły system plików musi nadpisać dane, zmienia każdy blok tam, gdzie się znajduje

Podstawy ZFS: pamięć masowa i wydajność
System plików kopiowania przy zapisie zapisuje nową wersję bloku, a następnie odblokowuje starą wersję

Podstawy ZFS: pamięć masowa i wydajność
Podsumowując, jeśli zignorujemy faktyczną fizyczną lokalizację bloków, wówczas nasza „kometa danych” zostanie uproszczona do „robaka danych”, który porusza się od lewej do prawej po mapie dostępnej przestrzeni

Podstawy ZFS: pamięć masowa i wydajność
Teraz możemy dobrze zrozumieć, jak działają migawki kopiowania przy zapisie — każdy blok może należeć do wielu migawek i będzie trwał, dopóki wszystkie powiązane migawki nie zostaną zniszczone

Mechanizm kopiowania przy zapisie (CoW) jest podstawową podstawą tego, co sprawia, że ​​ZFS jest tak niesamowitym systemem. Podstawowa koncepcja jest prosta — jeśli poprosisz tradycyjny system plików o zmianę pliku, zrobi dokładnie to, o co prosiłeś. Jeśli poprosisz system plików kopiowania przy zapisie, aby zrobił to samo, powie „ok”, ale cię okłamie.

Zamiast tego system plików kopiowania przy zapisie zapisuje nową wersję zmodyfikowanego bloku, a następnie aktualizuje metadane pliku, aby odłączyć stary blok i powiązać z nim nowy blok, który właśnie napisałeś.

Odłączenie starego bloku i połączenie nowego odbywa się w jednej operacji, więc nie można jej przerwać - jeśli wyłączysz po tym, masz nową wersję pliku, a jeśli wyłączysz wcześniej, masz starą wersję . W każdym razie nie będzie żadnych konfliktów w systemie plików.

Kopiowanie przy zapisie w ZFS występuje nie tylko na poziomie systemu plików, ale także na poziomie zarządzania dyskami. Oznacza to, że białe znaki nie mają wpływu na ZFS (dziura w RAID) - zjawisko, gdy taśma zdążyła tylko częściowo nagrać przed awarią systemu, z uszkodzeniem macierzy po restarcie. Tutaj pasek jest zapisany atomowo, vdev jest zawsze sekwencyjny i Bob jest twoim wujkiem.

ZIL: Dziennik intencji ZFS

Podstawy ZFS: pamięć masowa i wydajność
System ZFS traktuje zapisy synchroniczne w szczególny sposób - tymczasowo, ale natychmiastowo, przechowuje je w ZIL, zanim później zapisze je na stałe wraz z zapisami asynchronicznymi.

Podstawy ZFS: pamięć masowa i wydajność
Zazwyczaj dane zapisane w ZIL nigdy nie są ponownie odczytywane. Ale jest to możliwe po awarii systemu

Podstawy ZFS: pamięć masowa i wydajność
SLOG, czyli drugorzędne urządzenie LOG, to po prostu specjalny – i najlepiej bardzo szybki – vdev, gdzie ZIL może być przechowywany oddzielnie od pamięci głównej

Podstawy ZFS: pamięć masowa i wydajność
Po awarii wszystkie brudne dane w ZIL są odtwarzane - w tym przypadku ZIL jest na SLOGu, więc jest odtwarzany stamtąd

Istnieją dwie główne kategorie operacji zapisu — synchroniczne (sync) i asynchroniczne (async). W przypadku większości obciążeń zdecydowana większość zapisów jest asynchroniczna — system plików umożliwia ich agregację i wydawanie w partiach, zmniejszając fragmentację i znacznie zwiększając przepustowość.

Zsynchronizowane nagrania to zupełnie inna sprawa. Gdy aplikacja żąda zapisu synchronicznego, informuje system plików: „Musisz zatwierdzić to do pamięci nieulotnej terazdo tego czasu nic więcej nie mogę zrobić”. Dlatego zapisy synchroniczne powinny być natychmiast zapisywane na dysku — a jeśli zwiększa to fragmentację lub zmniejsza przepustowość, niech tak będzie.

ZFS obsługuje zapisy synchroniczne inaczej niż zwykłe systemy plików — zamiast natychmiastowego umieszczania ich w zwykłym magazynie, ZFS umieszcza je w specjalnym obszarze przechowywania zwanym ZFS Intent Log lub ZIL. Sztuczka polega na tym, że te zapisy również pozostają w pamięci, są agregowane wraz z normalnymi asynchronicznymi żądaniami zapisu, aby później zostać opróżnione do pamięci jako całkowicie normalne TXG (grupy transakcji).

Podczas normalnej pracy ZIL jest zapisywany i nigdy więcej nie odczytywany. Gdy po kilku chwilach rekordy z ZIL-a zostaną przeniesione do pamięci głównej w zwykłych TXG z RAM-u, są one odłączane od ZIL-a. Jedynym momentem, w którym coś jest odczytywane z ZIL, jest import puli.

Jeśli ZFS zawiedzie - awaria systemu operacyjnego lub przerwa w dostawie prądu - podczas gdy w ZIL znajdują się dane, dane te zostaną odczytane podczas następnego importu puli (na przykład po ponownym uruchomieniu systemu awaryjnego). Wszystko w ZIL zostanie odczytane, pogrupowane w TXG, przekazane do pamięci głównej, a następnie odłączone od ZIL podczas procesu importu.

Jedna z klas pomocniczych vdev nazywa się LOG lub SLOG i jest drugorzędnym urządzeniem LOG. Ma to jeden cel - zapewnienie puli osobnego i najlepiej znacznie szybszego, bardzo odpornego na zapis vdev do przechowywania ZIL-a, zamiast przechowywania ZIL-a w głównym magazynie vdev. Sam ZIL zachowuje się tak samo bez względu na to, gdzie jest przechowywany, ale jeśli LOG vdev ma bardzo wysoką wydajność zapisu, zapisy synchroniczne będą szybsze.

Dodanie vdev z LOG do puli nie działa nie mogę poprawić wydajność zapisu asynchronicznego - nawet jeśli wymusisz wszystkie zapisy do ZIL zfs set sync=always, nadal będą one połączone z pamięcią główną w TXG w ten sam sposób iw tym samym tempie, co bez dziennika. Jedyną bezpośrednią poprawą wydajności jest opóźnienie zapisu synchronicznego (ponieważ szybszy dziennik przyspiesza operacje). sync).

Jednak w środowisku, które już wymaga wielu zapisów synchronicznych, vdev LOG może pośrednio przyspieszyć zapisy asynchroniczne i odczyty niebuforowane. Przeniesienie wpisów ZIL do oddzielnego dziennika vdev LOG oznacza mniejszą rywalizację o IOPS w podstawowej pamięci masowej, co w pewnym stopniu poprawia wydajność wszystkich operacji odczytu i zapisu.

Migawki

Mechanizm kopiowania przy zapisie jest również niezbędnym fundamentem dla atomowych migawek ZFS i przyrostowej replikacji asynchronicznej. Aktywny system plików ma drzewo wskaźników, które oznacza wszystkie rekordy z aktualnymi danymi — kiedy robisz migawkę, po prostu tworzysz kopię tego drzewa wskaźników.

Kiedy rekord jest nadpisywany w aktywnym systemie plików, ZFS najpierw zapisuje nową wersję bloku w nieużywanym miejscu. Następnie odłącza starą wersję bloku od bieżącego systemu plików. Ale jeśli jakaś migawka odnosi się do starego bloku, nadal pozostaje niezmieniona. Stary blok nie zostanie faktycznie przywrócony jako wolna przestrzeń, dopóki wszystkie migawki odnoszące się do tego bloku nie zostaną zniszczone!

Replikacja

Podstawy ZFS: pamięć masowa i wydajność
Moja biblioteka Steam w 2015 roku miała 158 GiB i zawierała 126 927 plików. Jest to dość zbliżone do optymalnej sytuacji dla rsync – replikacja ZFS przez sieć była „tylko” 750% szybsza.

Podstawy ZFS: pamięć masowa i wydajność
W tej samej sieci replikacja pojedynczego pliku obrazu maszyny wirtualnej z systemem Windows 40 o pojemności 7 GB to zupełnie inna historia. Replikacja ZFS jest 289 razy szybsza niż rsync - lub „tylko” 161 razy szybsza, jeśli jesteś wystarczająco inteligentny, aby wywołać rsync z opcją --inplace.

Podstawy ZFS: pamięć masowa i wydajność
Gdy obraz maszyny wirtualnej jest skalowany, problemy z rsync skalują się z nim. 1,9 TiB nie jest zbyt duży jak na nowoczesny obraz maszyny wirtualnej - ale wystarczająco duży, aby replikacja ZFS była 1148 razy szybsza niż rsync, nawet z argumentem rsync --inplace

Gdy zrozumiesz, jak działają migawki, zrozumienie istoty replikacji powinno być łatwe. Ponieważ migawka jest tylko drzewem wskaźników do rekordów, wynika z tego, że jeśli to zrobimy zfs send snapshot, następnie wysyłamy zarówno to drzewo, jak i wszystkie powiązane z nim rekordy. Kiedy to wyślemy zfs send в zfs receive w miejscu docelowym zapisuje zarówno rzeczywistą zawartość bloku, jak i drzewo wskaźników, które odnoszą się do bloków w docelowym zbiorze danych.

W drugiej robi się jeszcze ciekawiej zfs send. Mamy teraz dwa systemy, z których każdy zawiera poolname/datasetname@1i wykonasz nową migawkę poolname/datasetname@2. Dlatego w oryginalnej puli masz datasetname@1 и datasetname@2, aw puli docelowej jak dotąd tylko pierwsza migawka datasetname@1.

Ponieważ mamy wspólną migawkę między źródłem a celem datasetname@1, możemy to zrobić przyrostowe zfs send ponad tym. Kiedy mówimy do systemu zfs send -i poolname/datasetname@1 poolname/datasetname@2, porównuje dwa drzewa wskaźników. Wszelkie wskaźniki, które istnieją tylko w @2, oczywiście odnoszą się do nowych bloków - potrzebujemy więc zawartości tych bloków.

W systemie zdalnym przetwarzanie przyrostowe send tak samo proste. Najpierw piszemy wszystkie nowe wpisy zawarte w strumieniu send, a następnie dodaj wskaźniki do tych bloków. Voila, mamy @2 w nowym systemie!

Asynchroniczna replikacja przyrostowa ZFS to ogromne ulepszenie w stosunku do wcześniejszych metod nieopartych na migawkach, takich jak rsync. W obu przypadkach przesyłane są tylko zmienione dane - ale rsync musi najpierw czytać z dysku wszystkie dane po obu stronach, aby sprawdzić sumę i porównać. W przeciwieństwie do tego replikacja ZFS odczytuje tylko drzewa wskaźników - i wszelkie bloki, których nie ma we współdzielonej migawce.

Wbudowana kompresja

Mechanizm kopiowania przy zapisie upraszcza również wbudowany system kompresji. W tradycyjnym systemie plików kompresja jest problematyczna – zarówno stara, jak i nowa wersja zmodyfikowanych danych znajdują się w tej samej przestrzeni.

Jeśli weźmiemy pod uwagę fragment danych w środku pliku, który zaczyna życie jako megabajt zer od 0x00000000 i tak dalej, bardzo łatwo jest go skompresować do jednego sektora na dysku. Ale co się stanie, jeśli zastąpimy ten megabajt zer megabajtem nieskompresowanych danych, takich jak JPEG lub szum pseudolosowy? Nieoczekiwanie ten megabajt danych będzie wymagał nie jednego, a 256 4 KiB sektorów, aw tym miejscu na dysku zarezerwowany jest tylko jeden sektor.

ZFS nie ma tego problemu, ponieważ zmodyfikowane rekordy są zawsze zapisywane w nieużywanym miejscu - oryginalny blok zajmuje tylko jeden sektor 4 KiB, a nowy rekord zajmie 256, ale to nie jest problem - niedawno zmodyfikowany fragment z „ middle” pliku zostanie zapisany w nieużywanym miejscu, niezależnie od tego, czy jego rozmiar się zmienił, czy nie, więc w przypadku ZFS jest to dość normalna sytuacja.

Natywna kompresja ZFS jest domyślnie wyłączona, a system oferuje podłączalne algorytmy — obecnie LZ4, gzip (1-9), LZJB i ZLE.

  • LZ4 to algorytm przesyłania strumieniowego, który oferuje niezwykle szybką kompresję i dekompresję oraz korzyści w zakresie wydajności w większości przypadków użycia — nawet na dość wolnych procesorach.
  • GZIP jest czcigodnym algorytmem, który wszyscy użytkownicy Uniksa znają i kochają. Można go zaimplementować z poziomami kompresji 1-9, ze współczynnikiem kompresji i obciążeniem procesora rosnącymi w miarę zbliżania się do poziomu 9. Algorytm dobrze nadaje się do wszystkich przypadków użycia tekstu (lub innych wysoce kompresowalnych), ale poza tym często powoduje problemy z procesorem — używaj go ostrożnie, zwłaszcza na wyższych poziomach.
  • LZJB jest oryginalnym algorytmem w ZFS. Jest przestarzały i nie powinien być już używany, LZ4 przewyższa go pod każdym względem.
  • - kodowanie na poziomie zerowym, kodowanie na poziomie zerowym. W ogóle nie dotyka normalnych danych, ale kompresuje duże sekwencje zer. Przydatne w przypadku całkowicie nieskompresowalnych zestawów danych (takich jak JPEG, MP4 lub inne już skompresowane formaty), ponieważ ignoruje dane nieskompresowane, ale kompresuje niewykorzystane miejsce w wynikowych rekordach.

Zalecamy kompresję LZ4 dla prawie wszystkich przypadków użycia; spadek wydajności w przypadku napotkania danych niekompresowalnych jest bardzo mały i zyskać wydajność dla typowych danych jest znacząca. Kopiowanie obrazu maszyny wirtualnej dla nowej instalacji systemu operacyjnego Windows (świeżo zainstalowany system operacyjny, jeszcze bez danych) za pomocą compression=lz4 przeszedł 27% szybciej niż z compression=nonew ten egzamin w 2015 r.

ARC - adaptacyjna zastępcza pamięć podręczna

ZFS to jedyny znany nam nowoczesny system plików, który wykorzystuje własny mechanizm buforowania odczytu, zamiast polegać na pamięci podręcznej stron systemu operacyjnego do przechowywania kopii ostatnio odczytanych bloków w pamięci RAM.

Chociaż natywna pamięć podręczna nie jest pozbawiona problemów — ZFS nie może odpowiadać na nowe żądania alokacji pamięci tak szybko jak jądro, więc nowe wyzwanie malloc() przy alokacji pamięci może się nie powieść, jeśli potrzebuje pamięci RAM aktualnie zajmowanej przez ARC. Istnieją jednak dobre powody, aby korzystać z własnej pamięci podręcznej, przynajmniej na razie.

Wszystkie znane nowoczesne systemy operacyjne, w tym MacOS, Windows, Linux i BSD, wykorzystują algorytm LRU (Least Ostatnio Używany) do implementacji pamięci podręcznej strony. Jest to prymitywny algorytm, który przesuwa buforowany blok „w górę kolejki” po każdym odczycie i przesuwa bloki „w dół kolejki” w razie potrzeby, aby dodać nowe braki w pamięci podręcznej (bloki, które powinny były zostać odczytane z dysku, a nie z pamięci podręcznej) w górę.

Algorytm zwykle działa dobrze, ale w systemach z dużymi roboczymi zestawami danych LRU łatwo prowadzi do wyrzucania często potrzebnych bloków, aby zrobić miejsce na bloki, które nigdy nie zostaną ponownie odczytane z pamięci podręcznej.

ARC jest znacznie mniej naiwnym algorytmem, który można traktować jako „ważoną” pamięć podręczną. Za każdym razem, gdy odczytywany jest blok z pamięci podręcznej, staje się on nieco „cięższy” i trudniejszy do eksmisji - a nawet po eksmisji bloku śledzone w określonym czasie. Blok, który został eksmitowany, ale następnie musi zostać wczytany z powrotem do pamięci podręcznej, również stanie się „cięższy”.

Końcowym rezultatem tego wszystkiego jest pamięć podręczna o znacznie wyższym współczynniku trafień, stosunku między trafieniami w pamięci podręcznej (odczyty wykonywane z pamięci podręcznej) a chybieniami w pamięci podręcznej (odczyty z dysku). Jest to niezwykle ważna statystyka — nie tylko same trafienia w pamięci podręcznej są obsługiwane o rząd wielkości szybciej, ale także chybienia w pamięci podręcznej mogą być obsługiwane szybciej, ponieważ im więcej trafień w pamięci podręcznej, tym mniej jednoczesnych żądań dysku i tym mniejsze opóźnienie dla pozostałych chybień, które muszą podawać z dyskiem.

wniosek

Po zapoznaniu się z podstawową semantyką ZFS — jak działa funkcja kopiowania przy zapisie, a także relacjami między pulami pamięci masowej, urządzeniami wirtualnymi, blokami, sektorami i plikami — jesteśmy gotowi do omówienia rzeczywistej wydajności za pomocą liczb rzeczywistych.

W następnej części przyjrzymy się rzeczywistej wydajności pul z lustrzanymi vdev i RAIDz w porównaniu do siebie nawzajem, a także w porównaniu z tradycyjnymi topologiami RAID jądra Linuksa, które zbadaliśmy. wcześniej.

Na początku chcieliśmy omówić tylko podstawy - same topologie ZFS - ale później taki a przygotujmy się do rozmowy o bardziej zaawansowanej konfiguracji i dostrajaniu ZFS, w tym o użyciu pomocniczych typów vdev, takich jak L2ARC, SLOG i Special Allocation.

Źródło: www.habr.com

Dodaj komentarz