Definindo uma arquitetura focada em disponibilidade de dados

Uma arquitetura distribuída, altamente disponível e com foco na disponibilidade dos dados.

Vou utilizar a GCP (Google Cloud Platform) para essa proposta de arquitetura, mas poderia ser outro provider (desde que, obviamente, os componentes preservem as características dos que elenquei nessa proposta.

É fácil afirmar que, nenhuma arquitetura é 100% disponível, mesmo quando falamos em multi-cloud. Afinal, fatores externos podem gerar indisponibilidade e não temos como controlá-los, mas temos como minimizar as chances para termos problemas e gerar uma maior garantia de prevenção a falhas.

O modelo que vou apresentar, não é um modelo de missão crítica, nem deve ser considerado. Afinal, nem mesmo os providers como GCP, Azure ou AWS, garantem isso. 

Certo! vamos às armas oO'

Vou listar algumas ferramentas que vou utilizar nessa proposta, mas poderia ser outra, desde que tenha a proposta semelhante.

- Aplicações (cloud run, cloud function, kubernetes apps).
- Pub/Sub messaging - com disponibilidade GLOBAL - super importante.
- Bancos de dados (postgresql, mongodb, ...).
- Banco de cache (redis, memcached, ...).

O ponto mais importante aqui, é o pub/sub, por ser uma alternativa com disponibilidade GLOBAL. Ou seja, é aqui que vou garantir que receberei o dado gerado pelo usuário final independente da indisponibilidade da aplicação.

- A estratégia aqui, pode ser implementada de várias formas, vou apresentar apenas um modelo para exemplificar.

Tornando as aplicações mais disponíveis:

As aplicações, estejam onde estiverem, vamos buscar torná-las disponíveis entre diferentes zonas e regiões, usando essa solução que já expliquei como implementar e deploy em 2 regiões diferentes (sempre multi-zona), das aplicações Cloud run e Cloud function (por cobrarem por uso, não é um problema executar em regiões diferentes ou estarem duplicadas, você só vai pagar pelo processamento efetuado).

Tornando o banco de dados disponível:

Os bancos de dados, mongodb, postgresql, sqlserver o qualquer outro, podem estar onde você quiser, até mesmo em uma VM gerando snapshots para evitar dores de cabeça. O que vai tornar o dado disponível, é o banco de cache (redis ou memcached - destaco esses pela facilidade de subir instancias desses dentro do kubernetes).

A "mágica"

O segredo aqui, é a forma como as aplicações lidam com os dados. 
Basicamente nossas aplicações, independente de onde executam, vão gravar os dados em tópicos do pub/sub (pela garantia de disponibilidade) e vão ler os dados dos bancos de cache que estarão dentro do Kubernetes. 
Quando o usuário fizer uma operação para gravar um dado, a aplicação vai mandar para o pud/sub e utilizar um recurso assíncrono, para processamento dessa fila (pode ser hangfire, por exemplo) para enviar o dado da fila, para o banco de dados da aplicação (postgresql, sql server, mongodb ou outro) e esse mesmo poderia atualizar o banco de cache, mas isso pode ser feito no momento da leitura.
Vamos imaginar que agora o usuário faz uma requisição aos serviços e esses teriam de buscar o dados no banco de dados. No lugar de buscar no banco de dados, vai buscar no banco de cache e disparar uma thread para atualizar o banco de cache.
Dessa forma, estamos assegurando que a leitura está sempre na mesma região, independente se o banco de dados está distribuído em diferentes regiões ou está em uma maquina rodando apenas em uma zona.

Dica: Se quiser garantir mais disponibilidade entre regiões com seu banco de dados, opte por usar Cloud SQL da GCP, com banco MySql (ele possui recurso para replicas em diferentes regiões).

Algumas questões:

- Se o banco de dados estiver indisponível: Não tem problema, o dado estará disponível no pub/sub até que o banco esteja disponível, para receber o dado.
- Diferentes regiões, terão bancos de cache com dados diferentes. Mas isso não é um grande problema se você implementou o MCI como expliquei aqui, pois o Load Balancer vai cuidar de direcionar o usuário para o cluster mais próximo a ele e só vai ocorrer de cair em outro região, se o Load Balancer encontrar motivos para te mandar para lá. E entre não oferecer nada para o usuário e oferecer um dado que não está totalmente atualizado, prefiro dado não atualizado.

Fechamos \o/
Esse foi um exemplo BEM SIMPLES e BEM RESUMIDO. Obviamente, de acordo com a necessidade do seu negócio, isso pode ou não ser mais elaborado. É sempre valido avaliar os benefícios de uma arquitetura distribuída em qualquer problema, pode ser simples e barato resolver problemas que parecem impossíveis de serem resolvidos, apenas usando as ferramentas adequadas.