Como validar transferências de dados entre o HDFS e o Cloud Storage

É recomendável realizar algum tipo de validação para garantir a integridade dos dados ao copiá-los ou movê-los entre sistemas de armazenamento distintos, como clusters de vários sistemas de arquivos distribuídos do Apache Hadoop (HDFS, na sigla em inglês), ou entre HDFS e o Cloud Storage. Essa validação é essencial para garantir que eles não sejam alterados durante a transferência.

Ainda que vários mecanismos já garantam a integridade de dados ponto a ponto em trânsito, como o TLS (links em inglês) para toda a comunicação com o Cloud Storage, a validação explícita da integridade de dados completa aumenta a proteção em casos que podem passar despercebidos por mecanismos típicos em trânsito. Isso pode ajudar a detectar uma possível corrupção de dados causada, por exemplo, por links de rede ruidosos, erros de memória em servidores e roteadores ao longo do caminho ou bugs de software (como em uma biblioteca que os clientes usam).

Para o Cloud Storage, essa validação acontece automaticamente no lado do cliente com comandos como gsutil cp e rsync. Esses comandos calculam as somas de verificação (em inglês) de arquivos locais, que são validadas em relação às somas de verificação calculadas pelo Cloud Storage no final de cada operação. Se as somas de verificação não forem correspondentes, gsutil excluirá as cópias inválidas e imprimirá uma mensagem de aviso. Essa incompatibilidade raramente acontece e, caso aconteça, é possível repetir a operação.

Agora também há uma maneira de executar automaticamente a validação de completa do lado do cliente no Apache Hadoop em sistemas de arquivos heterogêneos compatíveis com o Hadoop, como HDFS e Cloud Storage. Neste artigo, descreveremos como o novo recurso permite comparar de forma eficiente e precisa as somas de verificação dos arquivos.

Como o HDFS executa as somas de verificação de arquivos

O HDFS usa o CRC32C, uma verificação de redundância cíclica (CRC, na sigla em inglês) de 32 bits baseada no polinômio de Castagnoli, para manter a integridade dos dados em diferentes contextos:

  • Em repouso, o Hadoop DataNodes verifica continuamente os dados em relação aos CRCs armazenados para detectar e reparar o bit-rot (em inglês).
  • Em trânsito, os DataNodes enviam CRCs conhecidos junto com os dados em massa correspondentes, e as bibliotecas de cliente HDFS cooperam entre si para calcular os CRCs por bloco e comparar com os CRCs recebidos dos DataNodes.
  • Para fins administrativos do HDFS, as somas de verificação no nível de bloco são usadas para verificações manuais de integridade (em inglês) de nível inferior de arquivos de bloco individuais em DataNodes.
  • Para casos de uso arbitrários da camada de aplicativo, a interface FileSystem define getFileChecksum e a implementação do HDFS usa CRCs detalhados armazenados para definir uma soma de verificação no nível do arquivo.

Para a maioria dos usos diários, os CRCs são usados de forma transparente em relação à camada de aplicativo. Os únicos CRCs usados são os CRC32Cs por parte, que já estão pré-calculados e armazenados em arquivos de metadados junto aos dados de bloco. O tamanho do bloco é definido por dfs.bytes-per-checksum e tem um valor padrão de 512 bytes.

Falhas do tipo das somas de verificação do arquivo padrão do Hadoop

Por padrão, quando se usa o Hadoop, todas as somas de verificação expostas à API assumem a forma de MD5 (em inglês) de uma concatenação de partes CRC32Cs, no nível de bloco por meio do DataTransferProtocol de nível inferior ou no arquivo por meio da interface FileSystem de nível superior. Uma soma de verificação no nível do arquivo é definida como o MD5 da concatenação de todas as somas de verificação do bloco, cada uma sendo um MD5 de uma concatenação de CRCs de fragmentos e, portanto, é chamada de MD5MD5CRC32FileChecksum. Esta é efetivamente uma árvore Merkle (em inglês) de três camadas sob demanda.

Essa definição da soma de verificação no nível do arquivo é sensível à implementação e aos detalhes do layout de dados do HDFS, ou seja, o tamanho da parte (padrão 512 bytes) e o tamanho do bloco (padrão 128 MB). Portanto, essa soma de verificação de arquivo padrão não é adequada em nenhuma das situações a seguir:

  • Duas cópias diferentes dos mesmos arquivos no HDFS, mas com diferentes tamanhos de bloco por arquivo configurados
  • duas instâncias diferentes de HDFS com tamanhos de blocos ou partes diferentes configurados
  • Uma combinação de HDFS e sistemas de arquivos compatíveis com Hadoop (HCFS, na sigla em inglês) não-HDFS, como o Cloud Storage

No diagrama a seguir, mostramos como o mesmo arquivo pode ter diferentes somas de verificação, dependendo da configuração do sistema de arquivos:

Divergência de soma de verificação

É possível exibir a soma de verificação padrão de um arquivo no HDFS usando o comando fs -checksum do Hadoop:

hadoop fs -checksum hdfs:///user/bob/data.bin

Em um cluster HDFS com tamanho de bloco de 64 MB (dfs.block.size=67108864), este comando exibe um resultado como este:

hdfs:///user/bob/data.bin   MD5-of-131072MD5-of-512CRC32C   000002000000000000020000e9378baa1b8599e50cca212ccec2f8b7

Para o mesmo arquivo em outro cluster com tamanho de bloco de 128 MB (dfs.block.size=134217728), você verá uma saída diferente:

hdfs:///user/bob/data.bin   MD5-of-0MD5-of-512CRC32C    000002000000000000000000d3a7bae0b5200ed6707803a3911959f9

Nesses exemplos, veja que as duas somas de verificação diferem para o mesmo arquivo.

Como funciona a nova soma de verificação do arquivo CRC composto do Hadoop

Um novo tipo de soma de verificação, rastreado no HDFS-13056 (em inglês), foi lançado no Apache Hadoop 3.1.1 para resolver essas deficiências. O novo tipo, configurado por dfs.checksum.combine.mode=COMPOSITE_CRC, define CRCs de bloco composto e CRCs de arquivo composto como CRC matematicamente composto entre os CRCs de bloco armazenados. A utilização desse tipo substitui o uso de um MD5 dos CRCs do componente para calcular um único CRC que representa o bloco ou arquivo inteiro e é independente da granularidade de nível mais baixo dos CRCs em partes.

A composição do CRC tem muitos benefícios: é eficiente, permite que as somas de verificação resultantes sejam totalmente independentes de partes/blocos e permite a comparação entre arquivos distribuídos e replicados, entre diferentes instâncias do HDFS e entre o HDFS e outros sistemas de armazenamento externo. Saiba mais detalhes sobre o algoritmo de CRC neste download em PDF.

No diagrama a seguir, veja como a soma de verificação de um arquivo é consistente após a transferência entre configurações de sistemas de arquivos heterogêneos:

Correspondência de soma de verificação

Esse recurso é minimamente invasivo: ele pode ser adicionado para ser compatível com os metadados de bloco atuais e não é necessário alterar o caminho normal da verificação de parte. Isso também significa que mesmo grandes implantações preexistentes do HDFS podem adotar esse recurso para sincronizar dados retroativamente. Para mais detalhes, é possível fazer o download do documento PDF de design completo.

Como usar o novo tipo de soma de verificação de CRC composto

Para usar o novo tipo de soma de verificação de CRC compostas no Hadoop, defina a propriedade dfs.checksum.combine.mode como COMPOSITE_CRC (em vez do valor padrão MD5MD5CRC). Quando um arquivo é copiado de um local para outro, o tipo de soma de verificação no nível do bloco (isto é, a propriedade dfs.checksum.type que é padronizada como CRC32C) também precisa corresponder em ambos os locais.

É possível exibir o novo tipo de soma de verificação para um arquivo no HDFS passando o argumento -Ddfs.checksum.combine.mode=COMPOSITE_CRC para o comando fs -checksum do Hadoop:

hadoop fs -Ddfs.checksum.combine.mode=COMPOSITE_CRC -checksum hdfs:///user/bob/data.bin

Independentemente da configuração de tamanho de bloco do cluster HDFS, você vê a mesma saída, como a seguir:

hdfs:///user/bob/data.bin   COMPOSITE-CRC32C    c517d290

Para o Cloud Storage, você também precisa definir a propriedade fs.gs.checksum.type do conector do Cloud Storage como CRC32C. Essa propriedade, por outro lado, assume o padrão NONE, fazendo com que as somas de verificação de arquivo sejam desativadas por padrão. Esse comportamento padrão do conector do Cloud Storage é uma medida preventiva para evitar um problema com distcp, em que, em vez de falhar normalmente, uma exceção é gerada caso os tipos de soma de verificação não correspondam. O comando se parece com isto:

hadoop fs -Ddfs.checksum.combine.mode=COMPOSITE_CRC -Dfs.gs.checksum.type=CRC32C -checksum gs://[BUCKET]/user/bob/data.bin

O comando exibe a mesma saída do exemplo anterior no HDFS:

gs://[BUCKET]/user/bob/data.bin COMPOSITE-CRC32C    c517d290

Perceba que as somas de verificação de CRC composto retornadas pelos comandos anteriores são todas iguais, independentemente do tamanho do bloco, bem como entre o HDFS e o Cloud Storage. Usando somas de verificação de CRC composto, você garante que a integridade dos dados seja preservada ao transferir arquivos entre todos os tipos de configurações de cluster do Hadoop.

Se você estiver executando distcp, como no exemplo a seguir, a validação será executada automaticamente:

hadoop distcp -Ddfs.checksum.combine.mode=COMPOSITE_CRC -Dfs.gs.checksum.type=CRC32C hdfs:///user/bob/* gs://[BUCKET]/user/bob/

Se distcp detectar uma divergência de soma de verificação do arquivo entre a origem e o destino durante a cópia, a operação falhará e retornará um aviso.

Como acessar o recurso

O novo recurso de soma de verificação de CRC composto está disponível no Apache Hadoop 3.1.1 (consulte as notas da versão em inglês), e backports para as versões 2.7, 2.8 e 2.9 (em inglês) estão sendo criados. Isso foi incluído por padrão em versões menores do Cloud Dataproc 1.3 desde o final de 2018.