Entendendo o RESP: O Protocolo por Trás do Redis
No meu post anterior, compartilhei uma visão geral do meu clone do Redis construído com Node.js. Agora, quero explicar uma parte crítica deste projeto: o RESP, ou Redis Serialization Protocol.
O Redis não recebe arrays JavaScript prontos. Ele recebe bytes brutos através de um socket TCP. Para funcionar, esses bytes precisam de uma estrutura. O servidor deve saber onde um comando começa e termina. Ele deve saber quantos argumentos existem e qual o comprimento de cada um.
O RESP fornece essa estrutura. É a linguagem que clientes e servidores usam para conversar.
Por exemplo, o comando GET name se parece com isto no RESP: *2\r\n$3\r\nGET\r\n$4\r\nname\r\n
Aqui está a decomposição:
- *2 significa um array com 2 elementos.
- $3 significa que a próxima parte tem 3 bytes de comprimento: GET.
- $4 significa que a próxima parte tem 4 bytes de comprimento: name.
O parser transforma esses bytes em ["GET", "name"]. Agora o motor pode executar o comando.
Por que não apenas dividir as strings por espaços? A divisão simples falha com valores que contêm espaços, como SET message "hello world". Também falha com dados binários. O RESP resolve isso incluindo o comprimento de cada valor. O servidor lê exatamente o número de bytes especificado. Isso o torna binary-safe e confiável.
A lição mais difícil foi aprender que o TCP é baseado em fluxo (stream), não em mensagens. Um servidor nem sempre recebe um comando completo de cada vez. Um comando pode chegar em dois pedaços separados. Ou, múltiplos comandos podem chegar em um único pedaço.
Isso significa que o parser não pode assumir que um evento de dados equivale a um comando. O parser deve usar um buffer interno.
Meu parser RESP funciona assim:
- Receber bytes do socket.
- Adicionar bytes a um buffer.
- Tentar fazer o parse de um comando completo.
- Se o comando estiver incompleto, aguardar mais dados.
- Se um comando estiver completo, retorná-lo.
- Se sobrarem dados extras, mantê-los no buffer para o próximo parse.
Um banco de dados começa na camada de protocolo. Antes que o Redis possa armazenar dados, ele deve entender o comando. Antes de retornar um valor, ele deve codificar a resposta.
Implementar o RESP transformou um simples servidor TCP em um verdadeiro sistema compatível com o Redis. Isso mudou a forma como vejo sistemas de backend. Um protocolo é mais do que um formato. É um contrato entre dois sistemas.
No meu próximo post, abordarei a camada de armazenamento em memória.
Repositório: https://github.com/Abhinov007/redis_clone Sandbox ao vivo: https://abhinov007.github.io/Redis_Clone/ Fonte: https://dev.to/abhinov007/understanding-resp-the-protocol-behind-redis-50p4