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

Fala pessoal! Tudo bem?

Pô, essa ideia de salvar o último saldo em uma coluna é muito boa e diminui bastante o tempo de leitura. Já cogitamos utilizá-la aqui no Pagar.me. Mas, como toda ideia, possui alguns tradeoffs que acabaram fazendo com que não seguíssemos com essa abordagem.

Quando discutimos um pouco mais a fundo esta ideia, percebemos que a vantagem de ter o cálculo de saldo mais rápido nos traria um custo: a escrita neste caso precisa ser serial. Dessa forma você garante a consistência das entradas e saídas. Mas, dependendo do volume de inserções na tabela de saldo, a serialização aumentará o tempo para processar a geração de saldo.

Esta solução é muito viável para os casos onde o volume de dados inseridos não é muito grande. Porém, não se provou muito escalável no nosso caso. Mesmo que utilizássemos critérios mais específicos para lock dos registros (por cliente, por exemplo), alguns casos ainda geravam gargalo.

Carregando publicação patrocinada...
1

Fala Galerinha Massa!

Acho que ficou pra aula 2 👨‍🏫 mostrar mais detalhes do cache implementado no Pagar.me pra gente ver melhor o tradeoff 🤓, mas algo importante para avaliar é a proporção de leituras/gravações de saldo em cada um dos dois sistemas.

Imagino que no Pagar.me o número de leituras de saldo seja um pouco maior que o de gravações, mas no TabNews o número de leituras vai ser ordens de grandeza maior do que o de gravações. Pelo menos foi o que considerei quando fiz essa sugestão na PR #462 que é bem alinhada com a sugestão do Rodrigo.

Para impedir inconsistências, poderia colocaria uma coluna a mais que seta o saldo acumulado como outdated quando outro saldo acumulado é calculado. Com isso, no início da transação, é feito o lock da linha que continha o saldo mais atual e, ao final da transação, ele é setado como outdated. Assim a escrita ocorreria de forma serial para cada usuário/conteúdo, sem risco de inconsistência.

->sequencebalance_typerecipient_idamountlast_balanceoutdated<-
...1user:tabcoinaa55true...
...2content:tabcoinbb11true...
...3user:tabcoinaa510false...
...4content:tabcoinbb12false...

O que acham dessa abordagem?

1

Sobre escrita/leitura no TabNews, não tinha parado para pensar. O que podemos especular talvez é o seguinte: sempre usaremos páginas estáticas (e mais para frente inclusive o retorno da API também deveria estar sob o efeito de cache). Mas em contra partida, cada tabcoin doada ou retirada (que seriam os "up votes" ou "down votes" de um conteúdo) irá gerar novas escritas no banco (novos lançamentos de balance_operations).

Mas independente disso, eu chutaria que por um bom tempo nada disso será gargalo, independente da estratégia adotada. Se isso for uma verdade, eu prefiro sempre utilizar a estratégia mais simples e bruta.

PS: o layout de tabelas que vocês estão usando está sensacional heim? Nota 10 😍 🤝

1

Penso que o número de leituras será muito maior do que o de escritas pelo seguinte...

Vamos partir de uma situação de cache ideal, onde nenhuma nova consulta ao banco de dados será necessária enquanto não houver nenhuma escrita.

Nesse caso, o quanto o número de leituras vai ser maior do que o de escritas irá depender somente do algoritmo utilizado para classificar a relevância dos conteúdos.

Dependendo desse algoritmo, uma única gravação (inclusão de novo conteúdo ou "curtida"), vai gerar a necessidade de reclassificar todo ou parte dos conteúdos, e para isso serão necessárias diversas leituras, não somente no conteúdo novo/alterado, mas em todos que serão reclassificados.

Só aí já serão várias leituras a mais do que escritas... Agora indo para a realidade, em que o cache demandará algumas revalidações, aumenta ainda mais o número de leituras com relação a escritas.

Resumindo... A depender do algoritmo de classificação e das estratégias de cache, teremos ordens de grandeza diferentes na razão entre leituras e gravações, mas, de qualquer forma, serão muito mais leituras.

PS: O Rodrigo caprichou mais na tabela, pois até centralizou o conteúdo... hahaha

1

Sensacional!

E você usou uma palavra que eu ainda não entendo completamente no caso de banco de dados que é serial, mas que nesse caso eu entendo que é uma coisa que precisa ser seguida da outra mandatoriamente, correto? Isso tem a ver com o termo serializable do Postgres? Tem alguma coisa nesse termo que eu ainda não consigo entender.

Algo que não precise ser serializable é mais rápido, por exemplo uma transaction pode ser configurada para não ser serializable, com o risco de retornar um erro se a ordem dos eventos não produzir o mesmo resultado se estiverem em ordens diferentes?

1

Então, o termo serial não necessariamente está ligado ao nível de isolamento serializable. Quer dizer apenas que as operações precisam estar enfileiradas, pois quando você quer criar uma operação debitando valores de uma conta, você precisa garantir que existe saldo e nenhuma outra operação irá ser executada simultaneamente.

Os níveis de isolamento são usados de acordo com anomalias que você quer (ou não) evitar ao lidar com transações no banco de dados.

Na documentação do Postgres tem uma explicação interessante sobre as anomalias e quais são evitadas com cada nível de isolamento. O serializable, por exemplo, evita todas elas, mas para isso ele exige que as operações sejam executadas de maneira isolada.

1

Estou vendo que vamos bugar o layout do tabnews. Isso é ótimo porque estamos em uma real discussão mostrando que existe uma melhoria necessária de layout.😄️

@jeanaugustoos nossa que legal receber seu feedback aqui!

Resumindo para conseguir deixar a tabela serializable vamos perder tempo na inserção, comparado com uma tabela não serializable ?

A forma que estamos fazendo de somar todos os registros para receber o saldo, o tempo é bem maior que o exemplo que informei utilizando a tabela serializable, certo?

1

Sobre o layout do TabNews, eu sugiro remover o padding a direita, e caso ficar muito apertadinho, fazer como o reddit, onde é possível clicar em "ver mais" onde abre como se fosse uma página de continuação r

1

Na PR #425, que vai ser analisada após a implementação das TabCoins, entre várias mudanças que corrigem problemas em telas pequenas, eu diminuí o padding da direita para 1px.

Depois vou subir essa versão e coloco o link aqui.