Black Friday 2016: Não deixe os erros se repetirem!

Black Friday 2016: Não deixe os erros se repetirem!

Acompanhando o hotsite sobre a BlackFriday do Reclame Aqui!, ignorando os levantamento de Propaganda enganosa, podemos ver uma boa melhora nas reclamações sobre lentidão nos sites (catálogo), mas ainda persiste o problema no fechamento da compra (carrinho).

O catálogo de produtos é algo simples de se melhorar para a Black Friday; Por não ser transacional, podemos colocar uma CDN para distribuir o conteúdo ou criar um auto-scaling – que acrescente novas instâncias de acordo com a demanda – e assim teremos uma entrega rápida e garantida do conteúdo mais acessado.

Mas e o carrinho, que é onde as compras são efetivadas e que precisa ser transacional? Como podemos torná-lo mais estável, independente do volume de compras?

Existem várias maneiras de se evitar gargalos no carrinho e sem aumentar o tamanho do servidor de banco de dados. Dependendo do volume de acessos ao banco, existem várias alternativas:

I/O de Leitura
Durante o processo de fechamento da compra, 75% dos acessos são de leitura do banco – leitura do produto, leitura das quantidades em estoque, leitura de valores e por aí vai.

Uma das soluções para o I/O de leitura – e a mais simples de implementar – é um cache in-memory das respostas da Query. Podemos fazer isto com o memcached, que é a solução mais usada ou com o Redis, um pouco mais complexa, mas que também atende às necessidades.

Vale também analisar o log de slow-querys e identificar as querys mais lentas e trabalhar os índices ou a lógica envolvida… Trabalhoso, mas compensador.

I/O de Gravação
Este é o I/O mais “pesado”, que consome mais recursos do hardware (ou instância de banco de dados) e que é o grande vilão da lentidão do fechamento de compra. A solução para esta situação é um pouco mais complexa e requer um trabalho mais detalhista no código.

Dependendo do seu fornecedor de banco de dados temos duas soluções possíveis: criar uma estrutura de Cluster “Master – Master”, onde as duas instâncias estão ativas simultaneamente ou criar uma estrutura “Master – Slave”, onde uma fica ativa para leitura e a outra para gravação.

Neste cenário, dividimos o I/O entre dois hardwares, minimizando o peso dos acessos. Uma das máquinas fica para as querys do memcached e a segunda, para a gravação das transações. Isto já alivia bastante o peso do carrinho de compras.

Na arquitetura Master – Master, com o memcached, as duas máquinas ficam ativas tanto para a leitura como para a gravação. Neste cenário, com um load-balance (HA-Proxy) configurado para balancear de acordo com o tempo de resposta, temos um cenário mais interessante, pois teremos alta-disponibilidade de banco.

Se os cenários acima ainda assim “engargalarem”, podemos tirar o peso da transação, enfileirando as transações. Ou seja, quando a compra é efetivada, a aplicação “entrega” a transação para um gerenciador de enfileiramento (Queue Manager) e finaliza a transação para o cliente. O Queue Manager se encarregará de efetivar a transação no banco de dados.

Esta última dica requer um pequeno ajuste na programação, para corrigir o resultado da query no Memcached (se ele estiver em uso) – no caso de quantidades em estoque.

Estas soluções irão resolver 90% dos problemas de lentidão no encerramento da compra. Para os outros 10%, dependendo do volume de compras, requer um trabalho mais profundo no código e/ou na infraestrutura do site de e-commerce.

Em e-commerces de grande volume, o banco de dados também precisa ser escalável, para crescer somente nos momentos de grande volume. Nesta situação, a recomendação é usar um banco de dados in-memory e escalável. Uma das alternativas que estão crescendo muito é o MemSQL(http://www.memsql.com/), que possui a versão community, que é totalmente gratuíta (http://www.memsql.com/community/).