Open filipedeschamps opened 1 year ago
Bom gostaria de lhe ajudar porem ja faz um bom tempo que não mexo com a AWS mais deixo aqui alguns artigos da porpria AWS sobre esse assunto que pode lhe ajudar....
Replicar backups automatizados para outra Região da AWS RDS - Backups entre regiões Copiar um snapshot de banco de dados Migrar uma instância de banco de dados Amazon RDS para outra VPC ou conta
Espero que isso te ajude...
Olá! Eu não tenho experiência com mudança de zona na AWS. Mas nosso banco de dados está na us-east-1, pois achei mais em conta. Porém, se eu precisasse fazer essa migração faria assim: 1º Criaria um banco na nova zona; 2º Escolheria um horário de menos trafego para pausar aplicação; 3º Faria o backup do banco antigo; 4º Restauraria no banco novo; e 5º Apontaria para o banco novo e retomaria a aplicação.
Acho que é uma das melhores formas para não perder nenhum dado durante a manutenção.
Eu acho que o fluxo normal seria criar uma réplica cross region somente leitura do banco e depois promover a réplica.
Se existir algum impedimento e realmente for necessário criar um novo banco e restaurar os dados, então que tal já aproveitar e migrar o banco para outro serviço?
O Supabase parece ser um ótimo substituto, pois oferece muitas facilidades e cobra apenas um pouco mais do que a AWS.
Para o banco de dados, além da conexão direta ao banco, ganhamos:
E além do banco, temos bônus que ajudam em outras funcionalidades que podem ser implementadas futuramente, como:
O Supabase também permitiria a tão solicitada busca de conteúdos, mas eu usaria outro serviço para isso. Analisaria a Xata, mas daí serviria não só para a busca de conteúdos, mas também como fonte de dados para a geração das páginas estáticas e para alguns dos endpoints da API.
@aprendendofelipe show, topo total testarmos o Supabase, principalmente para estarmos preparados para os server components 🤝 acabei de atualizar o título da issue 👍
- Armazenamento de arquivos (imagens);
Pelo que vi, o Storage deles pode ir além de imagens, envolvendo qualquer tipo de arquivo. Incluindo também a criação de buckets para objetos. Dessa forma, poderia "substituir" inclusive a implementação de um Amazon S3 no tabnews, estou correto?
- Armazenamento de arquivos (imagens);
Pelo que vi, o Storage deles pode ir além de imagens, envolvendo qualquer tipo de arquivo. Incluindo também a criação de buckets para objetos. Dessa forma, poderia "substituir" inclusive a implementação de um Amazon S3 no tabnews, estou correto?
Isso mesmo @marques-gabriel! Só citei o armazenamento de imagens porque é uma funcionalidade que provavelmente será implementada no TabNews 😉
Sobre armazenamento de imagens, talvez seja interessante considerar o R2 da Cloudflare que não tem egress: https://www.cloudflare.com/products/r2/
Se existir algum impedimento e realmente for necessário criar um novo banco e restaurar os dados, então que tal já aproveitar e migrar o banco para outro serviço?
O Supabase parece ser um ótimo substituto, pois oferece muitas facilidades e cobra apenas um pouco mais do que a AWS.
Apenas para fins de comparação, o Supabase seria mais adequado e conveniente do que o uso por exemplo de um Heroku Postgres, considerando o problema relatado? Visto que, acredito que o Heroku ainda exigiria um processo complexo nos casos de upgrade. Faz sentido?
@filipedeschamps, para migrar o banco para outra região (ou para outro provedor) com o mínimo de indisponibilidade, o processo é criar uma réplica somente leitura e depois promover ela.
Pra gente poder criar essa réplica, o primeiro passo é você setar no parameter_group
o rds.logical_replication
com valor 1
e reiniciar o servidor.
É para tudo continuar funcionando normalmente com essa alteração, pois só estará habilitando a possibilidade de replicação lógica.
Se quiser habilitar no banco de homologação, quando tiver feito é só avisar que eu crio uma réplica no Supabase pra testar. 👍
Falando em Supabase, já testei em modo de desenvolvimento e tudo funcionou normalmente. Também passou em todos os testes. 🎉
Logo vou fazer um teste em homologação, mesmo antes de criar a réplica, pois já dá pra gente testar algumas coisas, como os tempos de resposta. 🤝
Falando em Supabase, já testei em modo de desenvolvimento e tudo funcionou normalmente. Também passou em todos os testes. 🎉
@aprendendofelipe que notícia sensacional!!!! A plataforma do curso ta sofrendo muito com a demora para abrir uma nova conexão com o Banco. O TabNews tinha o mesmo problema, mas eu descobri que se eu criasse a instância com uma versão específica e depois fizesse o upgrade, esse problema não aparecia. Infelizmente segui a mesma estratégia no curso mas não teve jeito, e as vezes demora até 5 segundos para abrir uma conexão, muita maluquisse. Estou curioso se o Supabase resolve isso, pois se resolver, é migração de tudo na certa.
Sobre a réplica e a migração para o Supabase, você consegue detalhar melhor esse fluxo? Como que você está passando da réplica para o Supabase?
E sobre o desenvolvimento local, você seguiu os passos aqui? Achei "complicado", no sentido de que, se for isso, não fica mais transparente subir a aplicação com um simples npm run dev
. Ou tem outra forma de fazer isso?
Sobre a réplica e a migração para o Supabase, você consegue detalhar melhor esse fluxo? Como que você está passando da réplica para o Supabase?
Para criar a replicação lógica é o procedimento normal do PostgreSQL, só acrescenta aquele passo do parameter_group
por ser RDS. A única indisponibilidade será esse reset do servidor ao mudar o parameter_group
. Em homologação dá pra fazer a qualquer hora, mas em produção é bom escolher bem o momento.
Após a configuração da replicação, tudo que acontecer no RDS será replicado na outra instância (seja ela outra região da AWS ou seja qualquer instância PostgreSQL).
Daí é só aguardar a sincronização concluir, ou seja, quando a diferença dos dados entre as duas instâncias for de apenas milissegundos.
Quando chegar nessa condição é só escolher o melhor momento e mudar as variáveis de ambiente na Vercel para direcionar a gravação para o novo banco. A partir daí eles não vão mais estar sincronizados, pois as gravações no novo banco não são enviadas para o antigo (a sincronização é unidirecional).
Mas mesmo após isso, se ocorrer alguma gravação no banco antigo, ela ainda vai ser replicada para o novo. Isso não deveria acontecer, pois após o redeploy da Vercel, ninguém mais estará acessando o banco antigo, então ele já pode ser tirado do ar.
Resumidamente é isso. A configuração da replicação é bem simples. Dá pra se basear nesse tutorial da AWS:
https://aws.amazon.com/pt/premiumsupport/knowledge-center/rds-postgresql-use-logical-replication/
E sobre o desenvolvimento local, você seguiu os passos aqui? Achei "complicado", no sentido de que, se for isso, não fica mais transparente subir a aplicação com um simples
npm run dev
. Ou tem outra forma de fazer isso?
Não segui esses passos pois são para criar um novo projeto. Foi só adicionar a biblioteca e fazer alguns ajustes nos scripts e nas variáveis de ambiente. É para continuar transparente para os colaboradores.
Para criar a replicação lógica é o procedimento normal do PostgreSQL, só acrescenta aquele passo do parameter_group por ser RDS. A única indisponibilidade será esse reset do servidor ao mudar o parameter_group . Em homologação dá pra fazer a qualquer hora, mas em produção é bom escolher bem o momento.
Show, se eu não me engado, eu tinha antecipado que em algum momento precisaríamos adicionar algum parameter_group
e para evitar de precisar reiniciar o RDS por conta disso, eu já tinha colocado no Terraform:
O RDS pede para reiniciar após a adição do primeiro parameter_group
, mas os seguintes não, apesar de que acho que isso não vai valer ao adicionar o logical_replication
dado ao que o artigo que você linkou ali falou. E esse artigo esclareceu bastante coisa!
Então numa visão macro: a gente cria o Database lá na Supabase, roda as migrations nele (para ter as tabelas) e faz a replicação dos dados por SUBSCRIPTION
, correto?
Então numa visão macro: a gente cria o Database lá na Supabase, roda as migrations nele (para ter as tabelas) e faz a replicação dos dados por
SUBSCRIPTION
, correto?
Exato! E quando a sincronização estiver em "tempo real", ou seja, já tiver clonado os dados antigos e estiver recebendo as gravações mais atuais, é só direcionar o sistema para o banco novo
Massa demais!!!
E sobre localhost
, to pensando aqui: se é uma instância convencional de Postgres, a gente precisa fazer alguma alteração? Assumindo que por hora não vamos usar outros serviços da Supabase.
Já que foi bem fácil de migrar, eu achei que seria bom só porque é outra imagem do docker e é o PostgreSQL 15, então foi bom rodar todos os testes nela e ver tudo passar. Mas dá pra deixar a mudança para depois, se achar melhor.
Ah, talvez a instância do Supabase seja um pouco mais pesada que a atual. Tenho impressão que o projeto está demorando mais para abrir no Gitpod. Mas pode ser pelo tamanho da biblioteca do Supabase que não é nada pequena.
E sobre
localhost
, to pensando aqui: se é uma instância convencional de Postgres, a gente precisa fazer alguma alteração? Assumindo que por hora não vamos usar outros serviços da Supabase.
Refletindo aqui...
Então realmente é melhor o foco por enquanto ser em mudar as variáveis de ambiente na Vercel direcionando para o PostgreSQL do Supabase (primeiro homologação e depois produção) e manter o desenvolvimento local como está.
Conforme forem surgindo as necessidades podemos ir mudando apenas o que for preciso.
Show!!!
Uma curiosidade que bateu é entender qual o tamanho da instância do plano Pro e quantas conexões eles aceitam se conectando direto (ao invés da API em Rest). Você disse que eles já entregam diretamente com o PgBouncer, correto?
To no gás aqui no curso, mas em breve quero testar essa migração em homologação 🤝
Uma curiosidade que bateu é entender qual o tamanho da instância do plano Pro e quantas conexões eles aceitam se conectando direto (ao invés da API em Rest).
Respostas na tabela abaixo (disponível aqui ao expandir See Optimized Compute add-on plans).
Os valores são acréscimos em cima dos $25 do Pro. Aparentemente são os mesmos valores independentemente da região. 😉
Só agora eu notei que nem todas as instâncias do plano Pro são dedicadas. Só a partir da Large ($100 + $25 = $125). 😖
Tem que descobrir se é simples migrar a instância (deveria ser) para ir testando qual é a capacidade que precisamos. Pode ser que uma instância compartilhada seja suficiente com o nível de uso atual do TabNews. Para homologação eu testaria a gratuita mesmo.
Você disse que eles já entregam diretamente com o PgBouncer, correto?
É só habilitar o Pool em /settings/database
e usar as variáveis que aparecem nessa mesma tela (acho que só muda a porta de 5432 para 6543).
Hmm interessante. Isso agora me deixou pensando se ao invés de migrarmos para o Supabase, se deveríamos apenas adicionar o PgBouncer na nossa instância da AWS e ficar mais "raw" com essa stack. O que acha? Não sei o quão complicado é subir isso usando Terraform.
Hmm interessante. Isso agora me deixou pensando se ao invés de migrarmos para o Supabase, se deveríamos apenas adicionar o PgBouncer na nossa instância da AWS e ficar mais "raw" com essa stack. O que acha? Não sei o quão complicado é subir isso usando Terraform.
Você diz subir uma outra instância na AWS com o PgBouncer? Seriam duas novas instâncias na AWS se for colocar também em homologação, ou seja, mais ou menos dobraria o custo atual com banco de dados.
Não entendi se a intenção é fazer isso para aprender a configurar o PgBouncer do zero ou se é uma desistência do Supabase por algum motivo. Não ficou claro se você achou interessante algum ponto específico ou se foi o geral das informações sobre o Supabase.
Se for só uma desistência do Supabase, então só mexeria com o PgBouncer se for para aprender mais sobre ele, mas não compensaria manter essas novas instâncias com a demanda atual. Por outro lado, se for migrar para o Supabase, nem compensa mexer com isso na AWS.
No Supabase é só clicar no toggle da imagem abaixo para habilitar o PgBouncer na frente do Postgres, e não tem acréscimo no custo. Com o PgBouncer habilitado o sistema pode continuar se conectando diretamente com o banco (o que não faz sentido, mas funciona) ou é só trocar a porta nas variáveis de ambiente da Vercel e passar a se conectar ao banco através do Pool.
E não podemos esquecer que no Supabase tem a possibilidade de se conectar ao banco via REST, o que não tem relação com o PgBouncer. Provavelmente só daria pra fazer isso na AWS se subir um servidor que se mantenha conectado ao banco e exponha a API.
Este deploy em homologação está utilizando um banco do Supabase na versão gratuita:
https://tabnews-25tw3pmpu-tabnews.vercel.app/
Não fiz a migração dos dados do banco original de homologação, então vai ser preciso criar um novo usuário dependendo do teste que quiserem fazer.
E tenham em mente que esse banco pode ser apagado a qualquer momento. 😉
Ainda sobre o Supabase...
Rodei os testes com o ambiente de desenvolvimento conectado remotamente a uma instância gratuita do Supabase e só tive que ignorar os dois testes que fazem 100 requisições simultâneas, pois alcançavam o timeout de 60 segundos.
Os demais testes passaram, só que levou mais de 30 minutos para rodar todos 😅
O banco do Supabase está na mesma região que as lambdas da Vercel (sa-east-1), então está com uma latência bem menor:
AWS | Supabase |
---|---|
Apesar da latência estar mais baixa, o processamento demora um pouco mais, pois o Supabase está em uma instância compartilhada.
Então uma coisa anula a outra e, no geral, as respostas das requisições estão mais ou menos no mesmo patamar.
Você diz subir uma outra instância na AWS com o PgBouncer? Seriam duas novas instâncias na AWS se for colocar também em homologação, ou seja, mais ou menos dobraria o custo atual com banco de dados.
Não entendi sobre dobrar o custo com banco de dados, a idéia era manter o banco (na verdade reduzir o tamanho do de Produção) e colocar na frente o PgBouncer. Mas fui pesquisar aqui e não é tão simples colocar ele. Na verdade não é complicado, mas nem se compara com a facilidade do Supabase 😂
Não entendi se a intenção é fazer isso para aprender a configurar o PgBouncer do zero ou se é uma desistência do Supabase por algum motivo. Não ficou claro se você achou interessante algum ponto específico ou se foi o geral das informações sobre o Supabase.
As vezes eu endoido e tento projetar o que vai acontecer com uma empresa e eu vejo a AWS existindo por muito mais tempo que o Supabase, mas é besteira pensar assim e mesmo que o Supabase deixe de existir (ou seja adquirido), migrar tudo de novo é fácil 🤝
No Supabase é só clicar no toggle da imagem abaixo para habilitar o PgBouncer na frente do Postgres, e não tem acréscimo no custo. Com o PgBouncer habilitado o sistema pode continuar se conectando diretamente com o banco (o que não faz sentido, mas funciona) ou é só trocar a porta nas variáveis de ambiente da Vercel e passar a se conectar ao banco através do Pool.
Perfeito! Só uma pena que não tem um Terraform Provider pra deixar essa parte da infra versionada, mas pelo menos é tudo muito mais simples que AWS 🤝
E não podemos esquecer que no Supabase tem a possibilidade de se conectar ao banco via REST, o que não tem relação com o PgBouncer. Provavelmente só daria pra fazer isso na AWS se subir um servidor que se mantenha conectado ao banco e exponha a API.
Total!! E esse é o tipo de feature que seria muito ruim fazer na mão (fora ser inseguro), e que faz essa instância ser acessível pela Edge 😍 To muito curioso para saber a performance de uma request por essa API.
Rodei os testes com o ambiente de desenvolvimento conectado remotamente a uma instância gratuita do Supabase e só tive que ignorar os dois testes que fazem 100 requisições simultâneas, pois alcançavam o timeout de 60 segundos.
Os demais testes passaram, só que levou mais de 30 minutos para rodar todos 😅
Puts que massaaaa!! Isso é uma ótima notícia!
Essa instância de homologação está com o PgBouncer ligado? Se sim, infelizmente ele não ajudou na velocidade da primeira conexão, olha só :(
O banco do Supabase está na mesma região que as lambdas da Vercel (sa-east-1), então está com uma latência bem menor:
AWS Supabase Apesar da latência estar mais baixa, o processamento demora um pouco mais, pois o Supabase está em uma instância compartilhada.
Então uma coisa anula a outra e, no geral, as respostas das requisições estão mais ou menos no mesmo patamar.
A imagem da coluna AWS
é do nosso atual homologação? Se sim, daí não dá para comparar, pois esse banco está em us-east-1
. Então se colocar na mesma região vai ficar igual (1-2ms
após a conexão aberta).
Puts.. nosso maior vilão é o tempo de abertura inicial da conexão. Fico no aguardo de você responder se a instância de homologação lá em cima está com o PgBouncer ligado, e se estiver, se temos alguma outra manobra para melhorar o tempo inicial de conexão 🤝
Lendo o config do PgBouncer encontrei essa opção:
min_pool_size Add more server connections to pool if below this number. Improves behavior when the normal load suddently comes back after a period of total inactivity. The value is effectively capped at the pool size.
Default: 0 (disabled)
Que por padrão vem desabilitado. Seria interessante sempre manter conexões quentes com o banco. Tem como colocar essa config no Supabase?
Não entendi sobre dobrar o custo com banco de dados, a idéia era manter o banco (na verdade reduzir o tamanho do de Produção) e colocar na frente o PgBouncer.
O PgBouncer não é uma extensão que pode ser instalada no Postgres. É um servidor adicional. Precisa subir uma nova instância (EC2 ou contêiner) que vai atuar como se fosse um servidor PostgreSQL, mas que só lida com as conexões e se conecta no banco verdadeiro para fazer as consultas. Por isso dobra o número de instâncias.
As vezes eu endoido e tento projetar o que vai acontecer com uma empresa e eu vejo a AWS existindo por muito mais tempo que o Supabase, mas é besteira pensar assim e mesmo que o Supabase deixe de existir (ou seja adquirido), migrar tudo de novo é fácil 🤝
Só uma pena que não tem um Terraform Provider pra deixar essa parte da infra versionada, mas pelo menos é tudo muito mais simples que AWS 🤝
O Supabase pode ser auto-hospedado, então talvez seja boa ideia manter o versionamento do que seria necessário para auto-hospedar. Pode ser útil caso surjam problemas com a empresa Supabase, mas de qualquer modo servirá como registro histórico.
E esse é o tipo de feature que seria muito ruim fazer na mão (fora ser inseguro), e que faz essa instância ser acessível pela Edge 😍 To muito curioso para saber a performance de uma request por essa API.
Praticamente só muda que não ocorre a demora da primeira requisição de uma lambda que precisa estabelecer conexão com o banco, pois as requisições são feitas via REST para uma instância quente do Supabase que mantém a conexão sempre aberta com o banco. Fora isso, tem uma instância a mais no caminho da consulta, então é para demorar um pouco mais, mas o acréscimo de tempo deve ser insignificante.
Essa instância de homologação está com o PgBouncer ligado?
Está sim com PgBouncer, por isso está mostrando 57 conexões disponíveis. Teria um número bem menor se não tivesse, acho que seriam menos de 20 conexões diretas disponíveis nessa instância básica e compartilhada.
Se sim, infelizmente ele não ajudou na velocidade da primeira conexão, olha só :(
Mas o PgBouncer realmente não ajuda nada com isso. Para se conectar nele é o mesmo processo de se conectar diretamente ao banco.
O que ele ajuda é aumentando o número de conexões disponíveis. Em situações de alta demanda, mais lambdas serão necessárias e terão mais conexões disponíveis no Pool. Com isso evitamos que as lambdas fique se desconectando para liberar a conexão para outras lambdas, e só nesse caso vai ser economizando o tempo que leva para estabelecer novas conexões. Quem vai estar gerenciando o revezamento de conexões será o PgBouncer, mas sem precisar estabelecer novas conexões entre a lambda e o Pool e nem entre o Pool e o PostgreSQL.
Mas quando não tem demanda e as lambdas congelam, não tem jeito, ao subirem novamente elas precisam abrir novas conexões, seja diretamente com o banco ou com o PgBouncer, e isso sempre vai demorar um pouco mais.
A imagem da coluna
AWS
é do nosso atual homologação? Se sim, daí não dá para comparar, pois esse banco está emus-east-1
. Então se colocar na mesma região vai ficar igual (1-2ms
após a conexão aberta).
Isso, estou testando e comparando só homologação. E, sim, colocar o banco de homologação em us-east-1
deixaria a latência igual à do banco atual de produção, ou seja, iria melhorar a performance, mas essa possibilidade não faz sentido no contexto dessa issue, pois estaria aumentando os custos ao invés de diminuir.
A comparação foi da situação atual (AWS em sa-east-1
) para uma situação possível (Supabase em us-east-1
), mostrando que ela é aceitável, pois reduz o custo sem causar prejuízo significante para a performance em homologação.
O PgBouncer do Supabase também vem com min_pool_size=0
, mas não precisa habilitar isso para que as conexões entre o Pool e o Postgres permaneçam quentes. Acho que mudar esse parâmetro só teria efeito prático quando o servidor PgBouncer subir na primeira vez, pois aí ele já abriria essas X conexões com o Postgres, mesmo sem clientes conectados. Mas não muda nada entre as conexões das lambdas para o PgBouncer.
Para nunca ter o problema de demora com a primeira ~conexão~ consulta com o banco de dados a alternativa é a API REST ou GraphQL e não o PgBouncer.
Uma pequena atualização ao issue, o preço das instâncias no Supabase mudou, e a quantidade de conexões também:
Hoje existe o Vercel Postgres, em parceria com a Neon.
Será que faz sentido dar uma olhada e talvez aproveitar a parceria com a Vercel (quanto ao Pricing)?
Contexto
Hoje nosso banco de dados está hospedado na AWS e sendo servido pelo RDS, onde a instância de Produção está em SP (
sa-east-1
) conforme visto no arquivo do Terraform:https://github.com/filipedeschamps/tabnews.com.br/blob/0bbb0f655dc88847fa741001a83d3f3297bf01a1/infra/provisioning/production/main.tf#L18-L21
Porém como temos mais camadas em cima da API, por exemplo Cloudflare, não sei se valeu a pena esta escolha, pois está muito caro. O fato de movermos para o
us-east-1
vai trazer um pouco mais de latência, mas nada que irá atrapalhar os serviços.Execução
Não faço a mínima idéia de como fazer isso com pouco trabalho.
E infelizmente, eu coloquei o
state
do Terraform no mesmo arquivo e agora isto também está grudado emsa-east-1
:https://github.com/filipedeschamps/tabnews.com.br/blob/0bbb0f655dc88847fa741001a83d3f3297bf01a1/infra/provisioning/production/main.tf#L9-L15
O que eu estava cogitando era:
state
zerado), mas apontando tudo paraus-east-1
. Levantar a VPC, Banco, tudo lá.sa-east-1
.us-east-1
.us-east-1
.Dúvidas