Log de eventos assíncronos e de alto desempenho no ShareThis
por Fadi Obeid, Engenheiro Principal & Tech Lead, Produtos Publicitários
Se você trabalhou em ou com tempo real, você provavelmente teve que lidar com o registro de eventos. No ShareThis, nós somos todos sobre tempo real - coletamos sinais sociais conforme eles acontecem, aplicamos a lógica de negócios a esses sinais e finalmente transformamos esses sinais em regras complexas de ad-targeting.
Neste post vamos cobrir o registro de eventos no aspecto de escala. Uma versão simplificada do nosso pipeline parece ser a seguinte:
O fluxo de Kafka está bombeando cerca de 800 milhões-1 bilhão de eventos / dia. Cada evento se expande em uma média de 12 eventos virtuais, portanto a lógica de negócios dentro do cluster de consumidores Kafka terá que processar e avaliar 9-12 bilhões de eventos por dia, e registrar os eventos qualificados em disco.
Inicialmente, tínhamos um mapeamento 1×1 de evento bruto para evento virtual, o que não era grande coisa, uma vez que tínhamos "máquinas suficientes". A capacidade de cluster era de 3 instâncias c3.xlarge e era apoiada por um logger síncrono de origem.
Com o tempo, o mapeamento aumentou - de 1×1 para 1×3 e assim por diante. Cada caixa Kafka no aglomerado estava rodando com 25 fios, e em carga, o efeito de travar a operação de escrita, como visto neste trecho de código, foi paralisante. O executor do conjunto de fios estava ficando para trás em sua capacidade de atender o pedido de entrada, e o offset Kafka começou a ficar para trás, às vezes até um ponto em que nunca conseguia alcançar.
Um perfil dos fios de corrida mostrou que os fios estão bloqueados quase o tempo todo, yikes!
Começamos a olhar para as nossas opções. A nossa lista resumiu-se a isso:
- Adicionar mais máquinas
- Registrador assíncrono caseiro
- Log4j2 assíncrono + disruptor + RandomAccessFile
Passamos por prós e contras e aterrissamos em Log4j2. Fizemos um benchmarking, e os resultados foram muito impressionantes. Para os fins deste post, estamos mostrando dois gráficos: o primeiro mostra a produção em cargas baixas, e o segundo mostra a produção em cargas altas. A parte boa foi como foi fácil ligá-lo ao projeto existente, ao suporte e à ampla documentação.
Em conclusão, podemos dizer com segurança que a nossa escolha "log4j2 asynchronous + disruptor + RandomAccessFile" para o registo foi a correcta. Se você estiver passando por um processo similar, recomendamos que você trace o perfil da sua aplicação, exponha suas opções e faça um benchmarking.