Meus aprendizados com a Rinha de Backend 2023 Q3
Tags: backend, database, docker, rinha
Published: 2024-02-22 18:03:42

A rinha de backend foi um evento incrível, e mesmo não acompanhando em *real time*, pude revisar os vídeos e tweets recentemente e fiquei muito impressionado com o que vi. Decidi compilar aqui os principais aprendizados que retirei desta competição.

## Docker

Docker sempre foi uma ferramenta que eu meio que negligenciei pra falar a verdade :)

Embora na maioria das empresas não tenhamos muito contato direto com a infraestrutura como desenvolvedores, acredito que valha a pena entender pelo menos o básico

Indo direto ao ponto, a técnica que realmente fez diferença pra rinha:

### network_mode: host

Basicamente, com Docker, podemos escolher alguns modos diferente para trabalharmos com rede. O modo padrão é o `bridge`, onde o Docker utiliza uma rede interna e privada (ao host) e os containers podem se comunicar uns com os outros através dos seus container names (que são utilizados como hostname), além de poderem se comunicar com a rede externa através de NAT.

Outro modo é o `host`,  onde os containers terão acesso direto as network interfaces do seu host, **o que aumenta a performance**. No entanto, é necessário ter cuidado para evitar conflitos, já que as portas reais são usadas.

Como a rinha em si não dizia nada a respeito de restrições de network no `docker-compose`, poderíamos aproveitar do modo `host` e ganhar uma performance maior.

#### Porquê o network_mode host é mais rápido?

O modo `bridge` na verdade que é mais lento, isso porque ele introduz uma camada extra sobre a rede do próprio host, um DNS interno, no qual o Docker precisa traduzir um container name para um endereço IP da rede.

Lembrando que os ganhos desse modo só são mais perceptíveis quando estamos falando de **containers rodando no mesmo host**.

Post de [ref](https://yangwwei.github.io/2017/11/22/docker-network-tests.html) com alguns benchmarks.

## Banco de dados

### Monitoramento e benchmarks

Aqui temos uns aprendizados bem interessantes.

Bancos de dados, especialmente os relacionais, costumam ser ferramentas familiares para os desenvolvedores, porém, são poucos os que possuem conhecimento em benchmarks, otimização e performance.

Na rinha, ficou claro que o banco de dados em si não era o gargalo, mas sim a configuração correta do mesmo. Para atingir o máximo desempenho nos testes da rinha, era necessário alocar os recursos adequadamente entre a aplicações, load balancer e o banco de dados.

Em um ambiente aberto e com restrições mais alto nível (algo como a EC2 “crua” da AWS), podemos rodar serviços na mesma máquina, dividindo recursos entre os diferentes serviços, assim como era o cenário da rinha.

Para mensurar e distribuir corretamente esses recursos, é necessário usar ferramentas de monitoramento nos serviços. Para o banco de dados, temos ferramentas como pgAdmin ou o MySQL Workbench, ajudando a enxergar e tunar o uso de CPU, memória e número de conexões.

Em resumo, o aprendizado que fica é: não assuma nada, sempre meça e tire suas conclusões. Em alguns casos, estamos restritos por outros fatores, o que facilita o calculo dos recursos necessários  ou número de conexões, mas em casos mais abertos, medir e chegar no número ideal é a melhor abordagem.

### Queries em campos de texto

Um aprendizado mais específico, nem sempre precisamos lidar com buscas desse tipo, mas é interessante termos essa técnica nosso “cinto de utilidades”.

Queries com `ILIKE` tendem a ser lentas e não conseguimos usar índices de forma convencional. O Postgres tem acesso nativo a index do tipo GIST que servem pra indexar campos de texto e otimizar queries deste tipo. No entanto, mesmo com esse índice, ainda teríamos que executar o `OR` em 3 campos diferentes e juntar os resultados, o que ainda tornaria a query lenta.

A solução inteligente neste caso é unir os 3 campos em um só e indexar via GIST este campo, assim conseguimos atingir máxima performance para este tipo de query especifica.

Vale ressaltar que utilizar o `EXPLAIN` é uma ferramenta valiosa pra nos ajudar a identificar o planejamento da query pelo banco e, assim, traçar estratégias, como essa mencionada, para otimizar queries.

Um último adendo é que embora o Postgres, ou outros bancos com suporte a _full text search_, consigam lidar bem com muitos casos, é importante estar atento se no nosso caso e escala específica já não estamos em um cenário em que ferramentas extremamente especializadas começam a fazer sentido, como o Elasticsearch. Precisamos sempre balancear os tradeoffs e ver quando estamos atingindo o limite da tecnologia que temos no momento e, ai sim, migrar pra outra que atenda nossos requisitos.

## Conclusão

Foram muitos aprendizados bacanas com a rinha e eu acho que esse é o tipo de competição saudável que ajuda demais a comunidade, deixo aqui meus agradecimentos ao [Zan Franceschi](https://twitter.com/zanfranceschi), organizador e idealizador da rinha e ao [Akita](https://twitter.com/AkitaOnRails) e o [MrPowerGamerBR](https://twitter.com/MrPowerGamerBR), pelos ótimos videos explicativos sobre a rinha.

Estou ansioso pra acompanhar o que vai rolar nessa rinha de 2024, além de estar planejando e executando minha solução aqui ;)