Zastosowanie O_DIRECT w systemie Linux


24

Jeśli to pytanie jest zbyt zorientowane na programistę, daj mi znać. Zastanawiam się, czy są ludzie znający flagę O_DIRECT dla wywołania systemowego open () w Linuksie 2.6? Linus dyskredytuje jego użycie, jednak wydaje się, że zapisywanie plików o wysokiej wydajności wskazuje na jego użycie. Chciałbym poznać wszelkie doświadczenia i rekomendacje z prawdziwego świata.

Więcej informacji: Aplikacja, której używam , utrzymuje własną pamięć podręczną, a dzięki temu osiąga średnio 5-krotnie lub więcej przyspieszenie. Podczas zapisywania do pliku zawartość pamięci podręcznej musi zostać zapisana w pamięci podręcznej systemu plików, co wydaje się zbędne i ma wpływ na wydajność.

Odpowiedzi:


17

Ok, pytasz o doświadczenia, to sprawia, że ​​pytanie jest trochę subiektywne i kłótliwe, ale możliwe do przejścia.

Linus powiedział, że odnosząc się do zastosowań, które ludzie zwykle przypisują O_DIRECT, i dla tych zastosowań, IMO Linus jest w większości poprawne. Nawet jeśli wykonujesz bezpośrednie operacje we / wy, nie możesz przesyłać danych do / z urządzeń bezpośrednio do instrukcji programu, potrzebujesz bufora, który jest wypełniany (przez program lub urządzenie) i przesyłany przez wywołanie systemowe na drugim końcu. Ponadto, aby uczynić go wydajnym, nie będziesz chciał ponownie czytać czegoś, co właśnie przeczytałeś, na wypadek, gdybyś go ponownie potrzebował. Potrzebujesz więc pamięci podręcznej ... i właśnie to zapewnia jądro bez O_DIRECT, pamięci podręcznej strony! Dlaczego tego nie użyć? Ma to również zalety, jeśli więcej procesów chce uzyskać dostęp do tego samego pliku jednocześnie, byłoby katastrofą z O_DIRECT.

Powiedziawszy to, O_DIRECT ma swoje zastosowania: Jeśli z jakiegoś powodu musisz uzyskać dane bezpośrednio z urządzenia blokowego. Nie ma to nic wspólnego z wydajnością.

Ludzie używający O_DIRECT do wydajności zwykle pochodzą z systemów ze złymi algorytmami pamięci podręcznej stron lub bez mechanizmów porad POSIX, a nawet bezmyślnie powtarzają to, co powiedzieli inni ludzie. Aby uniknąć tych problemów, O_DIRECT było rozwiązaniem. Linux, OTOH, ma filozofię, że powinieneś naprawić prawdziwy podstawowy problem, a podstawowym problemem były systemy operacyjne, które źle wykonały buforowanie stron.

Użyłem O_DIRECT do prostej implementacji cat, aby znaleźć błąd pamięci w mojej maszynie. Jest to jedno prawidłowe zastosowanie dla O_DIRECT. To nie miało nic wspólnego z wydajnością.


Dziękuję za informacje, jest to mile widziane. Zaktualizowałem moje pytanie o szczegółowe warunki aplikacji, które spowodowały to pytanie. Jeśli masz więcej szczegółów na temat mechanizmów doradztwa POSIX dotyczących zapisywania plików, również byłoby to mile widziane.
casualunixer

4
o_direct może być również przydatny w systemie, w którym programista chce udostępnić mechanizm buforowania w warstwie aplikacji (pomyśl bazy danych).
Jmoney38

Nie ma to nic wspólnego z wydajnością. Nie zawsze jest to prawdą, szczególnie w przypadku dostępu do szybkiego urządzenia, w którym IO ocenia przepustowość pamięci konkurencyjnej, a nawet tylko znaczny procent przepustowości pamięci. W takim przypadku pominięcie dodatkowej kopii do / z pamięci podręcznej strony może przynieść znaczące korzyści w zakresie wydajności.
Andrew Henle,

14

W rzeczywistości O_DIRECT jest to konieczne, aby uniknąć jednego z nich

  • zanieczyszczenie pamięci podręcznej - czasami wiesz, że buforowanie nie ma sensu, na przykład w przypadku naprawdę dużych plików, powiedz 64 GiB, gdy jest tylko 2 GiB pamięci RAM. Plik torrent 32 GiB, który użytkownik postanowił zweryfikować, nie wydaje się dobrym kandydatem do buforowania. To tylko dodatkowa aktywność z własnym narzutem. I może to spowodować, że niektóre naprawdę przydatne dane zostaną usunięte z pamięci podręcznej.
  • podwójne buforowanie - np. dla niektórych RDBMS (np. MySQL) pozwala na zdefiniowanie własnej pamięci podręcznej. Bazy danych podobno wiedzą lepiej, jak buforować i co, niż pamięć wirtualna jądra, która nie wie nic o planowaniu SQL i tak dalej.

- co nie jest dobre, jak się wydaje. I O_DIRECTnie oznacza, że ​​jest szybszy, często tak nie jest .


10
posix_fadvisemoże zająć się problemem zanieczyszczenia pamięci podręcznej.
psusi

Nie sądzę, aby pamięć wirtualna miała z tym coś wspólnego, jedynie mapuje adres pamięci. Masz na myśli bufor bufora / bufor strony.
ArekBulski

Buforowanie / buforowanie jest częścią podsystemu VM w UNIX, o ile wiem, dlatego użyłem tego terminu. Dzięki za edycję. :)
poige

6

Zauważ, że używanie O_DIRECTmoże zawieść w nowszych jądrach z nowszymi systemami plików. Zobacz na przykład ten raport o błędzie . Dlatego korzystanie nie tylko jest często wątpliwe, ale prawdopodobnie nie będzie działać w kolejnej generacji dystrybucji Linuksa. Nie postawiłbym więc na wydajność mojego kodu, nawet jeśli zdołasz udowodnić, że może to przynieść korzyść.


1
Raport o błędach faktycznie omawia użycie systemów plików z włączoną opcją journal = data. Ta opcja działa wprost przeciwnie do flagi O_DIRECT. Większość systemów plików ext3 i ext4 nie ma ustawionej tej flagi, a jeśli tak, jej wyłączenie pozwoli na otwarcie pliku za pomocą O_DIRECT.
casualunixer

3

Ma to wiele wspólnego z wydajnością.

Ciekawym przykładem jest mongodb wykorzystujący silnik mmap. O_DIRECT najlepiej jest używać, jak stwierdzili inni, tam gdzie przez pewien czas dane nie będą odczytywane. W mongodb dziennik bazy danych jest zapisywany przy użyciu O_DIRECT, podczas gdy zapisy danych i indeksów są obsługiwane przez mechanizm pamięci podręcznej strony (pdflush), ponieważ chociaż O_DIRECT oferuje mniejszą przepustowość, oznacza to również mniejsze opóźnienie, a zatem zmniejsza utratę danych w przypadku nieoczekiwana awaria (panika jądra, awaria dysku lub zasilania). Należy pamiętać, że buforowanie jest wykonywane, zanim zapis O_DIRECT zostanie zapisany w nieulotnej pamięci, co po prostu zmniejsza utratę danych.

Inną ważną cechą O_DIRECT jest to, że zapewnia większą kontrolę nad sekwencją zapisów. Ponownie nie gwarantuje to kolejności zapisu (chyba że masz nieulotny kontroler dysku buforującego i korzystasz z programu planującego fifo, ale ma to swoje komplikacje). Dlatego chociaż mysql używa O_DIRECT do swoich danych / indeksów, a także do rejestrowania, może oczekiwać, że to ostatnie zostanie zwykle zatwierdzone jako pierwsze.

Należy jednak pamiętać, że O_DIRECT narusza uczciwość w alokacji zasobów. Jednym z powodów przyspieszenia działania aplikacji jest spowolnienie innych rzeczy.


Mówisz, że ma to wiele wspólnego z wydajnością, ale podajesz przykład, w którym służy on do zmniejszenia opóźnień lub zapisywania zamówień. Ale zgadzam się, że wpływa to na wydajność. Uczciwa uwaga na temat uczciwości.
ArekBulski

Czy możesz podać więcej referencji wyjaśniających, kiedy jest to niesprawiedliwe?
ACykliczny

3

Odnosząc się do tego, co powiedział już Julian.

Zamówienie posix_fadvisejeśli prawdziwym problemem jest złe zachowanie od bazowego algorytmu pamięci podręcznej systemu plików, można spróbować dać mu rady, jak masz zamiar używać systemu plików. W przypadku ładnie zaimplementowanego fs powinno to zwiększyć wydajność. (Oto link do innego tematu dotykającego podobnych rozważań /programming//a/3755818/544721 )


1
Wygląda na to, że posix_fadvise zmienia algorytmy readahead używane przez jądro. Krytycznym czynnikiem w kodzie w pytaniu jest wydajność zapisu. Problem polega na tym, że wypisanie bufora najpierw wypełnia pamięci podręczne systemu Linux, które następnie jądro musi zrzucić, gdy zabraknie pamięci. Jest to strata wysiłku, w takim przypadku dane wyjściowe powinny być minimalnie buforowane na drodze do dysku.
casualunixer
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.