Pokazywanie postów oznaczonych etykietą tuning. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą tuning. Pokaż wszystkie posty

2011/01/31

Kompresja danych, a wydajność

Doświadczenie jest fajne, ale może prowadzić do rutyny, a to nie jest dobre. Myślenie się wyłącza, umysł się rozleniwia, robimy i mówimy cały czas to samo i w ten sam sposób. Warunki tymczasem zmieniają się i trzeba się do nich ciągle dostosowywać. Już kiedyś o tym pisałem tłumacząc się z mojego naiwnego tłumaczenia wyższości RAID10 nad RAID5. Jak widać sam się za dużo nie nauczyłem, bo oto kolejny raz wpadłem w pułapkę rutyny. Tym razem sprawa dotyczy tytułowej kompresji danych.

Kiedyś sprawa była prosta. Kompresja to ciężki proces, mocno angażujący procesor. Co prawda można dzięki niej upakować więcej danych na mniejszej przestrzeni, ale powoduje to znaczny spadek wydajności. Determinowało to przeznaczenie tej funkcji gdzieś w okolicach archiwizacji i backupu. Takie właśnie miałem podejście do tego tematu jeszcze w zeszły piątek, z rana. Potem poszedłem na warsztaty Oracle z migracji do wersji 11 i już na pierwszym wykładzie dotarło do mnie jak bardzo się mylę.

Sesję prowadził pan Piotr K., a jej tematem były nowe funkcje jedenastki, w tym Oracle Advanced Compression. Mechanizm ten pozwala na kompresję obiektów strukturalnych (tabele w relacjach) na poziomie bloku bazy danych. Dzięki temu można znacznie zredukować zapotrzebowanie na pamięć masową - co jest jasne. Dodatkowo jednak baza generuje mniej operacji i/o (w spakowanym bloku jest przecież więcej danych). To też jest oczywiste, ale dotarło do mnie po raz pierwszy. Świadomość tego faktu spowodowała, że nie zaprzeczyłem gdy pan Piotr stwierdził, że mechanizm ten może również pozytywnie wpłynąć na wydajność bazy danych. Przecież procesory są coraz szybsze i muszą czekać na wolne dyski. Okazuje się, że często dla wydajności całego systemu zysk w postaci mniejszej liczby operacji i/o jest większy niż strata związana z wykonywaniem kompresji.

Kompresję jako mechanizm zwiększający wydajność storage wykorzystują też nowe kontrolery SSD firmy SandForce. Używają one do tego dedykowanego procesora. Wspominałem o tym w zeszłym miesiącu, ale bez zrozumienia tematu. Teraz zastanawiam się, czy niedługo nie pojawią się macierze z taką funkcjonalnością. A może dyski twarde? Myślę, że to będzie nowy trend.

2010/01/29

i/o tuning - aix

Tym razem kilka informacji na temat strojenia i/o w systemie Aix (5.3 i 6.1). (Pozwolę sobie przekopiować część ogólnych informacji z poprzedniego wpisu z tej kategorii.)

- długość kolejki niepotwierdzonych operacji i/o (outstanding i/o queue depth)

Każde zlecenie z systemu operacyjnego do macierzy dyskowej wymaga potwierdzenia. Zawiera ono informacje o statusie zakończenia operacji i/o. Nie jest jednak powiedziane, że system musi czekać z wysłaniem nowego zlecenia na potwierdzenie zakończenia poprzedniego. System posiada kolejkę, w której umieszcza zlecone operacje i/o. Czekają one tam na potwierdzenie ich wykonania. Długość tej kolejki określa ile zleceń system może wysłać. (tu przeczytasz o tym więcej).
W systemie AIX kolejkę taką posiadają zarówno poszczególne lun'y jak i kontrolery (scsi, iscsi, fc). Parametry te są atrybutami tych urządzeń. W przypadku lun'ów jest to queue_depth. Jego wartość sprawdzamy tak:
# lsattr -El hdisk??
(...)
queue_depth 16 Queue DEPTH True
(...)
a zmieniamy tak:
# chdev -l hdisk?? -a queue_depth=??
Atrybut odpowiedzialny za długość kolejki na kontrolerze ma inną nazwę - num_cmd_elems. Aby sprawdzić jego wartość:
# lsattr -El fcs??
(...)
num_cmd_elems 200 Maximum number of COMMANDS to queue to the adapter True
(...)
Przy zmianie:
# chdev -l fcs?? -a num_cmd_elems=??
Zmiany obu tych atrybutów wymagają zamknięcia dostępu do modyfikowanych urządzeń - umount systemów plików, varyoff na grupach volumenowych.
Długość kolejki decyduje o ilości operacji i/o na sekundę (iops) jaką może zlecić system operacyjny. Zwiększanie go nie ma sensu jeżeli macierz nie jest w stanie wykonać tylu IOPS. Często jednak macierz może więcej, ale system jest ograniczany krótką kolejką. Widać to po różnicy w czasie wykonania operacji i/o na macierzy (szybko) i czasie wykonania operacji i/o w systemie (długo). W takiej sytuacji wydłużenie kolejki powinno zwiększyć wydajność.


2009/09/02

i/o tuning - linux

Skończyły się wakacje, czas odpoczynku i lenistwa. Dzieci i młodzież wracają do szkoły, dorośli zapominają o urlopach i biorą się do roboty. Czas odkurzyć klawiaturę i dodać nowej treści do tego bloga. Zaczynam od rozpoczęcia nowego cyklu dotyczącego tuningu różnych systemów operacyjnych pod kątem współpracy z macierzą dyskową.

Kilka miesięcy temu pewien Portugalczyk, konsultant z Microsoftu, młody człowiek z wielką charyzmą, uświadomił mi, że przy strojeniu współczesnych systemów operacyjnych najlepsze efekty można uzyskać w podsystemie i/o. Druga w kolejności, ale dosyć daleko, jest pamięć operacyjna, a parametry systemowe dotyczące pozostałych elementów sprzętu - procesorów, magistral, ..., - nie mają już praktycznie żadnego znaczenia dla wydajności całego systemu.

Powodem takiego stanu rzeczy jest fakt, że współczesne dyski mają wydajność nie wiele większą niż te z poprzedniego wieku. W tym samym czasie moc procesorów wzrosła o kilka tysięcy procent. Przy tak wielkiej różnicy wydajności tych podzespołów, dyski zawsze będą metalową kulą u nogi całego systemu.

Całe szczęście jest kilka mechanizmów, które przy prawidłowych ustawieniach są w stanie znacznie polepszyć tą sytuację. Większość z nich występuję we wszystkich systemach operacyjnych, czasami inaczej się nazywają i inaczej są konfigurowane. W tym wpisie opiszę te, które są istotne w systemie linux (RedHat 5, kernel 2.6):

- długość kolejki niepotwierdzonych operacji i/o (outstanding i/o queue depth)

Każda zlecenie z systemu operacyjnego do macierzy dyskowej wymaga potwierdzenia. Zawiera ono informacje o statusie zakończenia operacji i/o. Nie jest jednak powiedziane, że system musi czekać z wysłaniem nowego zlecenia na potwierdzenie zakończenia poprzedniego. System posiada kolejkę, w której umieszcza zlecone operacje i/o. Czekają one tam na potwierdzenie ich wykonania. Długość tej kolejki określa ile zleceń system może wysłać. (tu przeczytasz o tym więcej). W linux'ie wielkość tą konfiguruje się na poziomie sterownika karty HBA. Jest to jeden parametr który określa długość kolejki dla każdego lun'a obsługiwanego przez ten sterownik. Wpisujemy go do pliku /etc/modprobe.conf:

dla kart Qlogic dopisujemy:
options qla2xxx ql2xmaxqdepth=długość kolejki

dla kart Emulex dopisujemy:
options lpfc lpfc_lun_queue_depth=długość kolejki

(update - zapomniełem o tym napisać) Teraz trzeba skreować nowy plik initrd (mkinitrd), aby nowe parametry były dostępne dla modułów ładowanych podczas startu systemu.

Niestety konieczny jest restart systemu.
Parametr ten decyduje o ilości operacji i/o na sekundę (iops) jaką może zlecić system operacyjny. Zwiększanie go nie ma sensu jeżeli macierz nie jest w stanie wykonać tylu IOPS. Często jednak macierz może więcej, ale system jest ograniczany krótką kolejką. Widać to po różnicy w czasie wykonania operacji i/o na macierzy (szybko) i czasie wykonania operacji i/o w systemie (długo). W takiej sytuacji wydłużenie kolejki powinno zwiększyć wydajność.

- I/O scheduler (elewator)

Developerzy jądra linux'a, mając świadomość ograniczeń wydajnościowych dysków twardych, zaimplementowali mechanizm i/o scheduler'ów zwanych również elewatorami. Znając budowę dysku (sektory, cylindry) stara się on grupować operacji i/o przed wysłaniem do dysku, tak aby jednocześnie trafiły w ten sam region talerza. Mechanizm ten sprawdza się przy pojedynczych dyskach, ale w przypadku macierzy jest zupełnie nieprzydatny. Co więcej może ograniczać wydajność systemu. Dlatego najlepsze co można zrobić to go wyłączyć. Robi się to poprzez ustawienie na dyskach elewatora noop. Można to zrobić globalnie dla całego systemu dodając opcję elevator=noop w linii z parametrami kernela w pliku /boot/grub/grub.conf, np.:

kernel /boot/vmlinuz-2.6.18-32.el5 ro root=LABEL=/1 rhgb quiet elevator=noop

Następnie należy wykonać restart systemu.
Można również zmienić elewator dla konkretnego dysku:

echo noop > /sys/block/nazwa dysku/queue/scheduler

Operacja ta jest online, jednak wymaga powtórzenia po każdym restarcie (potrzebny skrypt startowy). Więcej o scheduler'ach można poczytać w Red Hat Enterprise Linux 5 IO Tuning Guide

I to tyle w temacie tuning i/o w systemie Linux.

2009/03/26

Bufory i/o - czy response time jest istotny!?

System operacyjny bez mechanizmu buforowania operacji i/o działa bardzo niewydajnie. Za każdym razem gdy zapisuje lub odczytuje dane z pamięci masowej, musi czekać na potwierdzenie jej zakończenia. Dopiero wtedy kolejne zlecenie może być wysłane. Dostęp do dysków w takim systemie realizowany jest w 100% synchronicznie. Przy średnim czasie odpowiedzi na zlecenie wynoszącym 5ms, wydajność podsystemu i/o wynosi raptem 1000/5 = 200 IOPS. Całe szczęście takich systemów już chyba nie ma.

We współczesnych OS'ach wykonuje się jednocześnie wiele procesów i wątków. Wiele z nich używa pamięci masowej w tym samym momencie. Dodatkowo duża część aplikacji korzysta teraz z dysków w sposób asynchroniczny. Działa to tak, że po zgłoszeniu żądania zapisu/odczytu proces/wątek nie zatrzymuje się. Zajmuje się innym zadaniem, a do poprzedniego wraca jak dostanie od systemu informacje o wykonaniu żądania. Wszystko to powoduje, że konieczny jest mechanizm umożliwiający wysyłanie do pamięci masowej wielu operacji i/o jednocześnie. Nie oznacza to, że można zapomnieć o potwierdzeniach. Są one niezbędne dla poprawności składowanych danych.
Zależnie od systemu operacyjnego, mechanizm ten różnie się nazywa. Zasada działania jest jednak wszędzie prawie taka sama. Żądania zapisu/odczytu po wysłaniu do pamięci masowej są zapisywane w specjalnym buforze i zostają tam aż przyjdzie potwierdzenie ich wykonania. Dzięki temu system nie musi czekać z wysłaniem nowej operacji i/o na zakończenie poprzedniej. Wiele zleceń i/o może wykonywać się jednocześnie.
Opisywany mechanizm jest umiejscowiony zależnie od OS na poziomie dysku/lun'a albo portu FC/SCSI/iSCSI, albo w obu miejscach jednocześnie. Może też dotyczyć wszystkich dysków/portów lub każdego z osobna. Parametr systemowy odpowiedzialny za jego wielkość ma też różne nazwy. Przykłady:
AIX: indywidualnie dla każdego portu FC (num_cmd_elems) i dysku (queue_depth)
Solaris: globalnie dla wszystkich dysków (sdd_max_throttle)
Windows: indywidulanie dla każdego z portów FC (dla qlogic - execution throttle) globalnie dla wszystkich dysków (DriverParameter -> qd)
Wielkość tego buforu bezpośrednio wpływa na ilość IOPS jaką serwer jest w stanie zlecić do macierzy. Przykłady:
średni czas odpowiedzi=5ms, bufor=4, 1000/5 * 4 = 800 IOPS
średni czas odpowiedzi=5ms, bufor=8, 1000/5 * 8 = 1600 IOPS
Nie jest jednak powiedziane, że im większy bufor tym lepsza wydajność. Po drugiej stronie stoi bowiem macierz dyskowa, która też ma przecież swoje limity.
I teraz właśnie dochodzę do sedna sprawy. Czy czas odpowiedzi macierzy jest istotny dla jej wydajności? Nie ma wątpliwości, że tak. Dzięki buforom można jednak ograniczyć jego wpływ. Przykłady:
średni czas odpowiedzi=25ms, bufor=20, 1000/25 * 20 = 800 IOPS
średni czas odpowiedzi=25ms, bufor=40, 1000/25 * 40 = 1600 IOPS
Nie można przesadzić z wielkością buforów. Porty po stronie macierzy są w stanie obsłużyć ograniczoną liczbę niezakończonych operacji - od kilku do kilkunastu tysięcy.
Mechanizm ten nie spowoduje, że wydajność dysków wzrośnie do poziomu SSD, których czas odpowiedzi jest o rząd wielkości krótszy. Może jednak sprawić, że na dyskach 7200 RPM uda się zrobić konfigurację tak wydajną jak przy użyciu dysków 15000 RPM. Przykład dla RAID 0, 50% odczytów, 50% zapisów, 0 trafień w cache:
20 * 15000 RPM, array IOPS=3598, czas odpowiedzi=5ms, liczba buforów=18, host IOPS=3600
49 * 7200 RPM, array IOPS=3615, czas odpowiedzi=15ms, liczba buforów=55, host IOPS=3630
Cena tego rozwiązania będzie niższa, pojemność ponad 2x większa, a wydajność jak widać niemal identyczna.