Por que a configuração arc_max não é respeitada no ZFS no Linux?

20

Estou executando o ZoL 0.6.2 do PPA deles no Ubuntu 12.04. Está em um host com 16 GB de memória destinado a executar algumas VMs usando KVM / Libvirt. Depois de algum tempo, o ZoL está usando uma quantidade insana de memória, atingindo 98% do uso de RAM com algumas VMs em execução. Isso resulta em novos processos que se recusam a iniciar "não é possível alocar memória". Não consigo nem mais iniciar todas as minhas VMs que antes de usar o ZFS estavam usando cerca de 40-50% da RAM.

Tanto quanto eu entendo, sem mexer, o ZoL deve liberar memória assim que o sistema estiver com pouca memória. Bem, não. Então, eu decidi definir a arc_maxconfiguração para 1 GB.

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

Ainda assim, ele não libera nenhuma memória.

Como você pode ver nas estatísticas abaixo do ARC, ele está usando mais memória do que o configurado (compare c= 7572030912com c_max= 1073741824).

O que eu estou fazendo errado aqui?

# 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
fonte

Respostas:

22

IMHO os parâmetros em / sys / module / zfs / parameters podem ser definidos apenas para 0/ 1- disabled/ enabled. " Correção: depende do parâmetro

Estou no mesmo barco que deseja limitar o uso de memória do zfs e parece que é necessário criar um arquivo /etc/modprobe.d/zfs.conf e inserir o parâmetro e o valor desejado. Essa alteração entrará em vigor após a reinicialização.

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

Para efetuar o módulo em execução, é possível alterar o parâmetro zfs_arc_max.

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

Observe o uso de >para substituir o conteúdo do arquivo, ao contrário de adicionar ao arquivo >>.

fonte: /programming//a/18808311

Tobias F. Meier
fonte
11
O arco do ZFS não diminui imediatamente. No entanto (ZFSonLinux), ele é recuperado enquanto os aplicativos alocam essa memória - como de costume. Se você precisa de algo para suínos na memória, talvez ter um olhar para github.com/hilbix/killmem (apenas 8K depois make static; strip -s killmem)
Tino
No Ubuntu 16.04, eu precisava executar update-initramfs -u -k allantes da reinicialização para que essas configurações /etc/modprobe.d/zfs.conffossem propagadas.
Lechup
@lechup: No Ubuntu 16.04, adicionei options zfs zfs_vdev_scheduler=cfqao meu /etc/modprobe.d/zfs.conf . Eu reiniciei e funcionou; o agendador agora era cfq em vez de noop . Você pode explicar por que update-initramfs -u -k allé necessário?
Martin Velez
@MartinVelez Eu sei que é estranho, mas sem ele na minha máquina as alterações não foram propagadas após a reinicialização ... Eu estava tentando exibir outra opção, zfs_arc_maxtalvez essa chave esteja de alguma forma armazenada em cache no initramfs?
Lechup
4

Depois de modificar o tamanho do seu arco, você precisa eliminar seus caches.

echo 3 > /proc/sys/vm/drop_caches

e aguarde (seu prompt não retornará imediatamente, mas outros processos continuarão em execução). Ele descarregará lentamente os caches (2,5 min para o meu cache de 24 GB em 2 pares de pretos WD de 2 TB de ataque 1D em um processador de 2Ghz de 4 anos em uma caixa com 64GB) - cuidado, você de repente não terá caches e os processos de leitura de dados extraem o disco bruto; portanto, você provavelmente verá a espera de E / S aumentar por um tempo até que o cache seja preenchido novamente.

matemática
fonte
Ah legal! Você poderia explicar por que o '3' como um valor para gravar nessa entrada do procfs?
gertvdijk
Limpar somente PageCache: # sync; echo 1 > /proc/sys/vm/drop_caches limpar dentries e inodes: # sync; echo 2 > /proc/sys/vm/drop_caches Limpar PageCache, dentries e inodes:# sync; echo 3 > /proc/sys/vm/drop_caches
math
2

Um problema em que você pode estar se metendo é o ZFS armazenando em cache os arquivos da máquina virtual (discos virtuais). Para evitar que eu sempre defina a propriedade primarycache como "metadados" em sistemas de arquivos que contêm discos virtuais.

A lógica é que o sistema operacional convidado tem mais dicas sobre quais áreas de seus discos armazenar em cache.

Pavka1
fonte
0

AFAIK, uma das seguintes condições deve ser atendida para adaptar o parâmetro.

  1. Em um sistema em execução: exporte todos os zpools, remova os módulos zfs, reative o módulo zfs (por definição, isso não pode ser feito se / estiver no zfs).
  2. Gere novamente a imagem initramfs ao alterar o parâmetro para que, após uma reinicialização, ele funcione. Isso é necessário, pois o local do arquivo zfs.conf ainda não está montado naquele momento no processo de inicialização.
Sam
fonte
0

Você tem um extra " >" a mais.

O comando deve ser

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

não " >>"

>>significa "adicionar a" (lista existente).
>significa "substituir" (valor).

É por isso que o código de comando na sua pergunta não funcionará.

Hipócrito
fonte
Isso já fazia parte da resposta aceita presente. serverfault.com/a/602457/135437
gertvdijk
Esse post é uma bagunça complicada, Sr. Downvotes. O autor diz um monte de coisas, apenas tocando a resposta correta ao passar perto do fim da bagunça, sem afirmar: "esse é o motivo" ou equivalente. Tão complicado, que não recebi minha resposta desse post. Eu vi o motivo da pergunta. Minha postagem foi votada por um motivo.
Hipócrito