Preparando um cache L2ARC do ZFS no Solaris 11.3

5

Existe uma boa maneira de preparar um cache L2ARC do ZFS no Solaris 11.3?

O L2ARC é projetado para ignorar blocos que foram lidos sequencialmente de um arquivo. Isso faz sentido para a operação em andamento, mas dificulta a preparação do cache para aquecimento inicial ou benchmarking.

Além disso, arquivos altamente fragmentados podem se beneficiar enormemente de leituras seqüenciais sendo armazenadas em cache no L2ARC (porque no disco são leituras aleatórias), mas com a heurística atual esses arquivos nunca serão armazenados em cache mesmo que o L2ARC seja apenas 10 % cheio.

Nas versões anteriores do Solaris 10 e 11, obtive sucesso ao usar dd duas vezes seguidas em cada arquivo. O primeiro dd leu o arquivo no ARC, e o segundo dd pareceu agradar os buffers para que eles se tornassem elegíveis para o armazenamento em cache do L2ARC. A mesma técnica não parece funcionar no Solaris 11.3.

Confirmei que os arquivos em questão têm um tamanho de registro de 8k, e tentei definir zfs_prefetch_disable , mas isso não teve impacto no comportamento do L2ARC ATUALIZAÇÃO: zfs_prefetch_disable acaba sendo importante , veja minha resposta abaixo.

Se não houver uma boa maneira de fazer isso, eu consideraria usar uma ferramenta que gera leituras aleatórias acima de 100% de um arquivo. Isso pode valer o tempo dado que o cache é persistente agora em 11.3. Existem ferramentas como esta?

    
por Tom Shaw 23.06.2016 / 10:13

2 respostas

3

Com um pouco de experimentação, encontrei quatro soluções possíveis.

Com cada abordagem, você precisa executar as etapas e continuar lendo mais dados para preencher o cache do ZFS ARC e disparar o feed do ARC para o L2ARC. Observe que, se os dados já estiverem armazenados em cache na memória, ou se o tamanho compactado no disco de cada bloco for maior que 32kB, esses métodos geralmente não farão nada.

1. Defina o sinalizador do kernel documentado zfs_prefetch_disable

O L2ARC, por padrão, se recusa a armazenar em cache os dados que foram pré-buscados automaticamente. Podemos ignorar isso desabilitando o recurso de pré-busca do ZFS. Esse sinalizador geralmente é uma boa ideia para cargas de trabalho de banco de dados de qualquer maneira.

echo "zfs_prefetch_disable/W0t1" | mdb -kw

.. ou para defini-lo permanentemente, adicione o seguinte a /etc/system :

set zfs:zfs_prefetch_disable = 1

Agora, quando os arquivos são lidos usando dd , eles ainda estarão qualificados para o L2ARC.

Operacionalmente, essa alteração também melhora o comportamento das leituras em meus testes. Normalmente, quando o ZFS detecta uma leitura sequencial, ele equilibra a taxa de transferência entre os dados vdevs e cache vdevs em vez de apenas ler do cache - mas isso prejudica o desempenho se os dispositivos de cache tiverem latência significativamente menor ou throughput maior do que os dispositivos de dados. / p>

2. Reescreva os dados

Como os dados são gravados em um sistema de arquivos ZFS, eles são armazenados em cache no ARC e (se atenderem aos critérios de tamanho de bloco) são qualificados para serem alimentados no L2ARC. Nem sempre é fácil reescrever dados, mas alguns aplicativos e bancos de dados podem ser executados, por exemplo, através do espelhamento de arquivos no nível do aplicativo ou da movimentação dos arquivos de dados.

Problemas:

  • Nem sempre é possível, dependendo do aplicativo.
  • Consome espaço extra se houver instantâneos em uso.
  • (Mas, do lado bom, os arquivos resultantes são desfragmentados.)

3. Desmarque o sinalizador do kernel não documentado l2arc_noprefetch

Isso se baseia na leitura do código-fonte do OpenSolaris e é, sem dúvida, completamente sem suporte. Use a seu próprio risco.

  1. Desative o sinalizador l2arc_noprefetch :

    echo "l2arc_noprefetch/W0" | mdb -kw
    

    Os dados lidos no ARC enquanto este sinalizador estiver desativado serão elegíveis para o L2ARC, mesmo que seja uma leitura sequencial (desde que os blocos tenham no máximo 32k no disco).

  2. Leia o arquivo no disco:

    dd if=filename.bin of=/dev/null bs=1024k
    
  3. Reabilite o sinalizador l2arc_noprefetch :

    echo "l2arc_noprefetch/W1" | mdb -kw
    

4. Leia os dados aleatoriamente

Eu escrevi um script Perl para ler arquivos em pedaços de 8kB pseudoaleatoriamente (baseado na ordenação de um hash Perl). Pode também funcionar com pedaços maiores, mas ainda não testei isso.

#!/usr/bin/perl -W

my $BLOCK_SIZE = 8*2**10;
my $MAX_ERRS = 5;

foreach my $file (@ARGV) {
        print "Reading $file...\n";
        my $size;
        unless($size = (stat($file))[7]) {print STDERR "Unable to stat file $file.\n"; next; }
        unless(open(FILE, "<$file")) {print STDERR "Unable to open file $file.\n"; next; }
        my $buf;
        my %blocks;
        for(my $i=0;$i<$size/$BLOCK_SIZE;$i++) { $blocks{"$i"} = 0; }
        my $errs = 0;
        foreach my $block (keys %blocks) {
                unless(sysseek(FILE, $block*$BLOCK_SIZE, 0) && sysread(FILE, $buf, $BLOCK_SIZE)) {
                        print STDERR "Error reading $BLOCK_SIZE bytes from offset " . $block * $BLOCK_SIZE . "\n";
                        if(++$errs == $MAX_ERRS) { print STDERR "Giving up on this file.\n"; last; }
                        next;
                }
        }
        close(FILE);
}

Problemas:

  • Isso leva muito tempo e sobrecarrega o disco.

Problemas restantes

  • Os métodos acima colocarão os dados na memória principal, qualificados para alimentar o L2ARC, mas não acionam o feed. A única maneira que sei para acionar a escrita para o L2ARC é continuar lendo dados para pressionar o ARC.
  • No Solaris 11.3 com SRU 1.3.9.4.0, apenas raramente o L2ARC aumenta o valor total esperado. O evict_l2_eligible kstat aumenta mesmo quando os dispositivos SSD não estão sob pressão, indicando que os dados estão sendo descartados. Esse restante de dados não armazenados em cache tem um efeito desproporcional no desempenho.
por 23.06.2016 / 16:24
0

Sugiro usar uma carga de trabalho real e monitorar o resultado com arcstat .

Algo como:

arcstat.py -f "time,read,l2read,hit%,hits,miss%,miss,l2hit%,l2miss%,arcsz,c,l2size" 1

Eu não acho que haja necessidade de "preparar" o cache. Se a carga de trabalho que você tem não preenche naturalmente o cache, então não é uma carga de trabalho de benchmarking representativa, certo?

Talvez você tenha um caso de uso excepcional (qual é o tamanho do seu conjunto de dados, tamanho do ARC e tamanho do conjunto de trabalho?) , mas em geral o foco no L2ARC é super enfatizado.

    
por 23.06.2016 / 14:08