GNU/Linux >> Linux Esercitazione >  >> Linux

Linux:configurare il sistema Linux per una memorizzazione nella cache del file system più aggressiva?

Non sono preoccupato per l'utilizzo della RAM (dato che ne ho abbastanza) né per la perdita di dati in caso di arresto accidentale (poiché la mia alimentazione è supportata, il sistema è affidabile e i dati non sono critici). Ma elaboro molto file e potrei usare un po' di miglioramento delle prestazioni.

Ecco perché vorrei impostare il sistema in modo da utilizzare più RAM per la lettura e la scrittura nella cache del file system, per precaricare i file in modo aggressivo (ad es. read-ahead dell'intero file a cui si accede da un'applicazione nel caso in cui il file sia di dimensioni normali o almeno leggere in anticipo una grossa fetta altrimenti) e svuotare i buffer di scrittura meno frequentemente. Come raggiungere questo obiettivo (potrebbe essere possibile)?

Uso i file system ext3 e ntfs (uso molto ntfs!) con XUbuntu 11.10 x86.

Risposta accettata:

Migliorare le prestazioni della cache del disco in generale è più che aumentare le dimensioni della cache del file system a meno che il tuo intero il sistema si adatta alla RAM, nel qual caso dovresti usare l'unità RAM (tmpfs va bene perché consente di eseguire il fallback su disco se in alcuni casi è necessaria la RAM) per l'archiviazione di runtime (e forse uno script initrd per copiare il sistema dalla memoria all'unità RAM all'avvio).

Non hai detto se il tuo dispositivo di archiviazione è SSD o HDD. Ecco cosa ho scoperto che funziona per me (nel mio caso sda è un HDD montato su /home e sdb è SSD montato su / ).

In primo luogo, ottimizza la parte di caricamento delle cose dallo storage alla cache:

Ecco la mia configurazione per HDD (assicurati che AHCI+NCQ sia abilitato nel BIOS se hai interruttori):

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

Degno di nota per la custodia dell'HDD è l'alto fifo_expire_async (di solito scrivi) e slice_sync lungo per consentire a un singolo processo di ottenere un throughput elevato (impostare slice_sync a 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 gli HDD, ma impostarlo da qualche parte nell'intervallo 3-20 dovrebbe andare bene a seconda dell'utilizzo del disco e del firmware del disco. Preferisco puntare a valori bassi, ma impostarlo su un valore troppo basso distruggerà il tuo throughput. Il quantum l'impostazione sembra influenzare molto il throughput, ma cerca di mantenerlo il più basso possibile per mantenere la latenza a un livello ragionevole. Impostazione di quantum troppo basso distruggerà il throughput. I valori nell'intervallo 3-8 sembrano funzionare bene con gli HDD. La latenza peggiore per una lettura è (quantum * slice_sync ) + (slice_async_rq * slice_async ) ms se ho compreso correttamente il comportamento del kernel. L'async è utilizzato principalmente dalle scritture e poiché sei disposto a ritardare la scrittura su disco, imposta entrambi slice_async_rq e slice_async a numeri molto bassi. Tuttavia, impostando slice_async_rq un valore troppo basso può bloccare le letture perché le scritture non possono più essere ritardate dopo le letture. La mia configurazione proverà a scrivere i dati su disco al massimo dopo 10 secondi dopo che i dati sono stati passati al kernel, ma poiché puoi tollerare la perdita di dati in caso di interruzione dell'alimentazione, imposta anche fifo_expire_async a 3600000 per dire che 1 ora va bene per il ritardo su disco. Tieni solo slice_async basso, però, perché altrimenti puoi ottenere un'elevata latenza di lettura.

Il hdparm il comando è necessario per evitare che AAM uccida 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 delle sezioni. L'impostazione più importante per un SSD è slice_idle che deve essere impostato su 0-1. Impostandolo su zero si spostano tutte le decisioni di ordinamento su NCQ nativo, mentre impostandolo su 1 si 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 la serie Intel 320, sembra che l'impostazione slide_idle a fornisce il miglior throughput ma impostandolo su 1 offre la migliore (bassa) latenza complessiva.

Per ulteriori informazioni su questi sintonizzabili, vedere https://www.kernel.org/doc/Documentation/block/cfq-iosched.txt .

Aggiornamento nell'anno 2020 e versione del kernel 5.3 (cfq è morto):

modprobe bfq
for d in /sys/block/sd?
do
        # HDD (tuned for Seagate SMR drive)
        echo bfq > "$d/queue/scheduler"
        echo 4 > "$d/queue/nr_requests"
        echo 32000 > "$d/queue/iosched/back_seek_max"
        echo 3 > "$d/queue/iosched/back_seek_penalty"
        echo 80 > "$d/queue/iosched/fifo_expire_sync"
        echo 1000 > "$d/queue/iosched/fifo_expire_async"
        echo 5300 > "$d/queue/iosched/slice_idle_us"
        echo 1 > "$d/queue/iosched/low_latency"
        echo 200 > "$d/queue/iosched/timeout_sync"
        echo 0 > "$d/queue/iosched/max_budget"
        echo 1 > "$d/queue/iosched/strict_guarantees"

        # additional tweaks for SSD (tuned for Samsung EVO 850):
        if test $(cat "$d/queue/rotational") = "0"
        then
                echo 36 > "$d/queue/nr_requests"
                echo 1 > "$d/queue/iosched/back_seek_penalty"
                # slice_idle_us should be ~ 0.7/IOPS in µs
                echo 16 > "$d/queue/iosched/slice_idle_us"
                echo 10 > "$d/queue/iosched/fifo_expire_sync"
                echo 250 > "$d/queue/iosched/fifo_expire_async"
                echo 10 > "$d/queue/iosched/timeout_sync"
                echo 0 > "$d/queue/iosched/strict_guarantees"
        fi
done

La configurazione è abbastanza simile ma ora uso bfq invece di cfq perché quest'ultimo non è disponibile con i kernel moderni. Cerco di mantenere nr_requests il più basso possibile per consentire bfq per controllare la programmazione in modo più accurato. Almeno le unità SSD Samsung sembrano richiedere una coda piuttosto profonda per essere in grado di funzionare con IOPS elevati.

Correlati:come analizzare un segmento di un file audio con sox?

Sto usando Ubuntu 18.04 con il pacchetto kernel linux-lowlatency-hwe-18.04-edge che ha bfq solo come modulo quindi devo caricarlo prima di poterlo passare.

Al giorno d'oggi uso anche zram ma uso solo il 5% della RAM per zram. Ciò consente al kernel Linux di utilizzare la logica relativa allo scambio senza toccare i dischi. Tuttavia, se decidi di utilizzare zero disk swap, assicurati che le tue app non perdano RAM o stai sprecando denaro.

Ora che abbiamo configurato il kernel per caricare materiale dal disco alla cache con prestazioni ragionevoli, è il momento di regolare il comportamento della cache:

Secondo i benchmark che ho fatto, non mi preoccuperei di impostare la lettura in anticipo tramite blockdev affatto. Le impostazioni predefinite del kernel vanno bene.

Imposta il sistema in modo che preferisca scambiare i dati del file rispetto al codice dell'applicazione (questo non importa se hai abbastanza RAM per mantenerlo 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 applicazioni diverse rispetto alla latenza per l'accesso a file di grandi dimensioni da una singola applicazione:

echo 15 > /proc/sys/vm/swappiness

Se preferisci mantenere le applicazioni quasi sempre nella RAM, puoi impostarlo su 1. Se lo imposti su zero, il kernel non si scambierà affatto a meno che non sia assolutamente necessario per evitare OOM. Se avevi una memoria limitata e lavoravi con file di grandi dimensioni (ad es. editing video HD), potrebbe avere senso impostarlo vicino a 100.

Al giorno d'oggi (2017) preferisco non avere alcuno scambio se hai abbastanza RAM. Non avere alcuno scambio di solito perderà 200-1000 MB di RAM su una macchina desktop di lunga durata. Sono disposto a sacrificare così tanto per evitare la latenza dello scenario peggiore (scambio del codice dell'applicazione quando la RAM è piena). In pratica, questo significa che preferisco OOM Killer allo scambio. Se consenti/hai bisogno di scambiare, potresti voler aumentare /proc/sys/vm/watermark_scale_factor anche per evitare una certa latenza. Suggerirei valori compresi tra 100 e 500. Puoi considerare questa impostazione come scambiare l'utilizzo della CPU per una latenza di scambio inferiore. Il valore predefinito è 10 e il massimo possibile è 1000. Un valore più alto dovrebbe (secondo la documentazione del kernel) comportare un maggiore utilizzo della CPU per kswapd processi e una minore latenza di scambio complessiva.

Quindi, dì al kernel di preferire mantenere la gerarchia delle directory in memoria rispetto al contenuto del file nel caso in cui sia necessario liberare della RAM (di nuovo, se tutto si adatta alla RAM, questa impostazione non fa nulla):

echo 10 > /proc/sys/vm/vfs_cache_pressure

Impostazione di vfs_cache_pressure un valore basso ha senso perché nella maggior parte dei casi, il kernel ha bisogno di 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 dei file quasi inutile. Considera di scendere fino a 1 con questa impostazione se hai molti file di piccole dimensioni (il mio sistema ha circa 150.000 foto da 10 megapixel e conta come sistema "molti file di piccole dimensioni"). Non impostarlo mai su zero o la struttura delle directory viene sempre conservata in memoria anche se il sistema sta esaurendo la memoria. Impostarlo su un valore grande è sensato solo se hai solo pochi file di grandi dimensioni che vengono costantemente riletti (di nuovo, l'editing video HD senza RAM sufficiente sarebbe un caso di esempio). La documentazione ufficiale del kernel afferma che "l'aumento di vfs_cache_pressure significativamente oltre 100 può avere un impatto negativo sulle prestazioni".

Eccezione: se hai una quantità davvero enorme di file e directory e raramente tocchi/ leggi/elenchi tutti i file impostando vfs_cache_pressure superiore a 100 può essere saggio. Ciò si applica solo se non si dispone di RAM sufficiente e non è possibile mantenere l'intera struttura della directory nella RAM e se si dispone ancora di RAM sufficiente per la normale cache di file e processi (ad es. file server a livello aziendale con molto contenuto di archivio). Se ritieni di dover aumentare vfs_cache_pressure sopra 100 stai eseguendo senza RAM sufficiente. vfs_cache_pressure in aumento può aiutare, ma l'unica vera soluzione è ottenere più RAM. Avere vfs_cache_pressure impostato su un numero alto sacrifica le prestazioni medie per avere prestazioni complessive più stabili (ovvero, puoi evitare comportamenti pessimi nel peggiore dei casi ma devi affrontare prestazioni complessive peggiori).

Correlati:come configurare il ripristino dello schermo in un terminale?

Infine, chiedi al kernel di utilizzare fino al 99% della RAM come cache per le scritture e indica al kernel di utilizzare fino al 50% della RAM prima di rallentare il processo di scrittura (impostazione predefinita per dirty_background_ratio è 10 ). Attenzione:personalmente non lo farei, ma 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 di' che 1 ora di ritardo in scrittura va bene anche per iniziare 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

Per ulteriori informazioni su questi sintonizzabili, vedere https://www.kernel.org/doc/Documentation/sysctl/vm.txt

Se li metti tutti in /etc/rc.local e includi il seguito alla fine, tutto sarà nella cache il prima 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 davvero in forma nella RAM):

(nice find /home /usr -type f -print0 | nice ionice -c 3 wc -l --files0-from - > /dev/null)&

Linux
  1. Come formattare le partizioni del disco in Linux

  2. Introduzione al file system Linux

  3. Come aumentare il numero di inode del disco in Linux

  4. Qual è l'equivalente del comando File Linux per Windows?

  5. Linux:dove mettere il file di scambio

Le 20 migliori alternative a Notepad++ per il sistema Linux

I 15 migliori sistemi di gestione dei documenti per il sistema Linux

I 10 strumenti di navigazione dei file open source per il sistema Linux

I 10 migliori strumenti di notifica della posta per il sistema Linux

I 15 migliori strumenti di crittografia della posta elettronica per il sistema Linux

I 10 migliori software Wiki self-hosted per il sistema Linux