Executando verificação de segurança...
1

Tenho cenário semelhante, mas em menor escala, porém mesmo assim uma grande volumetria - 400~600 tps em média no tópico Kafka. No passado, o workers inseriam do jeito tradicional, com insert into table(....) values (...) ou update table set.... Esse algoritmo ruim, não dava conta de sincronizar, estava sempre com lag, e ao escalar os workers, começava a catástrofe do ambiente. O alto número do workers fazia o DB ficar sempre com carga excessiva, acima de 80% de CPU.

Fiz um mudança pequena, no lugar de inserir/atualizar com comandos SQL cada mensagem recebida do tópico (q demanda mais cpu pra parser no db), passei a fazer bulk upsert da seguinte forma:

  1. Agrupar mensagens do tópico em pacotes antes de enviar pro DB. Fiz duas regras de corte do pacote: 5 mil mensagens, ou 10 segundos sem receber mensagens.
  2. Criar uma temporary table copiada da original (create temp table nome_temporario on commit drop as table nome_original with no data)
  3. Inserir o pacote de mensagens agrupadas com o com copy from stdin...
  4. Ao final copiar dados da tabela temporária para original com comando de upsert: insert into tabela(campos) values (valores) on conflict (campo pk) do update campos. (Com índice único, pois tb tenho situação parecida de duplicidades de msgs).
  5. Tudo isso é uma transaction.l

Com isso, reduzi o uso de CPU de 85% pra 13~15% em média, e sem lag.
Hj o db é um aurora postgresql r6g.large (2 cpu x 16 ram), e o worker é apenas uma instância de ecs com 0.5 cpu x 1 gb de ram (e até poderia ser menor, mas tem outras coisas internas q não vem ao caso aqui).

A otimização do worker, normalizou o resto do ambiente, apis q dependem desse db obviamente passaram a responder mais rápido, e de propósito não deixo mais o worker escalar pra não degradar o ambiente, embora com o novo algoritmo não deva ser problema processar umas 500 milhões de msg por dia no mesmo hardware.

Pro seu cenário de big data sobre telemetria de aplicações, tb julgo correta a mudança pra um DB colunar pra otimizar as consultas com agregações, só queria compartilhar essa solução de carga de alto volume de dados em postgresql após ler essa parte em específico da sua saga. Pretendo montar um post para explicar em maiores detalhes.
Pra quem se interessar, aqui tem alguns benchmarks e exemplos do que venho preparando.

Valeuuu, e novamente parabéns pela história e por compartilhar.

Carregando publicação patrocinada...
1

muito interessante seu comentário.
realmente é uma solução robusta.

vou estudar sobre essa ideia pra implementações futuras em outros DBs.

sobre o insert em bulk que vc mencionou, tive que fazer algo similar no PostgreSQL antes.

também deixava acumular em memória um lote de 5-10k linhas na aplicação (puxando em lotes tambem do kafka)

e depois mandava pro insert no PostgreSQL de uma vez.

cada uma das instâncias fazia isso de forma independente.

mas no meu cenário não existe update, é so inserir mesmo, então imagino que isso tenha evitado de eu ter esse problema que você descreveu no seu caso.

mas bom saber que tem uma solução pra esse tipo de situação também.

vou deixar aqui indexado no meu notion esse seu comentário pra aprendizado futuro.