Dlaczego ustawienie arc_max nie jest honorowane w ZFS w systemie Linux?

20

Korzystam z ZoL 0.6.2 z ich PPA na Ubuntu 12.04. Jest na hoście z 16 GB pamięci przeznaczonej do uruchamiania niektórych maszyn wirtualnych za pomocą KVM / Libvirt. Po pewnym czasie ZoL używa szalonej ilości pamięci, osiągając 98% wykorzystania pamięci RAM przy uruchomionych niektórych maszynach wirtualnych. Powoduje to, że nowe procesy odmawiają uruchomienia „nie można przydzielić pamięci”. Nie mogę nawet uruchomić wszystkich moich maszyn wirtualnych, które przed użyciem ZFS używały około 40-50% pamięci RAM.

O ile rozumiem, bez poprawiania, ZoL powinien zwolnić pamięć, gdy tylko w systemie zabraknie pamięci. Tak nie jest. Postanowiłem więc ustawić to arc_maxustawienie na 1 GB.

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

Mimo to nie zwalnia żadnej pamięci.

Jak widać z poniższych statystyk ARC, zużywa więcej pamięci niż jest skonfigurowane (porównaj c= 7572030912z c_max= 1073741824).

Co ja tu robię źle?

# 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
gertvdijk
źródło

Odpowiedzi:

22

IMHO parametry w / sys / module / zfs / parameters można ustawić tylko na 0/ 1- disabled/ enabled. ” Korekta: zależy od parametru

Jestem w tej samej łodzi, która chce ograniczyć użycie pamięci ZFS i wydaje się, że trzeba utworzyć plik /etc/modprobe.d/zfs.conf i wprowadzić tam parametr oraz żądaną wartość. Ta zmiana zacznie obowiązywać po ponownym uruchomieniu.

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

Aby wywołać działający moduł, można zmienić parametr zfs_arc_max.

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

Należy zwrócić uwagę na użycie >do zastąpienia zawartości pliku w przeciwieństwie do dodawania do pliku za pomocą >>.

źródło: /programming//a/18808311

Tobias F. Meier
źródło
1
Łuk ZFS nie kurczy się natychmiast. Jednak (ZFSonLinux) jest odzyskiwany, podczas gdy aplikacje przydzielają tę pamięć - jak zwykle. Jeśli potrzebujesz czegoś, co zajmie się pamięcią, być może zajrzyj na github.com/hilbix/killmem (tylko 8K po make static; strip -s killmem)
Tino
W systemie Ubuntu 16.04 musiałem uruchomić się update-initramfs -u -k allprzed ponownym uruchomieniem, aby /etc/modprobe.d/zfs.confrozpowszechnić te ustawienia .
lechup 15.07.17
@lechup: Na Ubuntu 16.04 dodałem options zfs zfs_vdev_scheduler=cfqdo mojego /etc/modprobe.d/zfs.conf . Uruchomiłem się ponownie i zadziałało; program planujący był teraz cfq zamiast noop . Czy potrafisz wyjaśnić, dlaczego update-initramfs -u -k alljest to konieczne?
Martin Velez
@MartinVelez Wiem, że to dziwne, ale bez niego zmiany na moim komputerze nie były propagowane po ponownym uruchomieniu ... Próbowałem popagate inną opcję zfs_arc_maxmoże ten klucz jest w jakiś sposób buforowany w initramfs?
lechup
4

Po zmodyfikowaniu rozmiaru łuku musisz upuścić swoje pamięci podręczne.

echo 3 > /proc/sys/vm/drop_caches

i poczekaj (twój monit nie wróci natychmiast, ale inne procesy będą nadal działać). Powoli zwolni pamięć podręczną (2,5 minuty dla mojej pamięci podręcznej 24 GB na 2 pary raidów 1'd 2 TB WD Blacks na 4-letnim procesorze 2 GHz w pudełku o pojemności 64 GB) - uważaj, nagle nie będziesz mieć żadnych pamięci podręcznych i żadnych procesy odczytujące dane będą pobierać surowy dysk, więc prawdopodobnie zobaczysz, że IO czeka na chwilę, aż pamięć podręczna zostanie ponownie zapełniona.

matematyka
źródło
A, fajnie! Czy możesz wyjaśnić, dlaczego „3” jako wartość, którą należy zapisać w tym wpisie procfs?
gertvdijk
Wyczyść tylko PageCache: # sync; echo 1 > /proc/sys/vm/drop_caches Wyczyść dentries i i-węzły: # sync; echo 2 > /proc/sys/vm/drop_caches Wyczyść PageCache, dentries i i-węzły:# sync; echo 3 > /proc/sys/vm/drop_caches
matematyka
2

Jednym z problemów, na które możesz wpaść, jest buforowanie plików maszyny wirtualnej przez ZFS (dyski wirtualne). Aby tego uniknąć, zawsze ustawiam właściwość primarycache na „metadane” w systemach plików zawierających dyski wirtualne.

Logika polega na tym, że system operacyjny gościa lepiej podpowiada, które obszary jego dysków mają być buforowane.

Pavka1
źródło
0

AFAIK musi zostać spełniony jeden z poniższych warunków, aby dostosować parametr.

  1. W działającym systemie: wyeksportuj wszystkie zpools, usuń moduły ZFS, ponownie włącz moduł ZFS (zgodnie z definicją nie można tego zrobić, jeśli / jest na ZFS).
  2. Ponownie wygeneruj obraz initramfs podczas zmiany parametru, aby po ponownym uruchomieniu zadziałał. Jest to potrzebne, ponieważ lokalizacja pliku zfs.conf nie jest jeszcze zamontowana w tym momencie w procesie uruchamiania.
Sam
źródło
0

Masz jeden dodatkowy „ >” za dużo.

Polecenie powinno być

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

nie „ >>

>>oznacza „dodaj do” (istniejąca lista).
>oznacza „zastąp” (wartość).

Dlatego kod polecenia w twoim pytaniu nie będzie działać.

Hipokryt
źródło
To była już część przyjętej odpowiedzi. serverfault.com/a/602457/135437
gertvdijk
Ten post jest zawiłym bałaganem, panie Downvotes. Autor mówi cały szereg rzeczy, dotykając tylko poprawnej odpowiedzi pod koniec bałaganu, nie stwierdzając „to jest powód” lub równoważny. Tak zawiłe, że nie otrzymałem odpowiedzi z tego postu. Widziałem powód pytania. Mój post został oceniony z jakiegoś powodu.
Hipokrytus,