Perché l'impostazione arc_max non è onorata su ZFS su Linux?


20

Sto eseguendo ZoL 0.6.2 dal loro PPA su Ubuntu 12.04. È su un host con 16 GB di memoria destinato a eseguire alcune macchine virtuali utilizzando KVM / Libvirt. Dopo un po 'di tempo ZoL utilizza una quantità folle di memoria, raggiungendo il 98% dell'utilizzo della RAM con alcune VM in esecuzione. Ciò comporta nuovi processi che si rifiutano di avviare "impossibile allocare memoria". Non riesco nemmeno più ad avviare tutte le mie macchine virtuali che prima di utilizzare ZFS utilizzavano circa il 40-50% di RAM.

A quanto ho capito, senza modificare, ZoL dovrebbe liberare memoria non appena il sistema ha poca memoria. Beh, non lo fa. Quindi ho deciso di impostare l' arc_maximpostazione su 1 GB.

# echo 1073741824 >> /sys/module/zfs/parameters/zfs_arc_max

Tuttavia, non rilascia alcuna memoria.

Come puoi vedere dalle statistiche ARC di seguito, utilizza più memoria di quella su cui è configurato (confronta c= 7572030912con c_max= 1073741824).

Cosa sto facendo di sbagliato qui?

# cat /proc/spl/kstat/zfs/arcstats
4 1 0x01 84 4032 43757119584 392054268420115
name                            type data
hits                            4    28057644
misses                          4    13975282
demand_data_hits                4    19632274
demand_data_misses              4    571809
demand_metadata_hits            4    6333604
demand_metadata_misses          4    289110
prefetch_data_hits              4    1903379
prefetch_data_misses            4    12884520
prefetch_metadata_hits          4    188387
prefetch_metadata_misses        4    229843
mru_hits                        4    15390332
mru_ghost_hits                  4    1088944
mfu_hits                        4    10586761
mfu_ghost_hits                  4    169152
deleted                         4    35432344
recycle_miss                    4    701686
mutex_miss                      4    35304
evict_skip                      4    60416647
evict_l2_cached                 4    0
evict_l2_eligible               4    3022396862976
evict_l2_ineligible             4    1602907651584
hash_elements                   4    212777
hash_elements_max               4    256438
hash_collisions                 4    17163377
hash_chains                     4    51485
hash_chain_max                  4    10
p                               4    1527347963
c                               4    7572030912
c_min                           4    1038188800
c_max                           4    1073741824
size                            4    7572198224
hdr_size                        4    66873056
data_size                       4    7496095744
other_size                      4    9229424
anon_size                       4    169150464
anon_evict_data                 4    0
anon_evict_metadata             4    0
mru_size                        4    1358216192
mru_evict_data                  4    1352400896
mru_evict_metadata              4    508928
mru_ghost_size                  4    6305992192
mru_ghost_evict_data            4    4919159808
mru_ghost_evict_metadata        4    1386832384
mfu_size                        4    5968729088
mfu_evict_data                  4    5627991552
mfu_evict_metadata              4    336846336
mfu_ghost_size                  4    1330455552
mfu_ghost_evict_data            4    1287782400
mfu_ghost_evict_metadata        4    42673152
l2_hits                         4    0
l2_misses                       4    0
l2_feeds                        4    0
l2_rw_clash                     4    0
l2_read_bytes                   4    0
l2_write_bytes                  4    0
l2_writes_sent                  4    0
l2_writes_done                  4    0
l2_writes_error                 4    0
l2_writes_hdr_miss              4    0
l2_evict_lock_retry             4    0
l2_evict_reading                4    0
l2_free_on_write                4    0
l2_abort_lowmem                 4    0
l2_cksum_bad                    4    0
l2_io_error                     4    0
l2_size                         4    0
l2_asize                        4    0
l2_hdr_size                     4    0
l2_compress_successes           4    0
l2_compress_zeros               4    0
l2_compress_failures            4    0
memory_throttle_count           4    0
duplicate_buffers               4    0
duplicate_buffers_size          4    0
duplicate_reads                 4    0
memory_direct_count             4    66583
memory_indirect_count           4    7657293
arc_no_grow                     4    0
arc_tempreserve                 4    0
arc_loaned_bytes                4    0
arc_prune                       4    0
arc_meta_used                   4    427048272
arc_meta_limit                  4    2076377600
arc_meta_max                    4    498721632

# free -m
             total       used       free     shared    buffers     cached
Mem:         15841      15385        456          0         75         74
-/+ buffers/cache:      15235        606
Swap:            0          0          0

Risposte:


22

IMHO i parametri in / sys / module / zfs / parametri possono essere impostati solo su 0/ 1- disabled/ enabled. " Correzione: dipende dal parametro

Sono nella stessa barca che desidera limitare l'utilizzo della memoria di zfs e sembra che si debba creare un file /etc/modprobe.d/zfs.conf e inserire il parametro e il valore desiderato. Questa modifica avrà effetto al riavvio.

echo "options zfs zfs_arc_max=34359738368" >> /etc/modprobe.d/zfs.conf

Per effettuare il modulo in esecuzione è possibile modificare il parametro zfs_arc_max.

echo "34359738368" > /sys/module/zfs/parameters/zfs_arc_max

Si noti l'uso di >per sostituire il contenuto del file in contrasto con l'aggiunta al file con >>.

fonte: /programming//a/18808311


1
L'arco ZFS non si restringe immediatamente. Tuttavia (ZFSonLinux) viene recuperato mentre le applicazioni allocano quella memoria - come al solito. Se hai bisogno di qualcosa da tenere a memoria, forse dai un'occhiata a github.com/hilbix/killmem (solo 8K dopo make static; strip -s killmem)
Tino

Su Ubuntu 16.04 dovevo eseguire update-initramfs -u -k allprima di riavviare per /etc/modprobe.d/zfs.confpropagare queste impostazioni .
Lechup,

@lechup: su Ubuntu 16.04, ho aggiunto options zfs zfs_vdev_scheduler=cfqal mio /etc/modprobe.d/zfs.conf . Ho riavviato e ha funzionato; lo scheduler era ora cfq anziché noop . Puoi spiegare perché update-initramfs -u -k allè necessario?
Martin Velez,

@MartinVelez So che è strano ma senza di esso sul mio computer le modifiche non sono state propagate dopo il riavvio ... Stavo cercando di popolare diverse opzioni zfs_arc_maxforse questa chiave è in qualche modo memorizzata nella cache in initramfs?
Lechup,


4

Una volta modificata la dimensione dell'arco, è necessario eliminare le cache.

echo 3 > /proc/sys/vm/drop_caches

e attendi (il tuo prompt non tornerà immediatamente, ma altri processi continueranno a essere eseguiti). Scaricherà lentamente le cache (2,5 min per la mia cache da 24 GB su 2 paia di raid neri da 2 TB WD neri su una CPU di 4 anni da 2 Ghz su una scatola da 64 GB) - attenzione, improvvisamente non avrai cache e qualsiasi i processi di lettura dei dati verranno estratti dal disco non elaborato, quindi probabilmente vedrai IO aspettare saltare per un po 'finché la cache non viene ripopolata.


Ah, bello! Potresti spiegare perché il '3' come valore da scrivere in quella voce procfs?
gertvdijk,

Cancella solo PageCache: # sync; echo 1 > /proc/sys/vm/drop_caches cancella dentifrici e inode: # sync; echo 2 > /proc/sys/vm/drop_caches cancella PageCache, dentifrici e inode:# sync; echo 3 > /proc/sys/vm/drop_caches
matematica

2

Un problema in cui potresti cadere è ZFS che memorizza nella cache i file della macchina virtuale (dischi virtuali). Per evitare ciò, ho sempre impostato la proprietà primarycache su "metadati" su filesystem contenenti dischi virtuali.

La logica è che il SO guest ha un suggerimento migliore su quali aree dei suoi dischi memorizzare nella cache.


0

AFAIK è necessario soddisfare una delle seguenti condizioni per adattare il parametro.

  1. Su un sistema in esecuzione: esporta tutti gli zpools, rimuovi i moduli zfs, riattiva il modulo zfs (per definizione questo non può essere fatto se / è su zfs).
  2. Rigenerare l'immagine initramfs quando si modifica il parametro, quindi dopo un riavvio funzionerà. Ciò è necessario poiché il percorso del file zfs.conf non è ancora stato montato in quel momento nel processo di avvio.

0

Ne hai uno " >" in più.

Il comando dovrebbe essere

echo 1073741824 > /sys/module/zfs/parameters/zfs_arc_max

non " >>"

>>significa "aggiungi a" (elenco esistente).
>significa "sovrascrivi" (valore).

Questo è il motivo per cui il codice comando nella tua domanda non funzionerà.


Questo faceva già parte della risposta accettata presente. serverfault.com/a/602457/135437
gertvdijk il

Quel post è un disastro contorto, Mr. Downvotes. L'autore dice un'intera serie di cose, toccando solo la risposta corretta passando vicino alla fine del pasticcio, senza dichiarare, "questa è la ragione" o equivalente. Così contorto, che non ho ricevuto la mia risposta da quel post. Ho visto il motivo della domanda. Il mio post è stato votato per un motivo.
Ipocrito,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.