Noções básicas do ZFS: armazenamento e desempenho

Noções básicas do ZFS: armazenamento e desempenho

Nesta primavera já discutimos alguns tópicos introdutórios, por ex. como verificar a velocidade de suas unidades и o que é RAID. No segundo deles, prometemos até continuar estudando o desempenho de várias topologias multi-disco no ZFS. Este é o sistema de arquivos da próxima geração que agora está sendo implantado em todos os lugares, desde Apple para Ubuntu.

Pois bem, hoje é o melhor dia para conhecer o ZFS, leitores curiosos. Saiba apenas que, na humilde avaliação do desenvolvedor OpenZFS Matt Ahrens, “é muito difícil”.

Mas antes de chegarmos aos números - e haverá, eu prometo - para todas as variantes da configuração ZFS de oito discos, precisamos falar sobre como Em geral, o ZFS armazena dados em disco.

Zpool, vdev e dispositivo

Noções básicas do ZFS: armazenamento e desempenho
Este diagrama de pool completo inclui três vdevs auxiliares, um de cada classe e quatro para RAIDz2

Noções básicas do ZFS: armazenamento e desempenho
Geralmente não há razão para criar um conjunto de tipos e tamanhos de vdev incompatíveis - mas se você quiser, não há nada que o impeça de fazer isso

Para realmente entender o sistema de arquivos ZFS, você precisa observar atentamente sua estrutura real. Primeiro, o ZFS unifica as camadas tradicionais de gerenciamento de volumes e sistemas de arquivos. Em segundo lugar, ele usa um mecanismo transacional de cópia na gravação. Esses recursos significam que o sistema é estruturalmente muito diferente dos sistemas de arquivos convencionais e das matrizes RAID. O primeiro conjunto de blocos de construção básicos a serem entendidos é o pool de armazenamento (zpool), o dispositivo virtual (vdev) e o dispositivo real (dispositivo).

zpool

O pool de armazenamento zpool é a estrutura ZFS mais alta. Cada pool contém um ou mais dispositivos virtuais. Por sua vez, cada um deles contém um ou mais dispositivos reais (dispositivo). Pools virtuais são unidades independentes. Um computador físico pode conter dois ou mais pools separados, mas cada um é completamente independente dos outros. Os pools não podem compartilhar dispositivos virtuais.

A redundância do ZFS está no nível do dispositivo virtual, não no nível do pool. Não há absolutamente nenhuma redundância no nível do pool – se um vdev ou um vdev dedicado for perdido, todo o pool será perdido junto com ele.

Os pools de armazenamento modernos podem sobreviver à perda do cache ou log de um dispositivo virtual - embora possam perder uma pequena quantidade de dados sujos se perderem o log vdev durante uma queda de energia ou falha do sistema.

Existe um equívoco comum de que as "distribuições de dados" do ZFS são gravadas em todo o pool. Isso não é verdade. Zpool não é um RAID0 engraçado, é mais engraçado JBOD com um mecanismo complexo de distribuição de variáveis.

Em sua maioria, os registros são distribuídos entre os dispositivos virtuais disponíveis de acordo com o espaço livre disponível, portanto, em tese, todos serão preenchidos ao mesmo tempo. Versões mais recentes do ZFS levam em consideração o uso atual do vdev (descarte) - se um dispositivo virtual estiver significativamente mais ocupado que outro (por exemplo, devido à carga de leitura), ele será temporariamente ignorado para gravações, apesar de ter a maior proporção de espaço livre .

O mecanismo de detecção de reciclagem incorporado nos métodos modernos de alocação de gravação do ZFS pode reduzir a latência e aumentar o rendimento durante períodos de carga excepcionalmente alta - mas isso não acontece. carta branca à mistura involuntária de HDDs lentos e SSDs rápidos em um pool. Esse pool desigual ainda operará na velocidade do dispositivo mais lento, ou seja, como se fosse inteiramente composto por tais dispositivos.

vdev

Cada pool de armazenamento consiste em um ou mais dispositivos virtuais (vdev). Por sua vez, cada vdev inclui um ou mais dispositivos reais. A maioria dos dispositivos virtuais é usada para armazenamento simples de dados, mas existem várias classes auxiliares vdev, incluindo CACHE, LOG e SPECIAL. Cada um desses tipos de vdev pode ter uma das cinco topologias: dispositivo único, RAIDz1, RAIDz2, RAIDz3 ou espelho.

RAIDz1, RAIDz2 e RAIDz3 são variedades especiais do que os antigos chamariam de RAID de paridade dupla (diagonal). 1, 2 e 3 referem-se a quantos blocos de paridade são alocados para cada faixa de dados. Em vez de ter discos separados para fornecer paridade, os dispositivos RAIDz virtuais distribuem a paridade de maneira semi-uniforme entre os discos. Um array RAIDz pode perder tantos discos quantos blocos de paridade; se perder outro, ele falhará e levará consigo o conjunto de armazenamento.

Em dispositivos virtuais espelhados (espelho vdev), cada bloco é armazenado em cada dispositivo no vdev. Embora os espelhos de duas larguras sejam os mais comuns, um espelho pode conter qualquer número arbitrário de dispositivos – em grandes instalações, os triplos são frequentemente usados ​​para melhorar o desempenho de leitura e a tolerância a falhas. Um espelho vdev pode sobreviver a qualquer falha, desde que pelo menos um dispositivo no vdev permaneça operacional.

Vdevs únicos são inerentemente perigosos. Esse dispositivo virtual não sobreviverá a uma única falha - e se for usado como armazenamento ou como um vdev especial, sua falha levará à destruição de todo o pool. Tenha muito, muito cuidado aqui.

Dispositivos virtuais CACHE, LOG e ESPECIAIS podem ser criados em qualquer uma das topologias acima - mas lembre-se de que perder um dispositivo virtual ESPECIAL significa perder o pool, portanto, uma topologia redundante é altamente recomendada.

dispositivo

Este é provavelmente o termo mais fácil de entender no ZFS - é literalmente um dispositivo de bloqueio de acesso aleatório. Lembre-se de que os dispositivos virtuais são compostos por dispositivos individuais e um pool é composto por dispositivos virtuais.

Discos, sejam magnéticos ou de estado sólido, são os dispositivos de bloco mais comuns usados ​​como blocos de construção do vdev. No entanto, qualquer dispositivo com um descritor em /dev servirá - portanto, matrizes RAID de hardware inteiras podem ser usadas como dispositivos separados.

Um arquivo bruto simples é um dos dispositivos de bloco alternativos mais importantes a partir dos quais um vdev pode ser construído. Conjuntos de testes de arquivos esparsos é uma maneira muito conveniente de verificar comandos de pool e ver quanto espaço está disponível em um pool ou dispositivo virtual de uma determinada topologia.

Noções básicas do ZFS: armazenamento e desempenho
Você pode criar um pool de teste a partir de arquivos esparsos em apenas alguns segundos - mas não se esqueça de excluir todo o pool e seus componentes posteriormente

Digamos que você queira um servidor de oito discos e planeje usar discos de 10 TB (~9300 GiB), mas não tem certeza de qual topologia melhor atende às suas necessidades. No exemplo acima, construímos um pool de teste a partir de arquivos esparsos em questão de segundos - e agora sabemos que um vdev RAIDz2 de oito discos de 10 TB fornece 50 TiB de capacidade utilizável.

Outra classe especial de dispositivos é SPARE. Os dispositivos hot-swap, diferentemente dos dispositivos normais, pertencem ao pool inteiro e não a um único dispositivo virtual. Se algum vdev no pool falhar e um dispositivo sobressalente estiver conectado ao pool e disponível, ele ingressará automaticamente no vdev afetado.

Uma vez conectado ao vdev afetado, o dispositivo substituto começa a receber cópias ou reconstruções dos dados que deveriam estar no dispositivo ausente. No RAID tradicional isso é chamado de "reconstrução" e no ZFS é "ressilvering".

É importante observar que os dispositivos de substituição não substituem permanentemente os dispositivos com falha. Esta é apenas uma substituição temporária para reduzir o tempo de degradação do vdev. Depois que o administrador substitui o dispositivo vdev com falha, a redundância é restaurada para esse dispositivo permanente e o SPARE é desconectado do vdev e volta a ser um sobressalente para todo o pool.

Conjuntos de dados, blocos e setores

O próximo conjunto de blocos de construção a serem entendidos em nossa jornada pelo ZFS está menos relacionado ao hardware e mais à forma como os dados em si são organizados e armazenados. Estamos pulando algumas camadas aqui - como o metaslab - para evitar sobrecarregar os detalhes e, ao mesmo tempo, manter a compreensão da estrutura geral.

Conjunto de dados

Noções básicas do ZFS: armazenamento e desempenho
Quando criamos um conjunto de dados pela primeira vez, ele mostra todo o espaço disponível no pool. Em seguida, definimos a cota e alteramos o ponto de montagem. Magia!

Noções básicas do ZFS: armazenamento e desempenho
Zvol é basicamente apenas um conjunto de dados despojado de sua camada de sistema de arquivos, que substituímos aqui por um sistema de arquivos ext4 completamente normal

O conjunto de dados ZFS é praticamente igual a um sistema de arquivos montado padrão. Como um sistema de arquivos normal, à primeira vista parece ser “apenas mais uma pasta”. Mas, assim como os sistemas de arquivos montados normais, cada conjunto de dados ZFS possui seu próprio conjunto de propriedades básicas.

Primeiro de tudo, um conjunto de dados pode ter uma cota atribuída. Se você instalar zfs set quota=100G poolname/datasetname, então você não poderá gravar na pasta montada /poolname/datasetname mais de 100 GiB.

Observe a presença – e ausência – de barras no início de cada linha? Cada conjunto de dados tem seu próprio lugar na hierarquia do ZFS e na hierarquia de montagem do sistema. Não há barra inicial na hierarquia do ZFS - você começa com o nome do pool e depois com o caminho de um conjunto de dados para o próximo. Por exemplo, pool/parent/child para um conjunto de dados chamado child no conjunto de dados pai parent em uma piscina com um nome criativo pool.

Por padrão, o ponto de montagem de um conjunto de dados será equivalente ao seu nome na hierarquia do ZFS, com uma barra inicial - o pool denominado pool montado como /pool, conjunto de dados parent montado em /pool/parente o conjunto de dados filho child montado em /pool/parent/child. No entanto, o ponto de montagem do sistema do conjunto de dados pode ser alterado.

Se indicarmos zfs set mountpoint=/lol pool/parent/child, então o conjunto de dados pool/parent/child montado no sistema como /lol.

Além dos conjuntos de dados, devemos mencionar os volumes (zvols). Um volume é praticamente igual a um conjunto de dados, exceto que na verdade não possui um sistema de arquivos – é apenas um dispositivo de bloco. Você pode, por exemplo, criar zvol Com nome mypool/myzvol, formate-o com um sistema de arquivos ext4 e monte esse sistema de arquivos - agora você tem um sistema de arquivos ext4, mas com todos os recursos de segurança do ZFS! Isso pode parecer bobo em um computador, mas faz muito mais sentido como back-end ao exportar um dispositivo iSCSI.

Blocos

Noções básicas do ZFS: armazenamento e desempenho
Um arquivo é representado por um ou mais blocos. Cada bloco é armazenado em um dispositivo virtual. O tamanho do bloco geralmente é igual ao parâmetro tamanho do registro, mas pode ser reduzido a 2^um turno, se contiver metadados ou um arquivo pequeno.

Noções básicas do ZFS: armazenamento e desempenho
Nós realmente realmente Não estamos brincando sobre a enorme penalidade de desempenho se você definir uma mudança muito baixa

Em um pool ZFS, todos os dados, incluindo metadados, são armazenados em blocos. O tamanho máximo do bloco para cada conjunto de dados é definido na propriedade recordsize (tamanho do registro). O tamanho do registro pode mudar, mas isso não alterará o tamanho ou a localização de nenhum bloco que já tenha sido gravado no conjunto de dados - isso afetará apenas os novos blocos à medida que forem gravados.

A menos que especificado de outra forma, o tamanho de entrada padrão atual é 128 KiB. É uma troca difícil em que o desempenho não será perfeito, mas não será terrível na maioria dos casos. Recordsize pode ser definido para qualquer valor de 4K a 1M (com configurações adicionais recordsize você pode instalar ainda mais, mas isso raramente é uma boa ideia).

Qualquer bloco refere-se aos dados de apenas um arquivo – você não pode comprimir dois arquivos diferentes em um bloco. Cada arquivo consiste em um ou mais blocos, dependendo do seu tamanho. Se o tamanho do arquivo for menor que o tamanho do registro, ele será armazenado em um bloco menor - por exemplo, um bloco com um arquivo de 2 KiB ocupará apenas um setor de 4 KiB no disco.

Se o arquivo for grande o suficiente para exigir vários blocos, todas as entradas desse arquivo terão tamanho recordsize - incluindo a última entrada, cuja parte principal pode ser espaço não utilizado.

volumes zvol não possuem a propriedade recordsize - em vez disso, eles têm a propriedade equivalente volblocksize.

Setores

O último e mais básico alicerce é o setor. É a menor unidade física que pode ser gravada ou lida em um dispositivo host. Durante várias décadas, a maioria dos discos utilizou setores de 512 bytes. Hoje em dia, a maioria das unidades é configurada para setores de 4 KiB e algumas - especialmente SSDs - são configuradas para setores de 8 KiB ou até maiores.

O ZFS possui um recurso que permite definir manualmente o tamanho do setor. Está Propriedade ashift. Um tanto confuso, ashift é uma potência de dois. Por exemplo, ashift=9 significa tamanho do setor 2 ^ 9 ou 512 bytes.

O ZFS solicita ao sistema operacional informações detalhadas sobre cada dispositivo de bloco quando ele é adicionado a um novo vdev e, teoricamente, define automaticamente a mudança apropriadamente com base nessas informações. Infelizmente, muitas unidades mentem sobre o tamanho do setor para manter a compatibilidade com o Windows XP (que não conseguia entender unidades com outros tamanhos de setor).

Isso significa que é altamente recomendável que o administrador do ZFS conheça o tamanho real do setor de seus dispositivos e defina manualmente ashift. Se ashift for definido como muito pequeno, o número de operações de leitura/gravação aumenta astronomicamente. Portanto, escrever "setores" de 512 bytes em um setor real de 4 KiB significa ter que escrever o primeiro "setor", depois ler o setor de 4 KiB, modificá-lo com um segundo "setor" de 512 bytes e gravá-lo de volta no novo Setor de 4 KiB e assim por diante para cada entrada.

No mundo real, tal penalidade afeta os SSDs Samsung EVO, aos quais deveria ser aplicada ashift=13, mas esses SSDs mentem sobre o tamanho do setor e, portanto, o padrão é definido como ashift=9. A menos que um administrador de sistema experiente altere esta configuração, este SSD funciona mais devagar HDD magnético normal.

Para efeito de comparação, por ser muito grande ashift praticamente não há penalidade. Não há nenhum impacto real no desempenho e o aumento no espaço não utilizado é infinitesimal (ou zero se a compactação estiver habilitada). Portanto, recomendamos fortemente que mesmo as unidades que usam setores de 512 bytes instalem ashift=12 ou ashift=13olhar com confiança para o futuro.

Propriedade ashift está instalado para cada dispositivo virtual vdev, e não para piscina, como muitas pessoas pensam erroneamente - e não muda após a instalação. Se você acidentalmente acertar ashift Ao adicionar um novo vdev a um pool, você poluiu irrevogavelmente esse pool com um dispositivo de baixo desempenho e, como regra, não há outra opção a não ser destruir o pool e recomeçar. Mesmo a exclusão do vdev não o salvará de uma configuração quebrada ashift!

Mecanismo de cópia na gravação

Noções básicas do ZFS: armazenamento e desempenho
Se um sistema de arquivos regular precisar reescrever dados, ele modifica cada bloco onde está localizado

Noções básicas do ZFS: armazenamento e desempenho
Um sistema de arquivos copy-on-write grava uma nova versão do bloco e então desbloqueia a versão antiga

Noções básicas do ZFS: armazenamento e desempenho
Em resumo, se ignorarmos a disposição física real dos blocos, o nosso “cometa de dados” simplifica-se para um “verme de dados” que se move da esquerda para a direita no mapa do espaço disponível.

Noções básicas do ZFS: armazenamento e desempenho
Agora podemos ter uma boa ideia de como funcionam os snapshots copy-on-write - cada bloco pode pertencer a vários snapshots e persistirá até que todos os snapshots associados sejam destruídos

O mecanismo Copy on Write (CoW) é a base fundamental do que torna o ZFS um sistema tão incrível. O conceito básico é simples: se você pedir a um sistema de arquivos tradicional para alterar um arquivo, ele fará exatamente o que você pediu. Se você pedir a um sistema de arquivos copy-on-write para fazer a mesma coisa, ele dirá “ok” – mas mentirá para você.

Em vez disso, um sistema de arquivos copy-on-write grava uma nova versão do bloco modificado e, em seguida, atualiza os metadados do arquivo para desvincular o bloco antigo e associá-lo ao novo bloco que você acabou de escrever.

Desvincular o bloco antigo e vincular o novo é feito em uma única operação, portanto não pode ser interrompido - se você reiniciar a energia depois que isso acontecer, você terá uma nova versão do arquivo, e se você reiniciar a energia antes, então você tem a versão antiga. De qualquer forma, não haverá conflitos no sistema de arquivos.

A cópia na gravação no ZFS ocorre não apenas no nível do sistema de arquivos, mas também no nível do gerenciamento de disco. Isso significa que o ZFS não é suscetível a espaços em branco no registro (buraco no RAID) - um fenômeno quando a faixa foi gravada apenas parcialmente antes da falha do sistema, com danos ao array após uma reinicialização. Aqui a faixa é escrita atomicamente, vdev é sempre sequencial e Bob é seu tio.

ZIL: Registro de intenção do ZFS

Noções básicas do ZFS: armazenamento e desempenho
O ZFS lida com gravações síncronas de uma maneira especial - ele as armazena temporariamente, mas imediatamente, no ZIL, antes de gravá-las permanentemente junto com gravações assíncronas.

Noções básicas do ZFS: armazenamento e desempenho
Normalmente, os dados gravados no ZIL nunca mais são lidos. Mas isso é possível após uma falha do sistema

Noções básicas do ZFS: armazenamento e desempenho
Um SLOG, ou dispositivo LOG secundário, é simplesmente um vdev especial - e de preferência muito rápido - onde o ZIL pode ser armazenado separadamente do armazenamento principal

Noções básicas do ZFS: armazenamento e desempenho
Após uma falha, todos os dados sujos no ZIL são reproduzidos - neste caso, o ZIL está no SLOG, então é onde eles são reproduzidos

Existem duas categorias principais de gravações: síncronas (sync) e assíncronas (assíncronas). Para a maioria das cargas de trabalho, a grande maioria das gravações é assíncrona – o sistema de arquivos permite que elas sejam agregadas e emitidas em lotes, reduzindo a fragmentação e aumentando significativamente o rendimento.

As gravações síncronas são uma questão completamente diferente. Quando um aplicativo solicita uma gravação síncrona, ele informa ao sistema de arquivos: "Você precisa confirmar isso na memória não volátil agora mesmo, e até então não há mais nada que eu possa fazer.” Portanto, as gravações síncronas devem ser confirmadas no disco imediatamente - e se isso aumentar a fragmentação ou reduzir o rendimento, que assim seja.

O ZFS lida com gravações síncronas de maneira diferente dos sistemas de arquivos normais – em vez de liberá-las imediatamente para o armazenamento regular, o ZFS as confirma em uma área de armazenamento especial chamada ZFS Intent Log, ou ZIL. O truque é que esses registros também permanecem na memória, sendo agregados junto com solicitações de gravação assíncronas normais, para posteriormente serem liberados no armazenamento como TXGs (Grupos de Transação) completamente normais.

Durante a operação normal, o ZIL é gravado e nunca mais lido. Quando, após alguns momentos, os registros do ZIL são enviados para o armazenamento principal em TXGs regulares da RAM, eles são separados do ZIL. A única vez que algo é lido no ZIL é durante a importação de um pool.

Se ocorrer uma falha do ZFS — uma falha no sistema operacional ou uma queda de energia — enquanto houver dados no ZIL, esses dados serão lidos durante a próxima importação do pool (por exemplo, quando o sistema de failover for reiniciado). Tudo o que estiver no ZIL será lido, agrupado em TXGs, enviado ao armazenamento principal e depois separado do ZIL durante o processo de importação.

Uma das classes auxiliares do vdev é chamada LOG ou SLOG, um dispositivo LOG secundário. Ele tem uma tarefa - fornecer ao pool um dispositivo vdev separado e, de preferência, muito mais rápido, com resistência de gravação muito alta, para armazenar ZIL, em vez de armazenar ZIL no armazenamento vdev principal. O próprio ZIL se comporta da mesma forma, independentemente do local de armazenamento, mas se o vdev com LOG tiver desempenho de gravação muito alto, as gravações síncronas serão mais rápidas.

Adicionar vdev com LOG ao pool não funciona não pode melhorar o desempenho de gravação assíncrona - mesmo se você forçar todas as gravações no ZIL com zfs set sync=always, eles ainda estarão vinculados ao armazenamento principal no TXG da mesma forma e no mesmo ritmo que sem o log. A única melhoria direta no desempenho é a latência de gravação síncrona (já que velocidades de log mais altas tornam as operações mais rápidas sync).

No entanto, em um ambiente que já requer muitas gravações síncronas, o vdev LOG pode acelerar indiretamente as gravações assíncronas e as leituras sem cache. Descarregar registros ZIL para um vdev LOG separado significa menos contenção de IOPS no armazenamento primário, o que melhora o desempenho de todas as leituras e gravações até certo ponto.

Instantâneos

O mecanismo de cópia na gravação também é uma base necessária para instantâneos atômicos do ZFS e replicação assíncrona incremental. O sistema de arquivos ativo possui uma árvore de ponteiros que marca todas as entradas com dados atuais - quando você tira um instantâneo, basta fazer uma cópia dessa árvore de ponteiros.

Quando um registro é substituído no sistema de arquivos ativo, o ZFS primeiro grava a nova versão do bloco no espaço não utilizado. Em seguida, desanexa a versão antiga do bloco do sistema de arquivos atual. Mas se algum instantâneo fizer referência a um bloco antigo, ele ainda permanecerá inalterado. O bloco antigo não será realmente restaurado como espaço livre até que todos os instantâneos que fazem referência a esse bloco sejam destruídos!

replicação

Noções básicas do ZFS: armazenamento e desempenho
Minha biblioteca Steam em 2015 tinha 158 GiB e incluía 126 arquivos. Isso está bem próximo da situação ideal para o rsync - a replicação do ZFS pela rede foi "apenas" 927% mais rápida.

Noções básicas do ZFS: armazenamento e desempenho
Na mesma rede, replicar um único arquivo de imagem de máquina virtual do Windows 40 de 7 GB é uma história completamente diferente. A replicação ZFS é 289 vezes mais rápida que o rsync - ou "apenas" 161 vezes mais rápida se você for experiente o suficiente para chamar o rsync com a opção --inplace.

Noções básicas do ZFS: armazenamento e desempenho
Quando uma imagem de VM é dimensionada, o rsync emite escala com ela. O tamanho de 1,9 TiB não é tão grande para uma imagem de VM moderna, mas é grande o suficiente para que a replicação ZFS seja 1148 vezes mais rápida que o rsync, mesmo com o argumento rsync --inplace

Depois de entender como funcionam os snapshots, será fácil compreender a essência da replicação. Como um instantâneo é simplesmente uma árvore de ponteiros de registro, segue-se que se fizermos zfs send snapshot, então enviamos esta árvore e todos os registros associados a ela. Quando passarmos por isso zfs send в zfs receive no objeto de destino, ele grava o conteúdo real do bloco e a árvore de ponteiros que faz referência aos blocos no conjunto de dados de destino.

As coisas ficam ainda mais interessantes no segundo zfs send. Agora temos dois sistemas, cada um contendo poolname/datasetname@1, e você tira um novo snapshot poolname/datasetname@2. Portanto, no pool de origem você tem datasetname@1 и datasetname@2, e no pool de destino há apenas o primeiro instantâneo datasetname@1.

Porque entre a origem e o destino temos um instantâneo comum datasetname@1, nós podemos fazer isso incremental zfs send no topo disso. Quando dizemos ao sistema zfs send -i poolname/datasetname@1 poolname/datasetname@2, ele compara duas árvores de ponteiros. Quaisquer ponteiros que existam apenas em @2, obviamente referem-se a novos blocos - então precisaremos do conteúdo desses blocos.

Em um sistema remoto, o processamento incremental send tão simples. Primeiro escrevemos todas as novas entradas incluídas no fluxo sende adicione ponteiros a esses blocos. Voilá, nós temos @2 no novo sistema!

A replicação incremental assíncrona do ZFS é uma grande melhoria em relação aos métodos anteriores não baseados em snapshots, como o rsync. Em ambos os casos, apenas os dados alterados são transferidos - mas o rsync deve primeiro ler do disco todos os dados de ambos os lados para verificar a soma e compará-la. Por outro lado, a replicação ZFS não lê nada além de árvores de ponteiros — e quaisquer blocos que não estejam representados no instantâneo geral.

Compressão integrada

O mecanismo de cópia na gravação também simplifica o sistema de compactação integrado. Em um sistema de arquivos tradicional, a compactação é problemática - tanto a versão antiga quanto a nova versão dos dados alterados estão no mesmo espaço.

Se você considerar um dado no meio de um arquivo que começa como um megabyte de zeros de 0x00000000 e assim por diante - é muito fácil compactá-lo em um único setor no disco. Mas o que acontece se substituirmos esse megabyte de zeros por um megabyte de dados incompressíveis, como JPEG ou ruído pseudoaleatório? De repente, esse megabyte de dados exigirá não um, mas 256 setores de 4 KiB, e apenas um setor será reservado neste espaço do disco.

O ZFS não tem esse problema, pois os registros modificados são sempre gravados no espaço não utilizado - o bloco original ocupa apenas um setor de 4 KiB e uma nova gravação ocupará 256, mas isso não é um problema - um fragmento modificado recentemente de o "meio" do arquivo seria gravado no espaço não utilizado, independentemente de seu tamanho ter mudado ou não, portanto, esta é uma situação completamente normal para o ZFS.

A compactação ZFS integrada está desabilitada por padrão e o sistema oferece algoritmos conectáveis ​​- atualmente incluindo LZ4, gzip (1-9), LZJB e ZLE.

  • LZ4 é um algoritmo de streaming que oferece compactação e descompactação extremamente rápidas e benefícios de desempenho para a maioria dos casos de uso - mesmo em CPUs bastante lentas.
  • GZIP é um algoritmo venerável que todos os usuários Unix conhecem e amam. Ele pode ser implementado com níveis de compactação de 1 a 9, com taxa de compactação e uso de CPU crescentes à medida que você se aproxima do nível 9. O algoritmo é adequado para todos os casos de uso de texto (ou outros altamente compressíveis), mas geralmente causa problemas de CPU de outra forma - use-o com cautela, especialmente em níveis mais elevados.
  • LZJB - algoritmo original em ZFS. Está obsoleto e não deve mais ser usado, o LZ4 é superior em todos os sentidos.
  • ZLE — codificação de nível zero, codificação de nível zero. Ele não toca nos dados normais, mas compacta grandes sequências de zeros. Útil para conjuntos de dados totalmente incompressíveis (como JPEG, MP4 ou outros formatos já compactados), pois ignora dados incompressíveis, mas compacta o espaço não utilizado nos registros resultantes.

Recomendamos a compactação LZ4 para quase todos os casos de uso; a penalidade de desempenho ao lidar com dados incompressíveis é muito pequena e crescimento o desempenho para dados típicos é significativo. Copiar uma imagem de máquina virtual para uma nova instalação do sistema operacional Windows (sistema operacional recém-instalado, sem dados ainda) de compression=lz4 passou 27% mais rápido do que com compression=noneEm esse teste de 2015.

ARC - cache de substituição adaptativo

ZFS é o único sistema de arquivos moderno que conhecemos que usa seu próprio mecanismo de cache de leitura, em vez de depender do cache de páginas do sistema operacional para armazenar cópias de blocos lidos recentemente na RAM.

Embora o cache nativo tenha seus problemas - o ZFS não pode responder a novas solicitações de alocação de memória tão rapidamente quanto o kernel, portanto, uma nova chamada malloc() a alocação de memória pode falhar se exigir RAM atualmente ocupada pelo ARC. Mas há bons motivos para usar seu próprio cache, pelo menos por enquanto.

Todos os sistemas operacionais modernos conhecidos, incluindo MacOS, Windows, Linux e BSD, usam o algoritmo LRU (menos usado recentemente) para implementar o cache de página. Este é um algoritmo primitivo que empurra um bloco em cache "para o topo da fila" após cada leitura e empurra os blocos "para o fundo da fila" conforme necessário para adicionar novas falhas de cache (blocos que deveriam ter sido lidos do disco em vez de do cache) para o topo.

Normalmente, o algoritmo funciona bem, mas em sistemas com grandes conjuntos de dados de trabalho, o LRU leva facilmente ao thrashing – despejando blocos frequentemente necessários para abrir espaço para blocos que nunca mais serão lidos do cache.

ARC é um algoritmo muito menos ingênuo que pode ser considerado um cache “ponderado”. Cada vez que um bloco em cache é lido, ele fica um pouco mais pesado e mais difícil de ser removido - e mesmo depois que o bloco é removido monitorados durante um determinado período de tempo. Um bloco que foi removido, mas que precisa ser lido novamente no cache, também ficará mais pesado.

O resultado final de tudo isso é um cache com uma taxa de acertos muito maior – a proporção entre acertos do cache (leituras do cache) e falhas (leituras do disco). Esta é uma estatística extremamente importante - não apenas os acertos de cache são atendidos em ordens de magnitude mais rápidas, como também os acertos de cache podem ser atendidos mais rapidamente, já que quanto mais acertos de cache houver, menos solicitações paralelas ao disco e menor será a latência para os erros restantes. que deve ser atendido com disco.

Conclusão

Agora que cobrimos a semântica básica do ZFS – como funciona a cópia na gravação, bem como os relacionamentos entre pools de armazenamento, dispositivos virtuais, blocos, setores e arquivos – estamos prontos para discutir o desempenho no mundo real com numeros reais.

Na próxima parte, veremos o desempenho real dos pools vdev e RAIDz espelhados, em comparação entre si e também em comparação com as topologias RAID tradicionais do kernel Linux que examinamos mais cedo.

A princípio queríamos cobrir apenas o básico - as próprias topologias ZFS - mas depois este Estaremos prontos para falar sobre configuração e ajuste mais avançados do ZFS, incluindo o uso de tipos auxiliares de vdev como L2ARC, SLOG e Alocação Especial.

Fonte: habr.com

Adicionar um comentário