Uso do Prefetch | RabbitMQ
- Uso do Prefetch | RabbitMQ
Quando você tem múltiplas instâncias de um worker consumindo mensagens de uma fila RabbitMQ, é fundamental configurar o prefetch (geralmente via basic_qos(prefetch_count=N)) para controlar quantas mensagens cada worker pode receber antes de confirmar (ack) as anteriores.
Sem isso, você pode acabar com desequilíbrio de carga, lentidão, ou até bloqueio.
🧠 Por que o prefetch é necessário com múltiplos workers?
1. RabbitMQ, por padrão, faz load balancing burro (round-robin)
- Ele distribui mensagens igualmente entre consumidores sem considerar sua velocidade de processamento.
- Ou seja, mesmo se um worker for lento e outro rápido, cada um recebe a mesma quantidade de mensagens.
👉 Resultado: workers lentos acumulam mensagens e viram gargalos.
2. Sem prefetch, um worker pode receber MUITAS mensagens de uma vez
Por padrão (prefetch = 0), o RabbitMQ envia mensagens ilimitadamente enquanto o worker não dá ack.
Então, se você iniciar vários workers:
- O RabbitMQ manda várias mensagens adiantadas para o worker A,
- Mesmo que o worker B esteja livre,
- A distribuição fica desigual e ineficiente.
👉 Isso causa starvation: mensagens ficam “presas” em workers mais lentos.
3. prefetch garante fair dispatch (distribuição justa)
Quando você define, por exemplo:
channel.basic_qos(prefetch_count=1)
Você diz:
“Envie no máximo 1 mensagem por vez para cada worker antes do ack.”
Então:
- Um worker só recebe outra mensagem depois que terminar a atual.
- Workers rápidos pegam mais mensagens.
- Workers lentos pegam menos.
👉 Isso maximiza throughput e mantém distribuição equilibrada.
4. Evita estouro de memória nos workers
Um worker muito rápido no recebimento mas lento no processamento pode acumular mensagens em RAM se o prefetch for alto ou ilimitado.
prefetch protege contra isso.
5. Melhora o tempo de processamento total e o SLA
Com prefetch correto:
- o RabbitMQ mantém os workers ocupados,
- mas nunca sobrecarrega um worker específico,
- evitando filas internas desnecessárias.
🎯 Em resumo
| Com múltiplas instâncias | Sem prefetch | Com prefetch |
|---|---|---|
| Distribuição das msgs | Desequilibrada | Justa |
| Possível overloaded worker | Alto | Baixo |
| Ocupação dos workers | Irregular | Ótima |
| Throughput total | Pior | Melhor |
| Uso de RAM no worker | Potencialmente alto | Controlado |
✔️ Regra de ouro
Para tasks longas:
prefetch_count = 1
Para alto throughput:
prefetch_count = 5–20 (dependendo do tipo da tarefa)