Spadek wydajności występuje, gdy zpool jest bardzo pełny lub bardzo rozdrobniony. Powodem tego jest mechanizm swobodnego wykrywania bloków zastosowany w ZFS. W przeciwieństwie do innych systemów plików, takich jak NTFS lub ext3, nie ma bitmapy blokowej pokazującej, które bloki są zajęte, a które wolne. Zamiast tego, ZFS dzieli twój zvol na (zwykle 200) większych obszarów zwanych „metaslabami” i przechowuje drzewa AVL 1 wolnych informacji o blokach (mapa kosmiczna) w każdej metaznaczce. Zrównoważone drzewo AVL pozwala na skuteczne wyszukiwanie bloku pasującego do wielkości żądania.
Chociaż ten mechanizm został wybrany ze względu na skalę, niestety okazał się również dużym bólem, gdy występuje wysoki poziom fragmentacji i / lub wykorzystania przestrzeni. Gdy tylko wszystkie metapliki przenoszą znaczną ilość danych, otrzymujesz dużą liczbę małych obszarów wolnych bloków, w przeciwieństwie do niewielkiej liczby dużych obszarów, gdy pula jest pusta. Jeśli ZFS następnie musi przydzielić 2 MB miejsca, zaczyna czytać i oceniać mapy przestrzeni wszystkich metaslab w celu znalezienia odpowiedniego bloku lub sposobu na rozbicie 2 MB na mniejsze bloki. To oczywiście zajmuje trochę czasu. Co gorsza, będzie to kosztować dużo operacji we / wy, ponieważ ZFS rzeczywiście odczyta wszystkie mapy kosmiczne z dysków fizycznych . Dla każdego z twoich zapisów.
Spadek wydajności może być znaczny. Jeśli masz ochotę na ładne zdjęcia, spójrz na post na blogu w Delphix, w którym niektóre numery zostały usunięte z (nadmiernie uproszczonej, ale jeszcze ważnej) puli ZFS. Bezwstydnie kradnę jeden z wykresów - spójrz na niebieskie, czerwone, żółte i zielone linie na tym wykresie, które (odpowiednio) reprezentują pule o pojemności 10%, 50%, 75% i 93% w porównaniu do przepustowości zapisu w KB / s podczas fragmentacji w czasie:
Szybkim i brudnym rozwiązaniem tego problemu jest tradycyjnie tryb debugowania metaslab (wystarczy problem echo metaslab_debug/W1 | mdb -kw
w czasie wykonywania, aby natychmiast zmienić ustawienie). W takim przypadku wszystkie mapy kosmiczne byłyby przechowywane w pamięci RAM systemu operacyjnego, co eliminowałoby konieczność nadmiernego i kosztownego wejścia / wyjścia przy każdej operacji zapisu. Ostatecznie oznacza to również, że potrzebujesz więcej pamięci, szczególnie w przypadku dużych pul, więc jest to rodzaj pamięci RAM do przechowywania handlu końmi. Twoja pula 10 TB prawdopodobnie będzie kosztować 2-4 GB pamięci 2 , ale będziesz w stanie doprowadzić ją do 95% wykorzystania bez większych problemów.
1 jest to trochę bardziej skomplikowane, jeśli jesteś zainteresowany, spójrz na post Bonwicka na mapach kosmicznych, aby uzyskać szczegółowe informacje
2 jeśli potrzebujesz sposobu na obliczenie górnego limitu pamięci, użyj, zdb -mm <pool>
aby pobrać liczbę segments
aktualnie używanych w każdej metaslabie, podziel go przez dwa, aby modelować najgorszy scenariusz (po każdym zajętym segmencie byłby wolny ), pomnóż go przez rozmiar rekordu dla węzła AVL (dwa wskaźniki pamięci i wartość, biorąc pod uwagę, że 128-bitowy charakter ZFS i 64-bitowe adresowanie sumowałoby do 32 bajtów, chociaż ludzie wydają się przyjmować 64 bajty dla niektórych powód).
zdb -mm tank | awk '/segments/ {s+=$2}END {s*=32/2; printf("Space map size sum = %d\n",s)}'
Odniesienie: podstawowy zarys znajduje się w tym poście Markus Kovero na liście dyskusyjnej zfs-dyskusji , chociaż uważam, że popełnił kilka błędów w swoich obliczeniach, które mam nadzieję poprawić w moim.
volume
do 8,5 T i nigdy więcej o tym nie myślę. Czy to jest poprawne?