W systemie Linux zakończone wykonanie polecenia takiego jak cp
lub dd
nie oznacza, że dane zostały zapisane na urządzeniu. Trzeba na przykład wywołać sync
lub wywołać funkcję „Bezpieczne usuwanie” lub „Wysuń” na dysku.
Jaka jest filozofia takiego podejścia? Dlaczego dane nie są zapisywane od razu? Czy nie ma niebezpieczeństwa, że zapis nie powiedzie się z powodu błędu we / wy?
kernel
drivers
io
unix-philosophy
marmistrz
źródło
źródło
Odpowiedzi:
Wydajność (lepsze wykorzystanie charakterystyki dysku) i wydajność (pozwala aplikacji kontynuować działanie natychmiast po zapisie).
Główną zaletą jest to, że system operacyjny może dowolnie zmieniać kolejność i łączyć ciągłe operacje zapisu, aby poprawić wykorzystanie przepustowości (mniej operacji i mniej prób). Dyski twarde działają lepiej, gdy żądana jest niewielka liczba dużych operacji, podczas gdy aplikacje zwykle wymagają dużej liczby małych operacji. Inną wyraźną optymalizacją jest to, że system operacyjny może również usuwać wszystkie zapisy oprócz ostatniego, gdy ten sam blok jest zapisywany wiele razy w krótkim czasie, a nawet usuwać niektóre zapisy razem, jeśli plik, którego dotyczy problem, został w międzyczasie usunięty.
Te asynchroniczne zapisy są zrobione po
write
powrócił wywołanie systemowe. To druga i najbardziej widoczna zaleta dla użytkownika. Zapisy asynchroniczne przyspieszają aplikacje, ponieważ mogą swobodnie kontynuować pracę bez czekania, aż dane faktycznie znajdą się na dysku. Ten sam rodzaj buforowania / buforowania jest również implementowany w operacjach odczytu, w których bloki ostatnio lub często odczytywane są zachowywane w pamięci zamiast ponownego odczytu z dysku.Niekoniecznie. Zależy to od używanego systemu plików i wprowadzonej nadmiarowości. Błąd we / wy może być nieszkodliwy, jeśli dane można zapisać w innym miejscu. Nowoczesne systemy plików, takie jak ZFS, samoleczą uszkodzone bloki dysków. Należy również pamiętać, że błędy we / wy nie powodują awarii nowoczesnych systemów operacyjnych. Jeśli zdarzają się one podczas dostępu do danych, są po prostu zgłaszane do aplikacji, której dotyczy problem. Jeśli zdarzają się one podczas strukturalnego dostępu do metadanych i narażają system plików na ryzyko, może on zostać ponownie zamontowany w trybie tylko do odczytu lub stać się niedostępny.
Istnieje również niewielkie ryzyko utraty danych w przypadku awarii systemu operacyjnego, przerwy w dostawie prądu lub awarii sprzętu. Z tego powodu aplikacje, które muszą mieć 100% pewności, że dane znajdują się na dysku (np. Bazy danych / aplikacje finansowe), wykonują mniej wydajne, ale bezpieczniejsze zapisy synchroniczne. Aby złagodzić wpływ na wydajność, wiele aplikacji nadal używa zapisów asynchronicznych, ale ostatecznie synchronizuje je, gdy użytkownik jawnie zapisuje plik (np. Vim, edytory tekstu).
Z drugiej strony ogromna większość użytkowników i aplikacji nie potrzebuje ani nie dba o bezpieczeństwo zapewniane przez zapisy synchroniczne. W przypadku awarii lub awarii zasilania jedynym ryzykiem jest często utrata w najgorszym przypadku ostatnich 30 sekund danych. O ile nie dojdzie do transakcji finansowej lub czegoś podobnego, co oznaczałoby koszt znacznie dłuższy niż 30 sekund ich czasu, ogromny wzrost wydajności (co nie jest złudzeniem, ale bardzo realne) zapisów asynchronicznych pozwala znacznie przewyższyć ryzyko.
Wreszcie, synchroniczne zapisy nie wystarczą do ochrony zapisanych danych. Jeśli Twoja aplikacja naprawdę musi upewnić się, że jej dane nie zostaną utracone, cokolwiek się stanie, należy zastosować replikację danych na wielu dyskach i w wielu lokalizacjach geograficznych, aby były odporne na katastrofy takie jak pożar, powódź itp.
źródło
Po prostu daje iluzję prędkości programom, które tak naprawdę nie muszą czekać na zakończenie zapisu. Zamontuj systemy plików w trybie synchronizacji (który zapewnia natychmiastowe zapisy) i zobacz, jak powolne jest wszystko.
Czasami pliki istnieją tylko tymczasowo ... program wykonuje trochę pracy i usuwa plik zaraz po zakończeniu pracy. Jeśli opóźnisz te zapisy, możesz uniknąć tego, że nigdy ich nie napisałeś.
Och, absolutnie. W takim przypadku zwykle cały system plików przechodzi w tryb tylko do odczytu i wszystko jest okropne. Ale to rzadko się zdarza, nie ma sensu tracić ogólnie zalet wydajności.
źródło
Asynchroniczne, buforowane operacje we / wy były używane przed Linuksem, a nawet przed Uniksem. Unix go miał, podobnie jak wszystkie jego odgałęzienia.
Oto, co napisali Ritchie i Thompson w swoim artykule CACM The UNIX Time-Sharing System :
W swoim pytaniu napisałeś również:
Tak, zapis może się nie powieść i program może nigdy się o tym nie dowiedzieć. Chociaż nigdy nie jest to dobre, skutki tego można zminimalizować w przypadkach, gdy błąd we / wy generuje panikę systemu (w niektórych systemach operacyjnych można to skonfigurować - zamiast paniki system może nadal działać, ale system plików, którego dotyczy problem, jest odmontowane lub zamontowane tylko do odczytu). Użytkownicy mogą następnie zostać powiadomieni, że dane w tym systemie plików są podejrzane. Napęd dyskowy można proaktywnie monitorować, aby sprawdzić, czy jego lista rozwijanych defektów gwałtownie rośnie, co wskazuje na awarię napędu.
BSD dodało
fsync
wywołanie systemowe, aby program mógł mieć pewność, że jego dane pliku zostały całkowicie zapisane na dysku przed kontynuowaniem, a kolejne systemy uniksowe zapewniły opcje zapisu synchronicznego. GNU dd ma opcję,conv=fsync
aby upewnić się, że wszystkie dane zostały zapisane przed wyjściem z polecenia. Jest to przydatne przy zapisywaniu na powolnych wymiennych dyskach flash, gdzie zapisywanie buforowanych danych może potrwać kilka minut.Innym źródłem uszkodzenia plików jest nagłe zamknięcie systemu, na przykład z powodu utraty zasilania. Praktycznie wszystkie obecne systemy obsługują czystą / brudną flagę w swoich systemach plików. Flaga jest ustawiona na czyszczenie, gdy nie ma już danych do zapisania, a system plików ma zostać odmontowany, zwykle podczas zamykania systemu lub przez ręczne wywołanie
umount
. Systemy zwykle będą uruchamianefsck
po ponownym uruchomieniu, jeśli wykryją, że systemy plików nie zostały poprawnie zamknięte.źródło
Wiele dobrych odpowiedzi, ale dodam jeszcze jedną rzecz ... Pamiętaj, że Unix to system wieloprocesowy i dla wielu użytkowników, więc potencjalnie wielu użytkowników będzie próbowało wykonywać operacje na plikach (szczególnie zapisuje) na (prawie) w tym samym czasie. W przypadku starych wolnych dysków twardych - być może montowanych w sieci - nie tylko zabierałoby to trochę czasu (na co programy w zasadzie się blokowały, a użytkownicy musieli czekać), ale powodowało także wiele ruchów głowicy odczytu / zapisu dysk do przodu i do tyłu.
Zamiast tego pliki oczekujące na zapis były przez pewien czas przechowywane w pamięci i sortowane według miejsca, w którym powinny znaleźć się na dysku ... i kiedy bufor był pełny - lub demon synchronizacji dysku czekał na wymagana liczba sekund (myślę, że zwykle trwało to około 30 sekund) - cały bufor został zapisany na dysk „w porządku”, przy czym głowica zapisująca musiała wykonać tylko jeden ciągły ruch zamiatania, zapisując pliki na dysku jako poszło ... zamiast skakać wszędzie.
Oczywiście w przypadku dzisiejszych szybkich dysków - nie wspominając o urządzeniach półprzewodnikowych - zysk jest o wiele mniej ... szczególnie na domowym systemie Linux, w którym pracuje tylko jeden użytkownik naraz i tylko kilka programów.
W każdym razie kombinacja przewidywania odczytów poprzez wczytywanie (do pamięci podręcznej / bufora) więcej niż zażądano - i sortowanie danych oczekujących na zapis, aby można je było zapisać jednym ruchem - było w rzeczywistości bardzo dobrym pomysłem na czas, szczególnie w systemach z dużą ilością czytania i pisania przez wielu użytkowników.
źródło
Nie jest specyficzny dla Linuksa i nazywa się pamięcią podręczną stron (co Linux robi całkiem dobrze). Zobacz także http://linuxatemyram.com/ ; więc jeśli plik zostanie zapisany, a następnie przeczytaj go ponownie kilka sekund później, bardzo często nie jest potrzebny dysk I / O.
Główną zaletą jest to, że w wielu systemach jest dużo pamięci RAM, a niektóre z nich mogą być używane przez jądro jako pamięć podręczna. Dlatego niektóre operacje na plikach mogą czerpać korzyści z tego buforowania. Ponadto czas wejścia / wyjścia dysku jest znacznie wolniejszy (zwykle wiele tysięcy razy w przypadku SDD i prawie milion razy wolniejszy w przypadku mechanicznych dysków twardych) niż w przypadku pamięci RAM.
Kod aplikacji może dawać wskazówki dotyczące tego buforowania: patrz np. Posix_fadvise (2) i madvise (2)
źródło
Wirujące talerze są wolniejsze niż RAM. Używamy buforowania odczytów / zapisów, aby „ukryć” ten fakt.
Przydatną rzeczą w zapisywaniu We / Wy jest to, że nie wymaga natychmiastowego wykonania We / Wy dysku - w przeciwieństwie do odczytu, w którym nie można zwrócić danych użytkownikowi, dopóki odczyt nie zostanie zakończony na dysku.
W ten sposób zapisy działają pod łagodnym ograniczeniem czasowym - dopóki nasza ciągła przepustowość nie przekracza przepustowości naszego dysku, możemy ukryć wiele kar za wydajność w pamięci podręcznej zapisu.
I musimy pisać w pamięci podręcznej - wirujące dyski są względnie bardzo wolne. Ale aby to zrobić, współczesne typy macierzy RAID mają znaczną karę w działaniu.
Na przykład RAID 6, aby ukończyć jeden zapis IO, musi:
Tak więc każdy zapis to w rzeczywistości 6 operacji We / Wy - a szczególnie, gdy masz wolne dyski, takie jak duże dyski SATA, staje się to niezwykle kosztowne.
Ale jest ładne łatwe rozwiązanie - pisz coalescing. Jeśli możesz zbudować zapis „pełnego paska” w buforze, nie musisz czytać parzystości z dysku - możesz to obliczyć na podstawie tego, co masz w pamięci.
Jest to bardzo pożądane, ponieważ wtedy nie masz już wzmocnienia zapisu. Rzeczywiście, możesz skończyć z niższą karą za zapis niż RAID 1 + 0.
Rozważać:
RAID 6, 8 + 2 - 10 wrzecion.
8 kolejnych bloków danych do zapisu - oblicz parzystość w pamięci podręcznej i zapisz jeden blok na każdym dysku. 10 zapisów na 8, oznacza karę zapisu w wysokości 1,25. 10 dysków RAID 1 + 0 nadal ma karę zapisu w wysokości 2 (ponieważ musisz pisać do każdego submirror). Więc w tym scenariuszu możesz faktycznie sprawić, by RAID 6 działał lepiej niż RAID1 + 0. Jednak w rzeczywistych zastosowaniach uzyskuje się nieco bardziej mieszany profil IO.
Zatem buforowanie zapisu ma ogromną różnicę w postrzeganej wydajności zestawów RAID - możesz pisać z prędkością pamięci RAM i masz niską karę zapisu - poprawiając w ten sposób swoją stałą przepustowość.
A jeśli tego nie zrobisz, cierpisz na obolałą wydajność SATA, ale pomnóż ją przez 6 i dodaj trochę rywalizacji. Twój 10-drożny SATA RAID-6 bez buforowania zapisu byłby trochę szybszy niż pojedynczy dysk bez RAID ... ale niewiele.
Podejmujesz ryzyko, jednak - jak zauważyłeś - utrata zasilania oznacza utratę danych. Możesz temu zaradzić poprzez cykle płukania pamięci podręcznej, tworzenie kopii zapasowej pamięci podręcznej baterii lub użycie dysku SSD lub innej nieulotnej pamięci podręcznej.
źródło
Żadna z pozostałych odpowiedzi nie wspomniała o opóźnionym przydziale . Używają go XFS, ext4, BTRFS i ZFS. XFS używa go od czasu istnienia ext4, więc użyję go jako przykładu:
XFS nawet nie decyduje, gdzie umieścić dane, aż do zapisu. Opóźniona alokacja daje alokatorowi znacznie więcej informacji, na których można oprzeć swoje decyzje. Kiedy plik jest zapisywany po raz pierwszy, nie ma sposobu, aby dowiedzieć się, czy będzie to plik 4k, czy też plik ciągle rosnący 1G. Jeśli gdzieś jest 10G ciągłego wolnego miejsca, umieszczenie pliku 4k na początku nie przynosi żadnego efektu. Umieszczenie dużego pliku na początku dużej wolnej przestrzeni zmniejsza fragmentację.
źródło
Wszystkie pozostałe odpowiedzi tutaj są co najmniej w większości poprawne dla normalnego przypadku i polecam przeczytanie dowolnej z nich przed moim, ale wspomniałeś, że dd i dd ma typowy przypadek użycia, który może nie obejmować buforowania zapisu. Buforowanie zapisu jest przede wszystkim realizowane na poziomie systemu plików. Surowe urządzenia zwykle nie buforują zapisu (wiele sterowników urządzeń, takich jak raid lub lvm, to kolejna kula wosku). Ponieważ dd jest często używany z urządzeniami typu raw, udostępnia bs i powiązane opcje, aby umożliwić duże zapisy w celu uzyskania lepszej wydajności na urządzeniach typu raw. Nie jest to tak przydatne, gdy oba punkty końcowe są zwykłymi plikami (chociaż duże zapisy używają w tym przypadku mniej wywołań systemowych). Innym powszechnym miejscem, w którym jest to szczególnie widoczne, jest pakiet mtools, który jest implementacją systemu plików tłuszczu w przestrzeni użytkownika. używanie mtooli z dyskietką zawsze wydaje się bardzo powolne, ponieważ narzędzia są całkowicie synchroniczne, a dyskietki są niezwykle wolne. Montowanie dyskietki i korzystanie z systemu plików tłuszczu jądra jest znacznie bardziej responsywne, z wyjątkiem synchronicznego umounta (i jest to bardzo ważne, aby zapobiegać utracie danych, szczególnie w przypadku urządzeń wymiennych, takich jak dyskietki). Jest tylko kilka innych programów, o których wiem, że są regularnie używane z surowymi urządzeniami, takimi jak specjalnie skonfigurowane bazy danych (które implementują własne buforowanie zapisu), tar oraz specjalne urządzenia i narzędzia systemu plików, takie jak chdsk, mkfs i mt. Montowanie dyskietki i korzystanie z systemu plików tłuszczu jądra jest znacznie bardziej responsywne, z wyjątkiem synchronicznego umounta (i jest to bardzo ważne, aby zapobiegać utracie danych, szczególnie w przypadku urządzeń wymiennych, takich jak dyskietki). Jest tylko kilka innych programów, o których wiem, że są regularnie używane z surowymi urządzeniami, takimi jak specjalnie skonfigurowane bazy danych (które implementują własne buforowanie zapisu), tar oraz specjalne urządzenia i narzędzia systemu plików, takie jak chdsk, mkfs i mt. Montowanie dyskietki i korzystanie z systemu plików tłuszczu jądra jest znacznie bardziej responsywne, z wyjątkiem synchronicznego umounta (i jest to bardzo ważne, aby zapobiegać utracie danych, szczególnie w przypadku urządzeń wymiennych, takich jak dyskietki). Jest tylko kilka innych programów, o których wiem, że są regularnie używane z surowymi urządzeniami, takimi jak specjalnie skonfigurowane bazy danych (które implementują własne buforowanie zapisu), tar oraz specjalne urządzenia i narzędzia systemu plików, takie jak chdsk, mkfs i mt.
źródło
O_DIRECT
jeśli chcesz ominąć pamięć podręczną.dd oflag=direct
. IIRC, niektóre jednorożce domyślnie kierują I / O na urządzeniach blokowych. (I wymagają odczytu / zapisu wyrównanych bloków, czego nie robi Linux, ponieważ i tak zapisuje tylko pamięć podręczną.)Ta filozofia jest domyślnie niebezpieczna.
Możliwe są dwie rozsądne i oczywiste strategie: natychmiastowe zapisywanie na dysk lub opóźnienie zapisu. UNIX historycznie wybrał to drugie. Więc zapewnij sobie bezpieczeństwo, musisz
fsync
później zadzwonić .Można jednak określić bezpieczeństwo z góry, montując urządzenie z opcją
sync
lub dla każdego pliku, otwierając je za pomocąO_SYNC
.Pamiętaj, że UNIX został zaprojektowany dla ekspertów komputerowych. „Domyślnie bezpieczny” nie był brany pod uwagę. Bezpieczeństwo oznacza wolniejsze operacje we / wy, a te wczesne systemy naprawdę miały wolne operacje we / wy, co spowodowało, że stawka ceny była wysoka. Niestety, ani UNIX, ani Linux nie przeszły na „bezpieczną domyślną”, mimo że jest to niezłomna zmiana.
źródło
Wymienia niewielką ilość niezawodności, co znacznie zwiększa przepustowość.
Załóżmy na przykład program do kompresji wideo. Z opóźnionym zapisem („write back”):
Przeciw
Druga wersja pojawia się dwa razy szybciej, ponieważ może jednocześnie korzystać z procesora i dysku, podczas gdy pierwsza wersja zawsze czeka na jedną lub drugą.
Zasadniczo chcesz odzyskać dane w przypadku operacji przesyłania strumieniowego i operacji na plikach zbiorczych oraz zapisu w przypadku baz danych i aplikacji podobnych do baz danych.
źródło
W wielu aplikacjach urządzenia pamięci masowej będą sporadycznie zajęte odczytywaniem danych. Jeśli system zawsze jest w stanie odroczyć zapis do czasu, kiedy urządzenie pamięci masowej nie będzie zajęte odczytywaniem danych, to z punktu widzenia aplikacji zapisanie zajmie zero czasu. Jedyne sytuacje, w których zapisy nie byłyby natychmiastowe, to:
Bufory zapisu wypełniają się do tego stopnia, że nie można już zaakceptować żądań odroczonego zapisu, dopóki zapisy nie zostaną faktycznie zakończone.
Konieczne jest wyłączenie lub usunięcie urządzenia, dla którego trwa zapis.
Aplikacja konkretnie prosi o potwierdzenie, że zapis został faktycznie zakończony.
Rzeczywiście, to tylko z powodu powyższych wymagań, które pisze, że w ogóle kiedykolwiek muszą mieć miejsce. Z drugiej strony, generalnie nie ma powodu, aby nie wykonywać żadnych oczekujących zapisów w czasie, gdy urządzenie w innym przypadku byłoby bezczynne, więc wiele systemów wykonuje je wtedy.
źródło
Jest też to:
Napisz „Cześć, Joe Moe”
jest szybszy niż:
Napisz „Cześć”, „
Napisz” Joe ”
Napisz„ Moe ”
I również:
Napisz „Cześć, jak się masz?”
jest szybszy niż:
Napisz „Cześć, co słychać?”
Usuń ten
napis „Cześć, jak się masz?”
Usuń ten
napis „Cześć, jak się masz?”
Lepiej jest, aby modyfikacje i agregacja następowały w pamięci RAM niż na dysku. Dysk wsadowy zapisuje twórców aplikacji od takich problemów.
źródło