2 pontos por GN⁺ 2024-01-19 | 1 comentários | Compartilhar no WhatsApp
  • O GOV.UK Notify reduziu o downtime para cerca de 11 segundos ao migrar um banco de dados PostgreSQL 11 de 400 GB para o PostgreSQL 15 no RDS, em sua própria conta AWS, em razão do encerramento do PaaS
  • No banco de destino, foram criadas primeiro apenas as tabelas; os dados foram copiados com DMS full load e os índices e restrições de chave foram aplicados depois, reduzindo o tempo de carga em larga escala
  • O banco de origem tinha cerca de 1,3 bilhão de linhas, 85 tabelas, 185 índices e 120 chaves estrangeiras; em dias úteis, recebia cerca de 1.000 inserções/atualizações por segundo e um volume semelhante de leituras
  • Por causa da restrição de que uma nova implantação da aplicação levava cerca de 5 minutos, a equipe preparou antecipadamente as mesmas credenciais e uma troca por pesos no DNS do Route53 para reduzir o tempo real de transição
  • O DMS foi escolhido por ser fácil de obter suporte do PaaS e da AWS, mas fica a possibilidade de que alternativas como pglogical fossem mais simples para migrações entre PostgreSQL

Migração do banco de dados do Notify em razão do encerramento do PaaS

  • O GOV.UK Notify estava hospedado no GOV.UK Platform as a Service e, com o encerramento do PaaS, precisou mover toda a infraestrutura para sua própria conta AWS
  • O banco de dados do Notify era um AWS RDS PostgreSQL na conta AWS do PaaS e armazenava desde dados de envio de notificações até o conteúdo de centenas de milhares de modelos usados pelas equipes de serviço
  • Na migração, o banco de dados existente foi tratado como source database, e o novo banco como target database
  • O principal desafio não era criar um novo banco PostgreSQL, mas minimizar o downtime durante a migração de todos os dados e a troca do destino de conexão da aplicação

Escala do banco de dados de origem e restrições do serviço

  • O banco de dados de origem era um PostgreSQL 11 de cerca de 400 GB
    • Cerca de 1,3 bilhão de linhas
    • 85 tabelas
    • 185 índices
    • 120 chaves estrangeiras
  • Em um dia útil típico, ocorriam cerca de 1.000 inserções ou atualizações por segundo, além de um número semelhante de leituras
  • O GOV.UK Notify envia diariamente milhões de notificações importantes e sensíveis ao tempo, como alertas de enchente e atualizações sobre o andamento de solicitações de passaporte
  • Como todo envio de notificação exige acesso ao banco de dados, era necessário manter o tempo de indisponibilidade do serviço curto

Estrutura de carga inicial e replicação contínua criada com DMS

  • A equipe do PaaS ofereceu uma abordagem de migração de banco de dados usando o AWS Database Migration Service
  • O DMS é responsável por mover dados do banco de dados de origem para o banco de dados de destino e pode ser executado na conta AWS de origem ou de destino
  • A tarefa do DMS é dividida em duas etapas
    • full load: copia, tabela por tabela, todos os dados existentes até um determinado momento
    • replicação contínua: reproduz no banco de destino as novas transações do banco de origem para manter os dois bancos sincronizados
  • A equipe do Notify ficou responsável por trocar a aplicação para usar o banco de destino em vez do banco de origem

Preparação do banco de destino e full load

  • A instância do DMS foi criada na conta AWS de origem
    • Como a equipe do PaaS já havia configurado uma instância do DMS dentro da conta, foi possível preparar tudo rapidamente
    • A instância do DMS precisava de credenciais para se conectar aos bancos PostgreSQL de origem e de destino
  • Como a instância do DMS e o banco de dados de destino estavam em VPCs diferentes, foi configurado VPC peering para que o tráfego do DMS na VPC do PaaS fosse roteado para a VPC própria sem passar pela internet pública
  • A instância RDS de destino foi criada na própria conta AWS e, como o fim do suporte ao PostgreSQL 11 estava se aproximando, o novo banco foi configurado com PostgreSQL 15
  • O esquema do banco de dados de origem foi exportado com pg_dump para criar um arquivo SQL de recriação do esquema; inicialmente, apenas as declarações de tabela foram aplicadas ao banco de destino
  • As chaves estrangeiras não foram aplicadas no momento do full load
    • Isso porque o DMS full load não copia os dados respeitando a ordem das restrições de chave estrangeira
  • As chaves primárias e os índices também não foram criados antes do full load
    • Cada inserção exigiria atualização de índices, o que poderia aumentar muito o tempo total ao inserir bilhões de linhas
    • Era mais rápido copiar todos os dados primeiro e adicionar os índices depois
  • A tarefa de full load copiou os dados existentes no momento em que o botão de início foi pressionado
    • Novos dados ou atualizações ocorridos depois disso não foram incluídos no full load
    • A conclusão do full load levou cerca de 6 horas
  • Após o full load, o restante do arquivo de esquema foi aplicado para adicionar índices e restrições de chave, e essa etapa levou cerca de 3 horas

Manutenção da replicação por 10 dias e troca de tráfego

  • Depois do full load, o banco de dados de destino correspondia aos dados do banco de origem no momento de início do full load, mas inserções, atualizações e exclusões continuaram ocorrendo no banco de origem depois disso
  • A replicação contínua do DMS, ou seja, a tarefa de change data capture, foi iniciada para enviar ao banco de destino as transações do transaction log do banco de origem ocorridas após o início do full load
  • O processo de replicação levou algumas horas para alcançar o ritmo, e depois a latência de replicação do DMS foi monitorada para confirmar o estado de sincronização
  • A replicação do DMS rodou em segundo plano por cerca de 10 dias, mantendo os dois bancos sincronizados até o momento de migração de tráfego previamente comunicado aos usuários
  • O procedimento de troca de tráfego foi escrito antecipadamente como scripts em Python
    • Interromper o tráfego da aplicação para o banco de dados de origem
    • Confirmar que a replicação havia alcançado completamente a origem
    • Permitir que a aplicação se conectasse ao banco de dados de destino
  • Era preciso evitar um estado em que algumas aplicações usassem o banco de origem e outras o banco de destino
    • Como mudanças feitas no banco de destino não seriam refletidas no banco de origem, os usuários poderiam ver dados inconsistentes
  • Os scripts foram criados para serem mais explícitos, repetíveis e rápidos do que operações manuais, e foram usados pelo menos 40 vezes em testes e ensaios prévios
  • A meta de downtime era menos de 5 minutos, e a migração foi agendada para um sábado à noite relativamente tranquilo, evitando o meio da madrugada

Troca de DNS que gerou downtime de 11 segundos

  • A interrupção do tráfego para o banco de dados de origem foi feita chamando pg_terminate_backend nas conexões da aplicação, e levou menos de 1 segundo
  • A senha do usuário PostgreSQL também foi alterada para impedir que a aplicação se reconectasse ao banco de origem, causando erro de autenticação em novas tentativas de conexão
  • O DMS criou uma tabela de estado de replicação no banco de destino e a atualizava a cada minuto; o script de migração usava essa tabela para verificar o atraso entre origem e destino
  • Como salvaguarda adicional, depois que a aplicação parava de acessar o banco de origem, o script gravava um único registro no banco de origem e esperava até que ele chegasse ao banco de destino
  • As informações de conexão da aplicação ao banco de dados eram fornecidas pela variável de ambiente SQLALCHEMY_DATABASE_URI
    • O formato existente era postgresql://...@random-identifier.eu-west-1.rds.amazonaws.com:5432, incluindo nome de usuário, senha e localização do RDS
    • Para alterar a localização do banco de dados ou as credenciais, era necessário reimplantar a aplicação, e a reimplantação levava cerca de 5 minutos
  • Para evitar downtime adicional causado pela reimplantação, duas medidas foram preparadas antes da migração
    • Criar usuários com o mesmo nome de usuário e senha nos bancos de dados de origem e de destino
    • Criar um registro DNS database.notifications.service.gov.uk no AWS Route53 e definir o TTL como 1 segundo
  • Inicialmente, o registro DNS foi configurado com peso de 100% para a origem e 0% para o destino
  • A URI da aplicação foi alterada antecipadamente para usar o nome de usuário, a senha e o novo nome de domínio comuns
  • No momento da troca real, o script alterou os pesos de DNS da AWS para 100% no destino e esperou o TTL de 1 segundo expirar
  • No momento da troca, na noite de sábado, 4 de novembro de 2023, o atraso entre o banco de destino e o banco de origem era de apenas alguns segundos
  • Como resultado da execução do script de migração, a aplicação deixou de acessar o banco de origem e passou a usar o novo banco de destino, com downtime de cerca de 11 segundos

Avaliação da escolha do DMS e próximos passos

  • O DMS foi escolhido porque tinha bom suporte no GOV.UK PaaS e também permitia obter suporte da AWS
  • Caso façam novamente uma migração entre bancos PostgreSQL no futuro, a equipe pretende avaliar melhor ferramentas alternativas como pglogical
  • É possível que o DMS tenha adicionado mais complexidade e um processo de replicação menos familiar do que outras ferramentas
  • Após a migração do banco de dados, a próxima etapa é a migração da aplicação
  • A aplicação GOV.UK Notify será movida para o AWS Elastic Container Service, e o andamento do processo será compartilhado posteriormente

1 comentários

 
GN⁺ 2024-01-19
Opiniões do Hacker News
  • Também fizemos uma migração parecida com AWS RDS Blue-Green Deployments; o banco de dados era um pouco maior, mas o downtime foi de cerca de 20 segundos e o trabalho envolvido foi bem menor. Acho surpreendente que isso ainda não tenha sido mencionado nesta thread
    Basicamente, você sobe uma nova implantação Blue/Green com as alterações desejadas, e enquanto a configuração blue existente continua atendendo ao tráfego, a AWS sincroniza a implantação green usando replicação lógica
    No green, desde que você não faça escritas, é possível modificar, testar e até fazer teste de carga; as escritas continuam indo para o blue em produção e depois são replicadas para o green
    Quando estiver pronto, você executa o comando de switch, e a AWS cuida de verificar a sincronização, interromper escritas e conexões, esperar a replicação alcançar, renomear os bancos de dados e retomar conexões e escritas
    No nosso caso, o downtime foi menor que 20 segundos, e toda a configuração, incluindo o primary e várias réplicas de leitura, foi alternada sem problemas. A AWS também troca a URL do banco de dados, então não foi necessário mudar a configuração; o green vira o blue, o blue antigo vira old blue, e você pode apagá-lo depois
    Recomendo muito, mas há limitações, como talvez não funcionar em casos de migração entre contas: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-...

    • +1 para Blue/Green. Mas, neste caso, acho que não dava para usar por causa da migração entre contas. Já usei tanto com MySQL quanto com Postgres; no MySQL, o número de consultas por segundo era duas ordens de grandeza maior que o do artigo, e ambos foram tranquilos
      É preciso ler e reler a documentação, especialmente as limitações. Vale a pena executar testes com carga no ambiente de desenvolvimento e repetir também em staging
      Ou simplesmente mandar para produção no modo YOLO e talvez tudo fique bem
    • Usei implantações RDS Blue/Green para fazer um upgrade de versão principal do engine do MySQL 5.7 para 8.0, e do ponto de vista de downtime foi excelente. Acho que o downtime observado na API foi de cerca de 13 segundos
      Mas aprendi do jeito difícil que o RDS Blue/Green não serve para qualquer alteração arbitrária. No nosso caso, descobrimos que dava para usá-lo apenas para subir a versão do engine, não para descer
      No MySQL 8.0, uma stored procedure falhava muito de vez em quando, então avaliamos a opção de voltar para o 5.7, mas isso não era possível
    • Fico curioso se alguém já criptografou armazenamento RDS que originalmente não era criptografado usando Blue/Green
    • Fico curioso sobre como vocês pararam e reiniciaram as aplicações que acessam o banco de dados. Temos vários tasks rodando no ECS, e elas podem levar 1 minuto para desligar e alguns minutos para subir de novo
    • +1 para Route53 Groups e uma configuração Blue/Green. Fizemos algo parecido em um upgrade do PostgreSQL e, com AWS R53 groups e um patch próprio em transações do Rails ActiveRecord para repetir consultas em andamento, conseguimos fazer sem downtime
      O trade-off foi que algumas requisições ficaram mais lentas por alguns segundos
      A combinação de DNS Groups com retry é um mecanismo bem útil para esse tipo de operação
      Ferramenta usada: https://github.com/shayonj/pg_easy_replicate
  • Há várias formas de “pausar” consultas Postgres de entrada; por exemplo, usando pgbouncer para atrasá-las, em vez de fazê-las falhar, até que a replicação alcance, e então continuar no novo banco de dados
    Se algo der errado e a replicação não conseguir alcançar, é só desfazer a pausa e deixar essas consultas executarem no banco de dados antigo
    Isso transforma 11 segundos de downtime em 0 a 11 segundos de tempo adicional de carregamento de página. Mais importante: entre milhares de usuários do banco de dados que nunca viram uma consulta falhar, se houver caminhos de tratamento de erro com bugs ou jobs em lote inteiros que quebram por causa de uma única consulta com falha, o dano colateral fica muito menor

    • Pode até ser possível pausar as consultas, mas fico curioso se também dá para pausar transações já em andamento. Como isso funcionaria?
  • É interessante comparar com https://knock.app/blog/zero-downtime-postgres-upgrades. A discussão relacionada aconteceu em https://news.ycombinator.com/item?id=38616181
    Grande parte da discussão na época acabava em “não é complexo demais só para evitar alguns minutos de downtime?”. Este caso parece uma prova disso, e dá a impressão de que basta usar o AWS Data Migration Service, trocar o registro DNS para passar para produção e aceitar 11 segundos de downtime

    • Não há um “basta” aqui. A principal lição está em “o que aprendemos”

      Escolhemos o DMS porque ele era bem suportado no GOV.UK PaaS e também podíamos obter suporte da AWS. No futuro, se migrarmos um banco de dados de PostgreSQL para PostgreSQL, vamos dedicar mais tempo a avaliar ferramentas alternativas como o pglogical. O DMS pode ter acrescentado mais complexidade e um processo de replicação menos familiar do que teríamos enfrentado com outras ferramentas. Isso também está alinhado com o que a AWS diz diretamente sobre migrações entre PostgreSQL
      A mensagem aqui não é “simplesmente use DMS”

    • Fico curioso se alguém já fez algo parecido com https://cloud.google.com/database-migration/docs/postgres/qu.... Funciona de forma parecida com o AWS DMS?
    • O DMS parece usar pglogical internamente, mas tem muitas armadilhas. Como não é replicação em nível de hardware, pode dar problema com linhas grandes, colunas grandes e tabelas grandes, e também não lida corretamente com chaves estrangeiras
      Alguns tipos de dados especiais talvez nem sejam tratados. Depois da migração, também é preciso atualizar as sequências; caso contrário, podem ocorrer erros de chave primária duplicada
      Se não houver uma chave primária adequada, também podem surgir problemas porque ele nem sempre copia a linha inteira de uma vez
      Se os bancos de dados estiverem na mesma conta AWS e você puder aceitar 4 a 5 minutos de downtime, é bem provável que uma replicação em nível de hardware usando banco de dados global ou snapshots seja mais fácil
  • Recentemente migrei um banco de dados PostgreSQL de 3 TB auto-hospedado da versão 12 para a 16, e também troquei do Ubuntu 18 para o Ubuntu 22. Ao mesmo tempo, precisei atualizar várias extensões, especialmente o Timescale, para o qual não havia uma versão compatível que satisfizesse todas as combinações
    Fizemos isso atualizando uma réplica somente leitura: começamos com PG12, Ubuntu 18 e TS2.9, e primeiro criamos uma réplica somente leitura no Ubuntu 22 mantendo PG12 e TS2.9
    Depois entramos em modo de manutenção, paramos todos os serviços, destacamos a réplica somente leitura e então, no Ubuntu 22, atualizamos o PG12 para PG15 mantendo o TS2.9
    Em seguida, atualizamos de TS2.9 para TS2.13 com PG15, e por fim atualizamos de PG15 para PG16 no Ubuntu 22 mantendo o TS2.13
    Por último, reconectamos os serviços ao novo servidor de banco de dados, retomamos todos os serviços e saímos do modo de manutenção
    Todas as etapas de upgrade do banco de dados foram bem testadas e automatizadas com Ansible, mas surgiu um problema que não apareceu nos testes, aumentando o downtime para cerca de 30 minutos. Para o nosso uso, foi perfeitamente aceitável
    Se tivéssemos usado replicação lógica, talvez pudéssemos ter reduzido os problemas inesperados no último momento, e pretendemos avaliar essa abordagem no próximo ciclo de upgrade

    • Nós também seguimos quase o mesmo caminho de upgrade recentemente. Só que, na época, o Timescale ainda não dava suporte ao PG16, então paramos em PG15 + TS 2.12
      Também avaliamos replicação lógica para reduzir o downtime do upgrade, mas, como o schema do banco de dados e comandos DDL não são replicados, pareceu não ser recomendável quando o Timescale está envolvido
      As mudanças de schema subjacentes que o Timescale precisa fazer internamente provavelmente são, em grande parte, uma função do tamanho dos chunks das hypertables e do padrão de escritas recebidas, então talvez fosse possível planejar ou sincronizar isso, mas achamos que a complexidade e o risco potenciais eram grandes demais em comparação com abrir uma janela curta de manutenção enquanto o pg_upgrade terminava
  • O inimigo dessas migrações com baixo downtime ou sem downtime são as consultas de longa duração
    Por exemplo, se houver uma única consulta update que leva 30 minutos, você precisa matar essa consulta e fazer rollback, ou aceitar 30 minutos de perda de disponibilidade
    Até onde sei, não há como migrar consultas em andamento

    • Em um projeto de engenharia de software, é melhor limitar o tempo das transações a algo muito menor que isso. A configuração statement_timeout é sua amiga
      Se houver transações extremamente longas, é bem provável que você consiga fazer a troca evitando o período em que elas rodam. Espero que sejam resultado de algo como jobs agendados, e não ocorrências aleatórias
      Combinando limites de tempo de transação, configuração de failover — por exemplo, forçando a falha do primary antigo — e algo como pgbouncer, dá para controlar com bastante precisão o período de lentidão em vez de downtime
      Sinceramente, o que me preocupa mais é se toda a stack e os servidores DNS de cache externos dos quais ela depende respeitam corretamente o TTL do DNS
      Mas, em geral, evitar uns 10 segundos de downtime em uma aplicação não é crítico, então faz sentido escolher a solução que for mais simples para você
    • Pessoalmente, tenho dificuldade em imaginar um caso em que uma consulta update de 30 minutos não tenha sido escrita de forma extremamente ineficiente ou não seja uma migração pontual de dados em grande escala
      Claro que o primeiro caso existe bastante no mundo real. Já me diverti bastante transformando tarefas de minutos ou horas em tarefas de milissegundos
    • Aprendi algo novo. Fico curioso sobre a natureza de escritas que levam mais de 30 minutos
      Que tipo de dados e que tipo de pessoas lidam com essas escritas de banco de dados a ponto de dependerem do motor do banco de dados trabalhando por tanto tempo, em vez de quebrar melhor isso em uma fila na camada superior?
  • A parte estranha é que eles criaram um registro DNS no AWS Route53 para database.notifications.service.gov.uk com TTL de 1 segundo e, depois que o script de migração alterou o peso do DNS da AWS para enviar 100% ao local do banco de dados de destino, esperaram 1 segundo até o TTL expirar.
    Eles disseram que, assim, na próxima vez que a aplicação tentasse consultar o banco de dados, ela consultaria o banco de destino. Isso quer dizer que o ORM deles ou o comportamento padrão do Python faz uma consulta DNS a cada query e fica bloqueado nisso?
    Quer dizer que eles nem cacheiam o endereço resolvido por algum tempo, nem usam pooling ou reutilização de conexões?

    • Provavelmente quem faz esse comportamento é o getaddrinfo ou gethostname do SO. O Python praticamente não reimplementa chamadas de nível de sistema, então depende da configuração do sistema.
      Se o TTL de 1 segundo foi respeitado, teria ficado em cache por 1 segundo, mas não é raro que bibliotecas de resolução DNS — e especialmente servidores DNS com cache — não respeitem totalmente o TTL. Sinceramente, isso também poderia explicar parte do downtime observado.
  • Legal. Acabamos de migrar no RDS três clusters Postgres com cerca de 2 TB de dados e 8 bancos de dados, de Postgres 14 para 16. Ficamos fora do ar das 00:00 às 04:00.
    Primeiro ativamos um “modo de manutenção”, que era um site substituto bem leve rodando no Cloudflare Workers, e reduzimos para 0 via Terraform todas as aplicações que escrevem no DB.
    Na interface web da AWS, clicamos no botão de upgrade para fazer 14→15 com pg_upgrade e esperamos terminar; depois clicamos de novo para fazer 15→16.
    Esperamos até o banco de dados começar a aceitar conexões; parecia que ele aceitava conexões mesmo antes de aparecer como ready, e a AWS parecia fazer algo além do pg_upgrade.
    Depois iniciamos VACUUM ANALYZE; REINDEX DATABASE CONCURRENTLY. A intenção era evitar problemas de performance entre versões e aproveitar as melhorias de performance da nova versão.
    Começamos a subir as aplicações de novo e, depois de esperar que todas tivessem alguns contêineres rodando, passamos a receber tráfego, desligamos o site de manutenção e fomos dormir.
    O REINDEX CONCURRENTLY continuou rodando por mais 18 horas no maior DB, mas não bloqueou nada.
    Na próxima vez, pretendemos usar AWS Blue/Green deployments para evitar downtime. Desta vez não pudemos usar, porque não estávamos na versão menor mínima do 14 compatível com Blue/Green, que é a 14.9.
    Se eu fosse fazer por conta própria, sem pagar o custo da AWS, montaria meu próprio Blue/Green com replicação lógica e um balanceador de carga.

    • Eu usaria pg_upgrade --hardlinks para um upgrade in-place.
      Em instâncias Postgres próprias on-premises, já fiz isso com DB de 2 TB em menos de 1 minuto.
  • O GOV.UK Notify faz parte de um conjunto de serviços que o GDS oferece a órgãos públicos do Reino Unido. GOV.UK Pay e GOV.UK PaaS também fazem parte, e originalmente isso era conhecido como Government As A Platform.

  • DMS é uma ferramenta de migração péssima. Depois de quase um mês brigando com vários problemas de migração, desistimos.
    Ele não conseguia migrar tipos text e json, e o suporte da AWS também não conseguiu apresentar uma solução.
    Usamos o AWS Blue/Green na fase inicial de testes, e graças a isso um upgrade praticamente sem downtime se tornou viável.

    • Se você acha que o DMS é uma ferramenta de migração ruim, experimente usá-lo para replicação contínua para um destino externo.
      Está completamente quebrado.
  • É interessante, mas não entendo por que o governo usa AWS para começo de conversa. Não é uma startup hackeando para encontrar product-market fit, nem uma situação em que não previram um pico de tráfego impulsionado por marketing e precisam reagir
    Eles sabem que esse serviço será necessário no longo prazo, e os padrões de uso também são bastante previsíveis
    Poderiam criar uma nuvem para o setor público ou adotar uma abordagem on-premises razoável. Isso exigiria verba, coordenação e liderança técnica, mas no longo prazo economizaria uma quantia enorme para os contribuintes
    A TI do setor público em geral é uma bagunça, mas sei que também há bons engenheiros trabalhando nela

    • Como startup, o motivo para usar “nuvem”, ou seja, PaaS, não é dar conta de picos de tráfego, mas foco
      Uma hora correndo atrás de discos rígidos e drivers, ou das versões disso na nuvem, como storage e Ansible, é uma hora que deixa de ser usada para construir o que os clientes precisam
      Por que seria diferente para o governo?
      Ninguém espera que o governo fabrique seus próprios carros; espera-se que compre da Volkswagen ou da Renault. Mesmo que o governo claramente tenha necessidades de transporte. Então não entendo por que insistem que a infraestrutura de TI seja feita internamente
    • Se você acha que as necessidades e a demanda do governo são previsíveis, então não tem acompanhado a política, especialmente a política britânica dos últimos 10 anos
      E também há coisas que surgem de forma totalmente inesperada, como a pandemia. O fato de ter sido possível escalar para atender à demanda durante a pandemia foi uma das principais demonstrações de por que o setor público deve usar nuvens públicas comerciais
    • O governo britânico como um todo opera uma combinação das principais nuvens públicas com algum on-premises e colocation
      Recomendo assistir à apresentação de setembro sobre várias iterações do Gov.UK e migrações entre nuvens: https://youtube.com/watch?v=mpY1lxkikqM&pp=ygUOUmljaGFyZCB0b...
      Pelo menos no governo britânico, por causa dos requisitos de compras, é preciso recolocar no mercado, a cada poucos anos, uma cotação baseada no uso
      Por exemplo, se a Oracle Cloud custar um décimo do preço, ela provavelmente vai ganhar o contrato; então será necessário migrar para a Oracle durante a vigência do contrato e, se depois aparecer outra nuvem mais barata, talvez seja preciso migrar de novo
    • Muitos países da UE devem ter criado nuvens públicas. Na Croácia, passei por isso diretamente e fui um dos desenvolvedores que precisou fazer deploy nela
      Foi uma das piores coisas que já vi na vida. E olha que já trabalhei bastante com legados em VB.NET, Web Forms, SharePoint antigo, Basic e até aplicações inteiras que eram um enorme monte de stored procedures
      AWS, Azure e Google Cloud pelo menos foram feitas pensando no usuário final, isto é, o desenvolvedor. Já a nuvem governamental foi projetada e construída pelo licitante de menor preço, cujo objetivo principal era cortar custos em todos os lugares possíveis
    • Não sei como é no Reino Unido, mas nos EUA a AWS oferece o GovCloud há muito tempo e, sinceramente, comparado a muita infraestrutura que já vi, ele é quase uma bênção
      Por outro lado, também já conheci profissionais de infraestrutura e operações realmente excelentes que operavam datacenters internos de instituições de saúde do governo alemão. O problema ali não era a tecnologia nem as pessoas, mas 100% a gestão e os processos, que tentavam virar gargalo em toda interação entre a equipe de infraestrutura e a equipe de engenharia