Skip to content

Diagnóstico e Tuning de ARC/L2ARC no ZFS

PROPÓSITO

Entender se o cache do ZFS está ajudando e onde ele está falhando, antes de mexer em qualquer parâmetro.

Quando usar: Quando um pool está lento, ao avaliar se um L2ARC compensa, ou ao dimensionar a RAM de um servidor de armazenamento.

Pré-requisitos: TrueNAS SCALE ou OpenZFS com acesso ao shell.

1. Objetivo

Este documento descreve como avaliar a eficiência de cache do ZFS em ambientes TrueNAS SCALE, com foco em:

  • ARC em RAM;

  • L2ARC em SSD/NVMe;

  • hits e misses;

  • Demand Data;

  • MRU e MFU;

  • pressão de memória;

  • poluição/churn do L2ARC;

  • correlação entre as métricas;

  • critérios para decidir quando realizar tuning.

O objetivo principal não é obter o maior ARC hit ratio possível, mas reduzir acessos desnecessários ao pool físico e garantir baixa latência para as aplicações.


2. Caminho de uma leitura

De forma simplificada:

bash
Aplicação / VM
      |
      v
+-----------+
|    ARC    |  RAM
+-----------+
      |
     MISS
      |
      v
+-----------+
|   L2ARC   |  SSD / NVMe
+-----------+
      |
     MISS
      |
      v
+-----------+
| ZFS POOL  |  HDD / RAIDZ
+-----------+

O melhor cenário é:

bash
Aplicação
   |
   v
ARC HIT
   |
   v
RAM

O cenário mais caro é:

bash
Aplicação
   |
   v
ARC MISS
   |
   v
L2ARC MISS
   |
   v
POOL

3. ARC

O que é

ARC — Adaptive Replacement Cache — é o cache principal do ZFS e fica armazenado em RAM.

É a camada de cache mais rápida.

Exemplo:

text
ARC atual: 397 GiB
ARC máximo: 400 GiB

Isso significa que o ZFS está utilizando aproximadamente 397 GiB dos 400 GiB permitidos.

O que observar

Principalmente:

text
ARC demand data accesses
Demand data hits
Demand data misses

O ARC total accesses deve ser considerado apenas como contexto.


4. ARC Total x Demand Data

ARC Total

Inclui:

  • Demand Data;

  • Demand Metadata;

  • Prefetch Data;

  • Prefetch Metadata;

  • outros acessos internos.

Exemplo:

text
ARC total hits:   72%
ARC total misses: 27%

Esse número pode enganar.

Metadata normalmente possui hit rate próximo de 100%, elevando artificialmente o percentual geral.


Demand Data

Representa leituras realmente solicitadas pelas aplicações:

  • máquinas virtuais;

  • bancos de dados;

  • NFS;

  • SMB;

  • iSCSI;

  • containers;

  • aplicações.

Exemplo:

text
Demand data hits:   65%
Demand data misses: 33%

Para análise de performance,Demand Data deve ter prioridade sobre ARC Total.


5. Hit e Miss

Hit

Um hit significa que o dado foi encontrado no cache.

text
Aplicação
   |
   v
ARC
   |
  HIT

Não foi necessário buscar o dado em uma camada mais lenta.

Em geral:

text
mais HIT = melhor

Miss

Um miss significa que o dado procurado não estava naquela camada de cache.

Exemplo:

text
ARC MISS
   |
   v
L2ARC

Ou:

text
L2ARC MISS
   |
   v
POOL

Em geral:

text
menos MISS = melhor

6. Threshold sugerido para Demand Data Miss

Os valores abaixo são referências práticas e não limites oficiais do OpenZFS.

Demand Data MissAvaliação
0–2%EXCELENTE
>2–5%BOM
>5–10%ATENÇÃO
>10%RUIM

Um valor elevado significa que o ARC não consegue manter em RAM uma parcela importante do working set demandado pelas aplicações.


7. L2ARC

O que é

L2ARC é o segundo nível de cache do ZFS.

Normalmente utiliza:

  • SSD;

  • NVMe.

O L2ARC é:

text
mais lento que RAM
mais rápido que HDD/RAIDZ

Sua função é receber dados que saíram do ARC e permitir que futuras leituras evitem acesso ao pool principal.


8. L2ARC Hit Ratio

Exemplo:

text
L2ARC hits:   30%
L2ARC misses: 70%

Significa que, entre as consultas feitas ao L2ARC:

text
30% encontraram o dado no SSD
70% precisaram continuar para outra camada

Threshold prático:

L2ARC HitAvaliação
>= 40%EXCELENTE
25–40%BOM
10–25%ATENÇÃO
<10%RUIM

Esses valores devem ser interpretados junto com Demand Data.


9. MRU e MFU

MRU

MRU significa:

text
Most Recently Used

São dados acessados recentemente.

Muito MRU no L2ARC pode indicar dados de passagem com pouca reutilização.

Exemplo:

text
MRU: 98%
MFU:  1%

MRU alto isoladamente não é necessariamente problema.


MFU

MFU significa:

text
Most Frequently Used

São dados acessados repetidamente.

Em geral, dados MFU são candidatos valiosos para permanecer no cache.


10. Poluição e churn

Pode haver poluição do L2ARC quando existe a combinação:

text
MRU muito alto
+
L2ARC hit baixo
+
muitos writes
+
MFU muito baixo

Churn significa que dados entram e saem do L2ARC constantemente sem reutilização suficiente.

Exemplo:

text
L2ARC atual: 5 TiB
Writes:     10 TiB
Hit ratio:  12%

Isso sugere que muito conteúdo já girou pelo cache com retorno baixo.


11. Low-memory abort

O contador:

text
Low memory aborts

indica situações em que o ZFS deixou de alimentar o L2ARC por pressão de memória.

O importante é observar se ele aumenta.

Exemplo saudável:

yaml
Antes: 5
Depois: 5

Delta: 0

Exemplo problemático:

yaml
Antes: 5
Depois: 8

Delta: +3

12. zfs_arc_max

Para consultar:

bash
cat /sys/module/zfs/parameters/zfs_arc_max

Para converter o valor atual para GiB:

text
awk '{printf "%.2f GiB\n", $1/1024/1024/1024}' \
/sys/module/zfs/parameters/zfs_arc_max

Exemplo de configuração em runtime para 400 GiB:

bash
echo 429496729600 > /sys/module/zfs/parameters/zfs_arc_max

13. Comandos rápidos para diagnóstico

13.1 Resumo principal: ARC + Demand Data + L2ARC

text
arc_summary | grep -E \
'ARC total accesses|Total hits:|Total misses:|ARC demand data accesses:|Demand data hits:|Demand data misses:|L2ARC breakdown:|Hit ratio:|Miss ratio:'

Para performance, olhar primeiro:

text
Demand data hits
Demand data misses

Depois:

text
L2ARC Hit ratio
L2ARC Miss ratio

13.2 Apenas Demand Data

text
arc_summary | grep -A4 '^ARC demand data accesses:'

Útil para verificar rapidamente os hits e misses históricos das leituras demandadas pelas aplicações.


13.3 Apenas ARC status

text
arc_summary | grep -A7 '^ARC status:'

Mostra:

  • RAM total;

  • ARC mínimo;

  • ARC máximo;

  • target;

  • tamanho atual;

  • memória livre;

  • memória disponível.


13.4 Apenas L2ARC completo

text
arc_summary | grep -A30 '^L2ARC status:'

Mostra:

  • saúde do L2ARC;

  • low-memory aborts;

  • tamanho;

  • MRU;

  • MFU;

  • prefetch;

  • hit ratio;

  • misses;

  • writes.


13.5 Apenas L2ARC breakdown

text
arc_summary | grep -A4 '^L2ARC breakdown:'

Exemplo de saída:

text
L2ARC breakdown:
        Hit ratio:   16.6 %
        Miss ratio:  83.4 %

13.6 MRU, MFU e Prefetch do L2ARC

text
arc_summary | grep -E \
'L2ARC size|MFU allocated size|MRU allocated size|Prefetch allocated size'

13.7 Header do L2ARC

text
arc_summary | grep -E \
'L2 header size|Header size:'

Ou com mais contexto:

text
arc_summary | grep -A12 '^ARC structural breakdown'

13.8 Low-memory abort

text
arc_summary | grep -i 'Low memory aborts'

Diretamente do kernel:

text
awk '$1=="l2_abort_lowmem" {print $3}' \
/proc/spl/kstat/zfs/arcstats

13.9 Memória disponível

bash
free -h

Olhar principalmente a coluna:

text
available

Não analisar apenas free.


13.10 Principais contadores do L2ARC diretamente do kernel

bash
grep -E \
'^l2_(hits|misses|size|asize|write_bytes|abort_lowmem|mru_asize|mfu_asize|prefetch_asize)' \
/proc/spl/kstat/zfs/arcstats

13.11 Calcular L2ARC Hit Ratio diretamente

bash
awk '
$1=="l2_hits" {
    hits=$3
}

$1=="l2_misses" {
    misses=$3
}

END {
    total=hits+misses

    printf "L2ARC hits:   %d\n", hits
    printf "L2ARC misses: %d\n", misses

    if (total > 0)
        printf "L2ARC hit:    %.2f%%\n", hits/total*100
}
' /proc/spl/kstat/zfs/arcstats

13.12 Calcular Demand Data diretamente

bash
awk '
$1=="demand_data_hits" {
    hits=$3
}

$1=="demand_data_iohits" {
    iohits=$3
}

$1=="demand_data_misses" {
    misses=$3
}

END {
    total=hits+iohits+misses

    printf "Demand hits:     %d\n", hits
    printf "Demand I/O hits: %d\n", iohits
    printf "Demand misses:   %d\n", misses

    if (total > 0) {
        printf "Hit:             %.2f%%\n", hits/total*100
        printf "I/O hit:         %.2f%%\n", iohits/total*100
        printf "Miss:            %.2f%%\n", misses/total*100
    }
}
' /proc/spl/kstat/zfs/arcstats

13.13 Monitorar Demand Data e L2ARC ao vivo

Atualização a cada 10 segundos:

bash
watch -n10 '
arc_summary | grep -E \
"ARC demand data accesses:|Demand data hits:|Demand data misses:|L2ARC breakdown:|Hit ratio:|Miss ratio:"
'

13.14 Monitorar L2ARC completo

Atualização a cada 60 segundos:

bash
watch -n60 "
arc_summary | grep -A30 '^L2ARC status:'
"

13.15 Visão diária recomendada

bash
watch -n10 '
arc_summary | grep -E \
"ARC demand data accesses:|Demand data hits:|Demand data misses:|L2ARC breakdown:|Hit ratio:|Miss ratio:|Low memory aborts:"
'

Ordem de leitura:

text
1. Demand Data Miss
2. Low-memory aborts
3. L2ARC Hit Ratio
4. MRU / MFU
5. Writes no L2ARC

14. Monitor por janela

Para uma análise mais confiável, utilizar medições por delta em vez de apenas os valores históricos do arc_summary.

Iniciar uma janela:

text
/root/arc-monitor.sh start

Deixar o storage operar normalmente durante um período representativo:

text
30 minutos
1 hora
4 horas

Depois:

text
/root/arc-monitor.sh report

O relatório deve comparar apenas os acessos realizados naquela janela.


15. Histórico x janela atual

O arc_summary mostra contadores acumulados desde o início da coleta.

Exemplo:

text
Demand miss histórico: 40%

Isso não significa necessariamente que o storage esteja atualmente com 40% de miss.

Uma janela recente pode apresentar:

text
Demand miss atual: 0.5%

Portanto:

text
arc_summary
=
visão histórica/acumulada

Enquanto:

text
arc-monitor.sh
=
visão da janela atual

Para tuning, a janela atual durante uma carga representativa normalmente é mais importante.


16. Ordem correta de análise

1. Demand Data Miss

Pergunta:

text
Quanto das leituras solicitadas pelas aplicações está escapando do ARC?

2. Low-memory aborts

Pergunta:

text
Há pressão de memória afetando o L2ARC?

3. L2ARC Hit

Pergunta:

text
Quando o ARC não atende, o L2ARC consegue ajudar?

4. MRU x MFU

Pergunta:

text
O L2ARC está armazenando dados reutilizados ou dados de passagem?

5. L2ARC Writes

Pergunta:

text
Quanto está sendo escrito nos SSDs para obter esse benefício?

6. ARC Total

Usar apenas como visão geral.


17. Matriz rápida de diagnóstico

Demand MissL2 HitMRUInterpretação
BaixoBaixoqualquerARC já resolve a carga
BaixoAltoqualquerSituação excelente
AltoAltomoderadoL2ARC está ajudando
AltoBaixoAltoInvestigar poluição/churn
AltoBaixoBaixoWorking set/cache possivelmente insuficiente

18. ARC excessivo

Sintomas:

text
ARC próximo da RAM total
+
MemAvailable baixa
+
low-memory aborts aumentando

Possível ação:

text
reduzir zfs_arc_max

Sempre medir novamente após a alteração.


19. L2ARC poluído

Sintomas:

text
MRU muito alto
+
MFU muito baixo
+
L2ARC hit baixo
+
alto churn

Possível ação:

text
avaliar l2arc_mfuonly=1

Não ativar apenas porque MRU está alto.


20. l2arc_write_max

Consultar:

bash
cat /sys/module/zfs/parameters/l2arc_write_max

Converter para MiB:

text
awk '{printf "%.2f MiB\n", $1/1024/1024}' \
/sys/module/zfs/parameters/l2arc_write_max

Consultar o intervalo de alimentação:

bash
cat /sys/module/zfs/parameters/l2arc_feed_secs

Não aumentar l2arc_write_max enquanto houver sinais de poluição.

Se o cache estiver armazenando dados pouco úteis, aumentar a velocidade significa apenas escrever esses dados mais rapidamente.


21. Consultar principais tunables

bash
for p in \
    zfs_arc_max \
    l2arc_write_max \
    l2arc_feed_secs \
    l2arc_mfuonly \
    l2arc_meta_percent \
    l2arc_noprefetch
do
    printf '%-25s = ' "$p"
    cat "/sys/module/zfs/parameters/$p"
done

Saída típica:

text
zfs_arc_max               = 429496729600
l2arc_write_max           = 33554432
l2arc_feed_secs           = 1
l2arc_mfuonly             = 0
l2arc_meta_percent        = 33
l2arc_noprefetch          = 1

22. Situação saudável

Exemplo:

text
Demand miss:              < 5%
Low-memory abort delta:     0
MemAvailable:              confortável
L2ARC hit:                 razoável quando consultado
Writes no L2ARC:           proporcionais ao benefício

Não é necessário que todas as métricas sejam perfeitas.


23. Situação de atenção

Investigar quando houver:

text
Demand miss > 10%
+
L2ARC hit < 10-20%
+
MRU > 95%
+
MFU muito baixo
+
alto volume de writes

Ou:

text
low-memory abort aumentando

24. Regra principal

text
Demand Miss baixo
=
as aplicações estão sendo atendidas eficientemente pelo ARC

Mesmo que:

text
L2ARC hit seja baixo

Isso pode ser perfeitamente saudável porque o L2ARC quase não precisa ser utilizado.


25. Situação que realmente merece tuning

text
Demand Miss alto
        +
L2ARC Hit baixo
        +
MRU muito alto
        +
MFU muito baixo
        +
muitos writes no L2ARC
        +
low-memory aborts ou pouca memória disponível

Nesse cenário existe forte justificativa para investigar e realizar tuning.


26. Procedimento recomendado

Sempre alterar uma coisa por vez:

text
1. Corrigir pressão de memória
        |
        v
2. Medir carga real
        |
        v
3. Avaliar Demand Miss
        |
        v
4. Avaliar L2ARC Hit
        |
        v
5. Avaliar MRU/MFU
        |
        v
6. Avaliar churn/writes
        |
        v
7. Alterar um tunable
        |
        v
8. Medir novamente

Evitar alterar simultaneamente:

text
zfs_arc_max
l2arc_mfuonly
l2arc_write_max
prefetch

Caso contrário fica difícil identificar qual mudança realmente melhorou ou piorou o storage.


27. Objetivo final

O objetivo não é:

text
100% ARC Hit
100% L2ARC Hit

O objetivo é:

text
baixa latência
+
baixo Demand Data Miss
+
uso eficiente da RAM
+
L2ARC realmente útil
+
mínimo acesso possível ao RAIDZ
+
ausência de pressão de memória

Em ZFS,mais cache não significa automaticamente melhor cache.

As métricas devem sempre ser correlacionadas com o workload real.