Ogólnie rzecz biorąc, poprawa wydajności pamięci podręcznej dysku jest czymś więcej niż tylko zwiększeniem wielkości pamięci podręcznej systemu plików, chyba że cały system mieści się w pamięci RAM. W takim przypadku należy użyć napędu RAM ( tmpfs
jest to dobre, ponieważ w niektórych przypadkach umożliwia powrót do dysku) do przechowywania w środowisku wykonawczym (i być może skrypt initrd do kopiowania systemu z pamięci na dysk RAM podczas uruchamiania).
Nie wiesz, czy twoim urządzeniem pamięci jest dysk SSD czy HDD. Oto, co dla mnie działa (w moim przypadku sda
jest to dysk twardy zamontowany w, /home
a sdb
dysk SSD zamontowany w /
).
Najpierw zoptymalizuj część load-stuff-from-storage-to-cache:
Oto moja konfiguracja dysku twardego (upewnij się, że AHCI + NCQ jest włączony w systemie BIOS, jeśli masz przełączniki):
echo cfq > /sys/block/sda/queue/scheduler
echo 10000 > /sys/block/sda/queue/iosched/fifo_expire_async
echo 250 > /sys/block/sda/queue/iosched/fifo_expire_sync
echo 80 > /sys/block/sda/queue/iosched/slice_async
echo 1 > /sys/block/sda/queue/iosched/low_latency
echo 6 > /sys/block/sda/queue/iosched/quantum
echo 5 > /sys/block/sda/queue/iosched/slice_async_rq
echo 3 > /sys/block/sda/queue/iosched/slice_idle
echo 100 > /sys/block/sda/queue/iosched/slice_sync
hdparm -q -M 254 /dev/sda
Warto zauważyć, że przypadek dysku twardego jest wysoki fifo_expire_async
(zwykle zapis) i długi, slice_sync
aby umożliwić pojedynczemu procesowi uzyskanie wysokiej przepustowości (ustaw slice_sync
niższą liczbę, jeśli trafisz na sytuacje, w których wiele procesów czeka równolegle na niektóre dane z dysku). Jest slice_idle
to zawsze kompromis w przypadku dysków twardych, ale ustawienie go gdzieś w zakresie 3-20 powinno być w porządku, w zależności od użycia dysku i oprogramowania układowego dysku. Wolę celować na niskie wartości, ale ustawienie go zbyt nisko zniszczy Twoją przepustowość. To quantum
ustawienie wydaje się mieć duży wpływ na przepustowość, ale staraj się utrzymywać ją na jak najniższym poziomie, aby utrzymać opóźnienie na rozsądnym poziomie. Ustawienie quantum
zbyt niskiej wartości zniszczy przepustowość. Wartości w zakresie 3-8 wydają się dobrze współpracować z dyskami twardymi. Najgorsze opóźnienie dla odczytu to ( quantum
* slice_sync
) + ( slice_async_rq
*slice_async
) ms, jeśli poprawnie zrozumiałem zachowanie jądra. Asynchronizacja jest najczęściej używana przez zapisy, a ponieważ chcesz opóźnić zapis na dysk, ustaw zarówno slice_async_rq
i slice_async
bardzo niskie liczby. Jednak ustawienie slice_async_rq
zbyt niskiej wartości może opóźnić odczyty, ponieważ zapisy nie mogą być dłużej opóźniane po odczytach. Mój config spróbuje zapisać danych na dysku co najwyżej po 10 sekundach po dane zostały przekazane do jądra, ale ponieważ można tolerować utratę danych dotyczących strat mocy również zestaw fifo_expire_async
do 3600000
powiedzieć, że 1 godzina jest w porządku za opóźnienie na dysku. Po prostu utrzymuj slice_async
niski poziom, ponieważ w przeciwnym razie możesz uzyskać duże opóźnienie odczytu.
hdparm
Komenda jest wymagane, aby zapobiec AAM od zabijania wiele spektaklu, który pozwala AHCI + NCQ. Jeśli dysk robi zbyt dużo hałasu, pomiń to.
Oto moja konfiguracja dysku SSD (seria Intel 320):
echo cfq > /sys/block/sdb/queue/scheduler
echo 1 > /sys/block/sdb/queue/iosched/back_seek_penalty
echo 10000 > /sys/block/sdb/queue/iosched/fifo_expire_async
echo 20 > /sys/block/sdb/queue/iosched/fifo_expire_sync
echo 1 > /sys/block/sdb/queue/iosched/low_latency
echo 6 > /sys/block/sdb/queue/iosched/quantum
echo 2 > /sys/block/sdb/queue/iosched/slice_async
echo 10 > /sys/block/sdb/queue/iosched/slice_async_rq
echo 1 > /sys/block/sdb/queue/iosched/slice_idle
echo 20 > /sys/block/sdb/queue/iosched/slice_sync
Tutaj warto zauważyć niskie wartości dla różnych ustawień wycinków. Najważniejszym ustawieniem dla dysku SSD jest to, slice_idle
które musi być ustawione na 0-1. Ustawienie go na zero przenosi wszystkie decyzje dotyczące porządkowania do natywnego NCQ, a ustawienie go na 1 pozwala jądru na porządkowanie żądań (ale jeśli NCQ jest aktywne, sprzęt może częściowo zastąpić porządkowanie jądra). Przetestuj obie wartości, aby zobaczyć, czy widzisz różnicę. Intel serii 320, wydaje się, że ustawienie slide_idle
do 0
daje najlepszą wydajność, ale ustawienie go 1
daje najlepszą (najniższy) ogólną latencję.
Aby uzyskać więcej informacji o tych tunach, zobacz http://www.linux-mag.com/id/7572/ .
Teraz, gdy skonfigurowaliśmy jądro do ładowania rzeczy z dysku do pamięci podręcznej z rozsądną wydajnością, nadszedł czas, aby dostosować zachowanie pamięci podręcznej:
Według przeprowadzonych przeze mnie testów nie zawracałbym sobie głowy ustawieniem odczytu blockdev
. Domyślne ustawienia jądra są w porządku.
Ustaw system tak, aby wolał zamieniać dane pliku niż kod aplikacji (nie ma to znaczenia, jeśli masz wystarczającą ilość pamięci RAM, aby utrzymać cały system plików i cały kod aplikacji oraz całą pamięć wirtualną przydzieloną przez aplikacje w pamięci RAM). Zmniejsza to opóźnienie przełączania między różnymi aplikacjami w porównaniu z opóźnieniem dostępu do dużych plików z jednej aplikacji:
echo 15 > /proc/sys/vm/swappiness
Jeśli wolisz przechowywać aplikacje prawie zawsze w pamięci RAM, możesz ustawić to na 1. Jeśli ustawisz to na zero, jądro nie będzie w ogóle zamieniać, chyba że jest to absolutnie konieczne dla uniknięcia OOM. Jeśli masz ograniczoną pamięć i pracujesz z dużymi plikami (np. Edycja wideo HD), warto ustawić tę wartość na 100.
Ja obecnie (2017) wolę w ogóle nie zamieniać, jeśli masz wystarczającą ilość pamięci RAM. Brak wymiany zwykle powoduje utratę 200-1000 MB pamięci RAM na długo działającym komputerze stacjonarnym. Jestem gotów poświęcić tyle, aby uniknąć opóźnień w najgorszym przypadku (zamiana kodu aplikacji, gdy pamięć RAM jest pełna). W praktyce oznacza to, że wolę OOM Killera niż zamianę. Jeśli zezwolisz / potrzebujesz zamiany, możesz też chcieć zwiększyć /proc/sys/vm/watermark_scale_factor
, aby uniknąć opóźnień. Sugerowałbym wartości od 100 do 500. Możesz rozważyć to ustawienie jako zamianę wykorzystania procesora na mniejsze opóźnienia wymiany. Domyślnie jest to 10, a maksymalna możliwa to 1000. Wyższa wartość powinna (zgodnie z dokumentacją jądra ) skutkować większym zużyciem procesora dla kswapd
procesów i niższym całkowitym opóźnieniem zamiany.
Następnie powiedz jądru, aby wolało utrzymywać hierarchię katalogów w pamięci nad zawartością pliku na wypadek, gdyby część pamięci RAM musiała zostać zwolniona (ponownie, jeśli wszystko mieści się w pamięci RAM, to ustawienie nic nie robi):
echo 10 > /proc/sys/vm/vfs_cache_pressure
Oprawa vfs_cache_pressure
zbyt niska wartość ma sens, ponieważ w większości przypadków jądro musi znać strukturę katalogów, zanim będzie mogło użyć zawartości pliku z pamięci podręcznej, a zbyt szybkie opróżnienie pamięci podręcznej katalogu sprawi, że pamięć podręczna plików będzie prawie bezwartościowa. Zastanów się nad przejściem do 1 z tym ustawieniem, jeśli masz dużo małych plików (mój system ma około 150 000 zdjęć o rozdzielczości 10 megapikseli i liczy się jako system „dużo małych plików”). Nigdy nie ustawiaj go na zero lub struktura katalogów jest zawsze przechowywana w pamięci, nawet jeśli w systemie kończy się pamięć. Ustawienie tej dużej wartości jest sensowne tylko wtedy, gdy masz tylko kilka dużych plików, które są ciągle odczytywane ponownie (ponownie, przykładowo, edycja wideo HD bez wystarczającej ilości pamięci RAM). Oficjalna dokumentacja jądra mówi, że „
Wyjątek: jeśli masz naprawdę ogromną liczbę plików i katalogów i rzadko dotykasz / odczytujesz / wyświetlasz listę, wszystkie pliki vfs_cache_pressure
powyżej 100 mogą być mądre. Dotyczy to tylko sytuacji, gdy nie masz wystarczającej ilości pamięci RAM i nie możesz utrzymać całej struktury katalogów w pamięci RAM, a nadal masz wystarczającą ilość pamięci RAM do normalnej pamięci podręcznej plików i procesów (np. Serwer plików dla całej firmy z dużą ilością zawartości archiwalnej). Jeśli uważasz, że musisz zwiększyć vfs_cache_pressure
powyżej 100, biegniesz bez wystarczającej ilości pamięci RAM. Zwiększenie vfs_cache_pressure
może pomóc, ale jedynym prawdziwym rozwiązaniem jest uzyskanie większej ilości pamięci RAM. Po vfs_cache_pressure
ustawiony na dużą liczbę poświęca średnią wydajność na posiadanie więcej stabilną wydajność ogólna (czyli można uniknąć naprawdę złe zachowanie najgorszy przypadek, ale mamy do czynienia z gorszą ogólną wydajność).
Na koniec powiedz jądru, aby używało do 99% pamięci RAM jako pamięci podręcznej dla zapisów i poinstruuj jądro, aby używało do 50% pamięci RAM przed spowolnieniem procesu pisania (domyślnie dirty_background_ratio
jest to 10
). Ostrzeżenie: osobiście nie zrobiłbym tego, ale twierdziłeś, że masz wystarczającą ilość pamięci RAM i jesteś gotów stracić dane.
echo 99 > /proc/sys/vm/dirty_ratio
echo 50 > /proc/sys/vm/dirty_background_ratio
I powiedz, że opóźnienie zapisu 1h jest w porządku, aby nawet zacząć zapisywać rzeczy na dysku (ponownie, nie zrobiłbym tego):
echo 360000 > /proc/sys/vm/dirty_expire_centisecs
echo 360000 > /proc/sys/vm/dirty_writeback_centisecs
Jeśli umieścisz je wszystkie /etc/rc.local
i na końcu dołączasz, wszystko będzie w pamięci podręcznej jak najszybciej po starcie (zrób to tylko, jeśli twój system plików naprawdę pasuje do pamięci RAM):
(nice find / -type f -and -not -path '/sys/*' -and -not -path '/proc/*' -print0 2>/dev/null | nice ionice -c 3 wc -l --files0-from - > /dev/null)&
Lub nieco prostsza alternatywa, która może działać lepiej (pamięć tylko /home
i /usr
wyłącznie to zrobić jeśli /home
i /usr
naprawdę zmieścić się w pamięci RAM):
(nice find /home /usr -type f -print0 | nice ionice -c 3 wc -l --files0-from - > /dev/null)&