Pular para o conteúdo

Conceitos

Zero-copy I/O

Intuição

Imagine um garçom que precisa levar um prato da cozinha até a mesa: o jeito lento é passar o prato por três balcões intermediários antes de chegar ao cliente, mesmo que ninguém precise tocar nele no caminho. O jeito rápido é entregar o prato direto da cozinha à mesa. Quando um servidor manda um arquivo do disco pela rede, o caminho "lento" tradicional copia os dados várias vezes entre a memória do sistema operacional e a memória da própria aplicação antes de sair pela rede — cópias que existem só por causa de como o sistema é organizado, não porque a aplicação precisa fazer algo com esses bytes no meio do caminho.

Como funciona

No caminho tradicional de enviar um arquivo pela rede, os dados são copiados do disco para um buffer do kernel, depois para um buffer da aplicação em espaço de usuário, e depois de volta para um buffer do kernel associado ao socket de rede — várias cópias e trocas de contexto para mover bytes que a aplicação nunca precisa examinar. O Kafka evita esse caminho usando a chamada de sistema sendfile, que transfere dados diretamente de um arquivo em disco para a rede sem passar pelo espaço de memória da aplicação, eliminando as cópias intermediárias desnecessárias. Essa escolha é coerente com outra decisão de design do Kafka: em vez de manter seu próprio cache de mensagens em memória na aplicação, o broker se apoia no page cache do sistema operacional, já que produtores e consumidores acessam os arquivos de segmento de forma majoritariamente sequencial. Isso evita duplicar o mesmo dado em dois buffers (um da aplicação, um do SO) e tem a vantagem extra de que o cache continua "quente" mesmo se o processo do broker reiniciar, porque ele vive no SO e não na memória do processo. Juntas, essas duas decisões — sendfile para transferência e page cache como única camada de cache — reduzem o número de cópias de memória e trocas de contexto por mensagem, o que é exatamente o tipo de custo que domina o throughput quando o volume de dados é da ordem de centenas de gigabytes por dia.

Na prática

É por isso que sistemas de log distribuído e streaming de alto throughput como o Kafka preferem simplicidade agressiva no caminho de dados quente (append sequencial em disco, sendfile, page cache do SO) a um cache de aplicação sofisticado: em escala, o custo de cópias de memória evitáveis supera o benefício de qualquer lógica de cache mais "inteligente" feita na aplicação. Esse é o mesmo raciocínio por trás de otimizações de zero-copy em outros sistemas que servem arquivos ou streams estáticos em alto volume, como servidores web e proxies.

Use em um desenho

Pratique na escola de System Design os casos que dependem deste conceito.