Migliorare le prestazioni della cache del disco in generale è molto più che aumentare le dimensioni della cache del file system a meno che l' intero sistema non si adatti alla RAM, nel qual caso è necessario utilizzare l'unità RAM ( tmpfs
è utile perché consente di ricadere sul disco se in alcuni casi è necessaria la RAM) per l'archiviazione di runtime (e forse uno script initrd per copiare il sistema dall'archiviazione all'unità RAM all'avvio).
Non hai detto se il tuo dispositivo di archiviazione è SSD o HDD. Ecco cosa ho scoperto di funzionare per me (nel mio caso sda
è un HDD montato su /home
e sdb
SSD montato su /
).
Innanzitutto ottimizza la parte load-stuff-from-storage-to-cache:
Ecco la mia configurazione per HDD (assicurati che AHCI + NCQ sia abilitato nel BIOS se hai toggles):
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
Vale la pena notare che il caso dell'HDD è elevato fifo_expire_async
(di solito in scrittura) e lungo slice_sync
per consentire a un singolo processo di ottenere un throughput elevato (impostato slice_sync
su un numero inferiore se si verificano situazioni in cui più processi sono in attesa di alcuni dati dal disco in parallelo). Il slice_idle
è sempre un compromesso per HDD, ma l'impostazione da qualche parte nella gamma 3-20 dovrebbe essere a posto a seconda dell'uso del disco e il firmware del disco. Preferisco scegliere come target valori bassi, ma impostandolo su un valore troppo basso si distrugge il rendimento. L' quantum
impostazione sembra influenzare molto il throughput, ma cerca di mantenerlo il più basso possibile per mantenere la latenza a livello ragionevole. L'impostazione su un valore quantum
troppo basso distruggerà il throughput. I valori nell'intervallo 3-8 sembrano funzionare bene con gli HDD. La latenza nel caso peggiore per una lettura è ( quantum
* slice_sync
) + ( slice_async_rq
*slice_async
) ms se ho compreso correttamente il comportamento del kernel. L'asincrono viene utilizzato principalmente dalle scritture e poiché sei disposto a ritardare la scrittura su disco, imposta entrambi slice_async_rq
e slice_async
numeri molto bassi. Tuttavia, l'impostazione di slice_async_rq
un valore troppo basso può bloccare le letture perché non è più possibile ritardare le scritture dopo le letture. Il mio config tenterà di scrivere i dati su disco, al massimo dopo 10 secondi dopo che i dati è stata passata al kernel, ma dal momento che si può tollerare la perdita di dati sulla perdita di potenza anche fissati fifo_expire_async
a 3600000
dire che 1 ora va bene per il ritardo su disco. Basta tenere slice_async
basso, però, perché altrimenti si può ottenere una latenza di lettura elevata.
Il hdparm
comando è necessario per impedire ad AAM di uccidere gran parte delle prestazioni consentite da AHCI + NCQ. Se il tuo disco fa troppo rumore, salta questo.
Ecco la mia configurazione per SSD (serie 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
Qui vale la pena notare i valori bassi per le diverse impostazioni della sezione. L'impostazione più importante per un SSD è slice_idle
che deve essere impostata su 0-1. Impostandolo su zero, tutte le decisioni relative agli ordini vengono spostate su NCQ nativo mentre l'impostazione su 1 consente al kernel di ordinare le richieste (ma se l'NCQ è attivo, l'hardware potrebbe sovrascrivere parzialmente l'ordinamento del kernel). Prova entrambi i valori per vedere se riesci a vedere la differenza. Per Intel serie 320, sembra che l'impostazione slide_idle
a 0
dà il meglio di throughput, ma impostandolo 1
dà migliore (più basso) la latenza complessiva.
Per ulteriori informazioni su questi parametri sintonizzabili, consultare http://www.linux-mag.com/id/7572/ .
Ora che abbiamo configurato il kernel per caricare roba da disco a cache con prestazioni sensate, è tempo di regolare il comportamento della cache:
Secondo i benchmark che ho fatto, non mi preoccuperei affatto di impostare la lettura in anticipo blockdev
. Le impostazioni predefinite del kernel vanno bene.
Impostare il sistema in modo da preferire lo scambio di dati di file rispetto al codice dell'applicazione (questo non importa se si dispone di RAM sufficiente per mantenere l' intero filesystem e tutto il codice dell'applicazione e tutta la memoria virtuale allocata dalle applicazioni nella RAM). Ciò riduce la latenza per lo scambio tra diverse applicazioni rispetto alla latenza per l'accesso a file di grandi dimensioni da una singola applicazione:
echo 15 > /proc/sys/vm/swappiness
Se si preferisce mantenere le applicazioni quasi sempre nella RAM, è possibile impostarlo su 1. Se si imposta questo su zero, il kernel non cambierà affatto a meno che non sia assolutamente necessario per evitare OOM. Se la memoria era limitata e si lavora con file di grandi dimensioni (ad esempio, editing di video HD), potrebbe essere sensato impostare questo valore su 100.
Al giorno d'oggi (2017) preferisco non avere alcun cambio se hai abbastanza RAM. Non avendo alcuno swap di solito si perdono 200-1000 MB di RAM su macchine desktop di lunga durata. Sono disposto a sacrificare così tanto per evitare la latenza dello scenario peggiore (scambiando il codice dell'applicazione quando la RAM è piena). In pratica, ciò significa che preferisco OOM Killer allo scambio. Se si consente / è necessario scambiare, è possibile aumentare /proc/sys/vm/watermark_scale_factor
anche per evitare un po 'di latenza. Vorrei suggerire valori compresi tra 100 e 500. È possibile considerare questa impostazione come scambio dell'utilizzo della CPU per una latenza di scambio inferiore. Il valore predefinito è 10 e il massimo possibile è 1000. Un valore più elevato dovrebbe (secondo la documentazione del kernel ) comportare un maggiore utilizzo della CPU per i kswapd
processi e una minore latenza di scambio complessiva.
Quindi, dire al kernel di preferire mantenere la gerarchia di directory in memoria rispetto al contenuto del file nel caso in cui sia necessario liberare un po 'di RAM (di nuovo, se tutto si adatta alla RAM, questa impostazione non fa nulla):
echo 10 > /proc/sys/vm/vfs_cache_pressure
Ambientazione vfs_cache_pressure
il valore basso ha senso perché nella maggior parte dei casi, il kernel deve conoscere la struttura della directory prima di poter utilizzare il contenuto del file dalla cache e svuotare la cache della directory troppo presto renderà la cache del file quasi inutile. Considera di scendere fino a 1 con questa impostazione se hai molti file di piccole dimensioni (il mio sistema ha circa 150K di foto da 10 megapixel e conta come un sistema di "molti file di piccole dimensioni"). Non impostarlo mai su zero o la struttura della directory viene sempre mantenuta in memoria anche se il sistema sta esaurendo la memoria. L'impostazione di questo valore su grande valore è sensata solo se hai solo pochi file di grandi dimensioni che vengono costantemente riletti (di nuovo, un esempio di editing video HD senza RAM sufficiente). La documentazione ufficiale del kernel afferma che "
Eccezione: se hai una quantità davvero enorme di file e directory e raramente tocchi / leggi / elenchi tutti i file con impostazioni vfs_cache_pressure
superiori a 100 potrebbero essere saggi. Questo vale solo se non si dispone di RAM sufficiente e non è possibile mantenere l'intera struttura di directory nella RAM e avere ancora RAM sufficiente per la normale cache e processi dei file (ad es. File server a livello aziendale con un sacco di contenuti di archivio). Se ritieni di dover aumentare vfs_cache_pressure
oltre i 100 stai funzionando senza abbastanza RAM. L'aumento vfs_cache_pressure
può aiutare, ma l'unica vera soluzione è ottenere più RAM. L' vfs_cache_pressure
impostazione su un numero elevato sacrifica le prestazioni medie per avere prestazioni complessivamente più stabili (vale a dire, è possibile evitare comportamenti peggiori nel caso peggiore, ma è necessario affrontare prestazioni complessive peggiori).
Infine, chiedi al kernel di usare fino al 99% della RAM come cache per le scritture e di indicare al kernel di usare fino al 50% di RAM prima di rallentare il processo che sta scrivendo (il valore predefinito dirty_background_ratio
è 10
). Avviso: personalmente non lo farei ma tu hai affermato di avere abbastanza RAM e sei disposto a perdere i dati.
echo 99 > /proc/sys/vm/dirty_ratio
echo 50 > /proc/sys/vm/dirty_background_ratio
E dì che 1h di ritardo di scrittura è ok anche per iniziare a scrivere cose sul disco (di nuovo, non lo farei):
echo 360000 > /proc/sys/vm/dirty_expire_centisecs
echo 360000 > /proc/sys/vm/dirty_writeback_centisecs
Se metti tutti questi /etc/rc.local
e includi il seguito alla fine, tutto sarà nella cache il più presto possibile dopo l'avvio (fallo solo se il tuo filesystem si adatta davvero alla 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)&
O un'alternativa un po 'più semplice che potrebbe funzionare meglio (solo cache /home
e /usr
, fallo solo se il tuo /home
e /usr
si adatta davvero alla RAM):
(nice find /home /usr -type f -print0 | nice ionice -c 3 wc -l --files0-from - > /dev/null)&