Hoje fiz alguns testes no L2ARC usando o último ZFS no Linux 0.7.10. Eu vi que o L2ARC é preenchido com dados, mas com as configurações do módulo padrão, os dados que residem no cache L2ARC nunca são tocados. Em vez disso, os dados são lidos a partir dos vdevs do conjunto principal. Eu também tenho visto esse comportamento em 0.7.9 e não tenho certeza se esse é o comportamento esperado.
Mesmo que esse seja o comportamento esperado, acho estranho estragar o L2ARC com dados que nunca são lidos.
A instalação de teste é uma VM:
- CentOS 7.5 com os patches mais recentes
- ZFS no Linux 0.7.10
- 2 GB de RAM
Eu fiz algumas configurações do ZFS:
-
l2arc_headroom=1024
e l2arc_headroom=1024
para acelerar a população L2ARC
Veja como o pool foi criado e o layout. Eu sei que é bastante estranho para uma configuração do mundo real, mas isso foi destinado apenas para testes L2ARC.
[root@host ~]# zpool create tank raidz2 /dev/sda /dev/sdb /dev/sdc cache sdd -f
[root@host ~]# zpool list -v
NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 2.95G 333K 2.95G - 0% 0% 1.00x ONLINE -
raidz2 2.95G 333K 2.95G - 0% 0%
sda - - - - - -
sdb - - - - - -
sdc - - - - - -
cache - - - - - -
sdd 1010M 512 1009M - 0% 0%
Agora, grave alguns dados em um arquivo e observe o uso do dispositivo.
[root@host ~]# dd if=/dev/urandom of=/tank/testfile bs=1M count=512
512+0 records in
512+0 records out
536870912 bytes (537 MB) copied, 9.03607 s, 59.4 MB/s
[root@host ~]# zpool list -v
NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 2.95G 1.50G 1.45G - 10% 50% 1.00x ONLINE -
raidz2 2.95G 1.50G 1.45G - 10% 50%
sda - - - - - -
sdb - - - - - -
sdc - - - - - -
cache - - - - - -
sdd 1010M 208M 801M - 0% 20%
Tudo bem, alguns dos dados já foram movidos para o L2ARC, mas não todos. Então, leia-o mais algumas vezes para torná-lo completamente em L2ARC.
[root@host ~]# dd if=/tank/testfile of=/dev/null bs=512 # until L2ARC is populated with the 512MB testfile
[root@host ~]# zpool list -v
NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 2.95G 1.50G 1.45G - 11% 50% 1.00x ONLINE -
raidz2 2.95G 1.50G 1.45G - 11% 50%
sda - - - - - -
sdb - - - - - -
sdc - - - - - -
cache - - - - - -
sdd 1010M 512M 498M - 0% 50%
Ok, o L2ARC está preenchido e pronto para ser lido. Mas é preciso se livrar do L1ARC primeiro. Eu fiz o seguinte, que parece ter funcionado.
[root@host ~]# echo $((64*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; echo $((1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; arc_summary.py -p1
------------------------------------------------------------------------
ZFS Subsystem Report Sun Sep 09 17:03:55 2018
ARC Summary: (HEALTHY)
Memory Throttle Count: 0
ARC Misc:
Deleted: 20
Mutex Misses: 0
Evict Skips: 1
ARC Size: 0.17% 1.75 MiB
Target Size: (Adaptive) 100.00% 1.00 GiB
Min Size (Hard Limit): 6.10% 62.48 MiB
Max Size (High Water): 16:1 1.00 GiB
ARC Size Breakdown:
Recently Used Cache Size: 96.06% 1.32 MiB
Frequently Used Cache Size: 3.94% 55.50 KiB
ARC Hash Breakdown:
Elements Max: 48
Elements Current: 100.00% 48
Collisions: 0
Chain Max: 0
Chains: 0
Tudo bem, agora estamos prontos para ler o L2ARC (desculpe pelo longo prefácio, mas achei que era importante).
Então, rodando o comando dd if=/tank/testfile of=/dev/null bs=512
novamente, eu estava assistindo zpool iostat -v 5
em um segundo terminal.
Para minha surpresa, o arquivo foi lido a partir do vdevs normal em vez do L2ARC, embora o arquivo esteja no L2ARC. Este é o único arquivo no sistema de arquivos e nenhuma outra atividade está ativa durante meus testes.
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 1.50G 1.45G 736 55 91.9M 96.0K
raidz2 1.50G 1.45G 736 55 91.9M 96.0K
sda - - 247 18 30.9M 32.0K
sdb - - 238 18 29.8M 32.0K
sdc - - 250 18 31.2M 32.0K
cache - - - - - -
sdd 512M 498M 0 1 85.2K 1.10K
---------- ----- ----- ----- ----- ----- -----
Eu, então, mexi com algumas configurações como zfetch_array_rd_sz
, zfetch_max_distance
, zfetch_max_streams
, l2arc_write_boost
e l2arc_write_max
, configurando-as para um número ímpar alto. Mas nada mudou.
Depois de mudar
-
l2arc_noprefetch=0
(o padrão é 1
)
- ou
zfs_prefetch_disable=1
(o padrão é 0
)
- alternar os dois de seus padrões
as leituras são servidas a partir do L2ARC. Novamente executando dd if=/tank/testfile of=/dev/null bs=512
e assistindo zpool iostat -v 5
em um segundo terminal e se livrando do L1ARC.
[root@host ~]# echo 0 > /sys/module/zfs/parameters/l2arc_noprefetch
[root@host ~]# echo $((64*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; echo $((1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; arc_summary.py -p1
...
[root@host ~]# dd if=/tank/testfile of=/dev/null bs=512
E o resultado:
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 1.50G 1.45G 0 57 921 102K
raidz2 1.50G 1.45G 0 57 921 102K
sda - - 0 18 0 34.1K
sdb - - 0 18 0 34.1K
sdc - - 0 19 921 34.1K
cache - - - - - -
sdd 512M 497M 736 0 91.9M 1023
---------- ----- ----- ----- ----- ----- -----
Agora os dados são lidos do L2ARC, mas somente depois de alternar os parâmetros do módulo mencionados acima.
Eu também li que o L2ARC pode ser grande demais. Mas os tópicos que encontrei sobre esse tópico estavam se referindo a problemas de desempenho ou o mapa de espaço para o L2ARC estragando o L1ARC.
O desempenho não é meu problema aqui, e até onde eu posso dizer, o mapa espacial para o L2ARC também não é tão grande assim.
[root@host ~]# grep hdr /proc/spl/kstat/zfs/arcstats
hdr_size 4 279712
l2_hdr_size 4 319488
Como já foi mencionado, não tenho certeza se esse é o comportamento pretendido ou se estou perdendo alguma coisa.