Atualmente estou trabalhando no ManyChat. Na verdade, esta é uma startup - nova, ambiciosa e em rápido crescimento. E quando eu acabei de entrar na empresa, surgiu a pergunta clássica: "O que uma jovem startup deve tirar agora do mercado de DBMS e bancos de dados?"
Neste artigo, com base na minha palestra no festival online RIT ++ 2020 , vou responder a esta pergunta. Uma versão em vídeo do relatório está disponível no YouTube .

Bancos de dados bem conhecidos de 2020
É 2020, olhei em volta e vi três tipos de bancos de dados.
O primeiro tipo são os bancos de dados OLTP clássicos : PostgreSQL, SQL Server, Oracle, MySQL. Eles foram escritos há muito tempo, mas ainda são relevantes porque são familiares à comunidade de desenvolvedores.
O segundo tipo - bases de "zero" . Eles tentaram se afastar dos padrões clássicos abandonando SQL, estruturas tradicionais e ACID, adicionando sharding integrado e outros recursos atraentes. Por exemplo, são Cassandra, MongoDB, Redis ou Tarantool. Todas essas soluções queriam oferecer ao mercado algo fundamentalmente novo e ocupavam seu nicho, pois em certas tarefas se revelavam extremamente convenientes. Essas bases serão denotadas pelo termo genérico NOSQL.
Os "zeros" acabaram, habituaram-se às bases de dados NOSQL e o mundo, do meu ponto de vista, deu o passo seguinte - às bases de dados geridas . Esses bancos de dados têm o mesmo núcleo dos bancos de dados OLTP clássicos ou novos bancos de dados NoSQL. Mas eles não precisam de DBA e DevOps e são executados em hardware gerenciado nas nuvens. Para um desenvolvedor, essa é "apenas uma base" que funciona em algum lugar, mas como é instalada no servidor, quem configurou o servidor e quem o atualiza, ninguém liga.
Exemplos dessas bases:
- AWS RDS é um wrapper gerenciado sobre PostgreSQL / MySQL.
- O DynamoDB é um análogo AWS de um banco de dados baseado em documentos, semelhante ao Redis e MongoDB.
- Amazon Redshift é uma base de análise gerenciada.
Basicamente, são bancos de dados antigos, mas criados em um ambiente gerenciado, sem a necessidade de trabalhar com hardware.
Nota. Os exemplos são usados para o ambiente AWS, mas suas contrapartes também existem no Microsoft Azure, Google Cloud ou Yandex.Cloud.

Então, o que há de novo? Em 2020, nada disso.
Conceito sem servidor
O que é realmente novo no mercado em 2020 são as soluções sem servidor ou sem servidor.
Tentarei explicar o que isso significa usando o exemplo de um serviço regular ou aplicativo de back-end.
Para implantar um aplicativo de back-end regular, compramos ou alugamos um servidor, copiamos o código para ele, publicamos o endpoint fora e pagamos regularmente pelo aluguel, eletricidade e serviços de data center. Este é o layout padrão.
Existe alguma outra maneira? Com serviços sem servidor, você pode.
Qual é o foco dessa abordagem: não há servidor, não há nem mesmo aluguel de instância virtual na nuvem. Para implantar o serviço, copie o código (funções) para o repositório e publique o terminal fora. Em seguida, apenas pagamos por cada chamada desta função, ignorando completamente o hardware onde ela é executada.
Tentarei ilustrar essa abordagem em fotos.

Implantação clássica . Temos um serviço com certa carga. Levantamos duas instâncias: servidores físicos ou instâncias na AWS. As solicitações externas são enviadas para essas instâncias e processadas lá.
Como você pode ver na foto, os servidores são utilizados de forma diferente. Um está 100% utilizado, há duas solicitações e uma está apenas 50% parcialmente ociosa. Se não vierem três solicitações, mas 30, todo o sistema não aguentará a carga e começará a ficar mais lento.

Implantação sem servidor... Em um ambiente sem servidor, esse serviço não tem instâncias ou servidores. Há um pool de recursos aquecidos - pequenos contêineres Docker preparados com código de função implantado. O sistema recebe solicitações externas e, para cada uma delas, a estrutura sem servidor cria um pequeno contêiner com código: ele processa essa solicitação específica e mata o contêiner.
Um pedido - um contêiner elevado, 1000 pedidos - 1000 contêineres. E a implantação em servidores de ferro já é trabalho de um provedor de nuvem. Ele está completamente oculto pela estrutura sem servidor. Nesse conceito, pagamos por cada ligação. Por exemplo, chegava uma ligação por dia - pagamos por uma ligação, um milhão vinha em um minuto - pagamos por um milhão. Ou, em um segundo, isso também acontece.
O conceito de publicar uma função sem servidor é apropriado para um serviço sem estado. E se você precisar de um serviço com estado (estado), adicione um banco de dados ao serviço. Nesse caso, quando se trata de trabalhar com estado, com estado, cada função com estado simplesmente grava e lê do banco de dados. Além disso, de um banco de dados de qualquer um dos três tipos descritos no início do artigo.
Qual é a limitação geral de todas essas bases? Esses são os custos de um servidor em nuvem ou de ferro constantemente usado (ou vários servidores). Não importa se usamos um banco de dados clássico ou gerenciado, se há Devops e um administrador ou não, ainda pagamos 24/7 pelo aluguel de hardware, eletricidade e data center. Se tivermos uma base clássica, pagamos por mestre e escravo. Se uma base fragmentada altamente carregada - pagamos por 10, 20 ou 30 servidores, e pagamos constantemente.
A presença de servidores permanentemente reservados na estrutura de custos costumava ser percebida como um mal necessário. Bancos de dados comuns também apresentam outras dificuldades, como limites no número de conexões, limites de escalonamento, consenso geo-distribuído - eles podem ser resolvidos de alguma forma em determinados bancos de dados, mas não de uma vez e não o ideal.
Banco de dados sem servidor - teoria
Pergunta de 2020: o banco de dados também pode ser sem servidor? Todo mundo já ouviu falar sobre o back-end sem servidor ... mas vamos tentar tornar o banco de dados sem servidor também?
Isso parece estranho porque um banco de dados é um serviço com estado, não muito adequado para uma infraestrutura sem servidor. Ao mesmo tempo, o estado do banco de dados é muito grande: gigabytes, terabytes e até petabytes em bancos de dados analíticos. Não é tão fácil levantá-lo em contêineres Docker leves.
Por outro lado, quase todos os bancos de dados modernos são uma grande quantidade de lógica e componentes: transações, negociação de integridade, procedimentos, dependências relacionais e muita lógica. Grande parte da lógica do banco de dados é um estado bastante pequeno. Gigabytes e Terabytes são usados diretamente por apenas uma pequena parte da lógica do banco de dados associada à execução direta de consultas.
Conseqüentemente, a ideia: se uma parte da lógica permite a execução sem estado, por que não dividir a base em partes com e sem estado.
Sem servidor para soluções OLAP
Vamos ver como um banco de dados dividido em partes com e sem estado pode se parecer com exemplos práticos.

Por exemplo, temos um banco de dados analítico : dados externos (cilindro vermelho à esquerda), um processo ETL que carrega dados no banco de dados e um analista que envia consultas SQL ao banco de dados. Esta é a maneira clássica de funcionar um data warehouse.
Neste esquema, por convenção, o ETL é executado uma vez. Então você precisa pagar o tempo todo pelos servidores que executam o banco de dados com dados inundados com ETL, para que você tenha algo para lançar solicitações.
Considere uma abordagem alternativa implementada no AWS Athena Serverless. Não há hardware dedicado permanentemente no qual os dados baixados são armazenados. Em vez disso:
- SQL- Athena. Athena SQL- (Metadata) , .
- , , ( ).
- SQL- , .
- , .
Nesta arquitetura, pagamos apenas pelo processo de execução da solicitação. Sem pedidos - sem custos.

Esta é uma abordagem funcional e é implementada não apenas no Athena Serverless, mas também no Redshift Spectrum (na AWS).
O exemplo de Athena mostra que o banco de dados sem servidor funciona em consultas reais com dezenas e centenas de Terabytes de dados. Centenas de Terabytes exigirão centenas de servidores, mas não precisamos pagar por eles - pagamos pelas solicitações. A velocidade de cada solicitação é (muito) lenta em comparação com bancos de dados analíticos especializados como Vertica, mas não pagamos pelo tempo de inatividade.
Esse banco de dados é útil para consultas analíticas ad-hoc infrequentes. Por exemplo, quando decidimos espontaneamente testar uma hipótese em alguma quantidade gigantesca de dados. Athena é perfeita para esses casos. Para consultas regulares, esse sistema é caro. Nesse caso, armazene os dados em cache em alguma solução especializada.
Sem servidor para soluções OLTP
No exemplo anterior, as tarefas OLAP (analíticas) foram consideradas. Agora, vamos examinar as tarefas OLTP.
Imagine PostgreSQL ou MySQL escalonável. Vamos criar uma instância gerenciada regular PostgreSQL ou MySQL com recursos mínimos. Quando mais carga chegar à instância, conectaremos réplicas adicionais às quais distribuiremos parte da carga de leitura. Se não houver solicitações e nenhuma carga, desligamos as réplicas. A primeira instância é a mestre e as demais são réplicas.
Essa ideia é implementada em um banco de dados chamado Aurora Serverless AWS. O princípio é simples: as solicitações de aplicativos externos são aceitas pela frota de proxy. Vendo um aumento na carga, ele aloca recursos de computação de instâncias mínimas pré-aquecidas - a conexão é o mais rápida possível. Desconectar instâncias é o mesmo.
Dentro da Aurora, existe o conceito de Aurora Capacity Unit, ACU. Esta é (condicionalmente) uma instância (servidor). Cada ACU específico pode ser mestre ou escravo. Cada unidade de capacidade tem sua própria RAM, processador e disco mínimo. Conseqüentemente, um é mestre, o resto são réplicas somente leitura.
O número dessas unidades de capacidade Aurora em operação é configurável. A quantidade mínima pode ser um ou zero (neste caso, a base não funciona se não houver solicitações).

Quando a base recebe solicitações, a frota proxy eleva as unidades de capacidade Aurora, aumentando os recursos produtivos do sistema. A capacidade de aumentar e diminuir recursos permite que o sistema "faça malabarismos": exiba automaticamente ACUs individuais (substituindo-os por novos) e acumule todas as atualizações relevantes nos recursos removidos.
A base Aurora Serverless pode dimensionar a carga de leitura. Mas a documentação não diz isso diretamente. Pode parecer que eles podem pegar um multi-master. Não existe mágica.
Esta base é adequada para não gastar muito dinheiro em sistemas com acesso imprevisível. Por exemplo, ao construir sites de MVP ou de marketing de cartão de visita, geralmente não esperamos uma carga constante. Portanto, na ausência de acesso, não pagamos pelas instâncias. Quando uma carga surge inesperadamente, por exemplo, após uma conferência ou campanha publicitária, multidões de pessoas visitam o site e a carga aumenta drasticamente, o Aurora Serverless assume automaticamente essa carga e conecta rapidamente os recursos ausentes (ACU). Em seguida, a conferência continua, todos se esquecem do protótipo, os servidores (ACU) são desativados e os custos caem para zero - é conveniente.
Esta solução não é adequada para altas cargas estáveis porque não pode escalar a carga de gravação. Todas essas conexões e desconexões de recursos ocorrem no momento do chamado "ponto de escala" - o momento em que o banco de dados não é mantido pela transação, as tabelas temporárias não são mantidas. Por exemplo, dentro de uma semana o ponto de escala pode não acontecer e a base funciona com os mesmos recursos e simplesmente não pode expandir ou encolher.
Não há mágica - isso é PostgreSQL normal. Mas o processo de adicionar carros e desconectar é parcialmente automatizado.
Sem servidor por design
Aurora Serverless é uma base antiga reescrita para a nuvem para aproveitar os benefícios individuais de Serverless. E agora vou falar sobre a base, que foi originalmente escrita para a nuvem, para a abordagem sem servidor - sem servidor por design. Ele foi imediatamente desenvolvido sem a suposição de que seja executado em servidores físicos.
Essa base é chamada de floco de neve. Possui três blocos principais.

O primeiro é um bloco de metadados. É um serviço rápido na memória que resolve problemas de segurança, metadados, transações e otimização de consultas (na ilustração à esquerda).
O segundo bloco é um conjunto de clusters computacionais virtuais para cálculos (na ilustração - um conjunto de círculos azuis).
O terceiro bloco é um sistema de armazenamento baseado em S3. S3 é o armazenamento de objetos adimensional da AWS, semelhante ao Dropbox adimensional para empresas.
Vamos dar uma olhada em como o Snowflake funciona sob a suposição de inicialização a frio. Ou seja, o banco de dados está lá, os dados são carregados nele, não há consultas de trabalho. Conseqüentemente, se não houver consultas ao banco de dados, então criamos um serviço rápido de Metadados na memória (primeiro bloco). E temos o armazenamento S3, onde os dados da tabela são armazenados, divididos nas chamadas micropartições. Para simplificar: se a tabela contém negócios, os microlotes são os dias de negócios. Cada dia é um microlote separado, um arquivo separado. E quando o banco de dados funciona neste modo, você paga apenas pelo espaço ocupado pelos dados. Além disso, a taxa por assento é muito baixa (especialmente dada a compressão significativa). O serviço de metadados também funciona constantemente, mas não precisa de muitos recursos para otimizar as consultas, e o serviço pode ser considerado shareware.
Agora vamos imaginar que um usuário venha ao nosso banco de dados e lance uma consulta SQL. A consulta SQL é enviada imediatamente para o serviço de Metadados para processamento. Assim, ao receber um pedido, este serviço analisa o pedido, os dados disponíveis, a autoridade do utilizador e, se tudo correr bem, elabora um plano de processamento do pedido.
Em seguida, o serviço inicia o lançamento do cluster computacional. Um cluster de computação é um cluster de servidores que realiza cálculos. Ou seja, este é um cluster que pode conter 1 servidor, 2 norte, 4, 8, 16, 32 - quantos você quiser. Você lança um pedido e o lançamento deste cluster começa instantaneamente sob ele. Realmente leva segundos.

Além disso, depois que o cluster foi iniciado, as micropartições são copiadas para o cluster do S3, que são necessárias para processar sua solicitação. Ou seja, imagine que para executar uma consulta SQL, você precisa de duas partições de uma tabela e uma da segunda. Nesse caso, apenas as três partições necessárias serão copiadas para o cluster, e não todas as tabelas como um todo. É por isso e precisamente porque tudo está dentro da estrutura de um centro de dados e está conectado por canais muito rápidos, todo o processo de bombeamento ocorre muito rapidamente: em segundos, muito raramente - em minutos, se não estivermos falando de alguns pedidos monstruosos ... Assim, as micropartições são copiadas para o cluster computacional e, após a conclusão, uma consulta SQL é executada neste cluster computacional. O resultado desta consulta pode ser uma linha, várias linhas ou uma tabela - eles são enviados para o usuário,para que possa ser baixado, exibido em sua ferramenta de BI ou usado de alguma outra forma.
Cada consulta SQL pode não apenas ler agregados de dados carregados anteriormente, mas também carregar / formar novos dados no banco de dados. Ou seja, pode ser uma consulta que, por exemplo, insere novos registros em outra tabela, o que leva ao surgimento de uma nova partição no cluster computacional, que, por sua vez, é automaticamente armazenada em um único armazenamento S3.
O cenário descrito acima, da chegada de um usuário ao aumento do cluster, carregamento de dados, execução de consultas, obtenção de resultados, é pago pela taxa por minutos de uso do cluster de computação virtual gerado, armazém virtual. A taxa varia de acordo com a zona da AWS e o tamanho do cluster, mas, em média, custa alguns dólares por hora. Um aglomerado de quatro carros é duas vezes mais caro do que um aglomerado de dois carros e um aglomerado de oito carros é duas vezes mais caro. Opções disponíveis de 16, 32 carros, dependendo da complexidade das solicitações. Mas você paga apenas pelos minutos em que o cluster realmente funciona, porque quando não há solicitações, você meio que tira as mãos e, após 5-10 minutos de espera (um parâmetro configurável), ele sai sozinho, libera recursos e fica livre.
O cenário é bastante real quando você lança uma solicitação, o cluster aparece, relativamente falando, em um minuto, ele conta outro minuto, depois cinco minutos para desligar, e você paga como resultado por sete minutos de operação desse cluster, e não por meses e anos.
O primeiro cenário descrito usando Snowflake em um cenário de usuário único. Agora vamos imaginar que existem muitos usuários, o que está mais próximo de um cenário real.
Digamos que temos muitos analistas e relatórios do Tableau que bombardeiam constantemente nosso banco de dados com muitas consultas analíticas SQL simples.
Além disso, digamos que temos cientistas de dados engenhosos que estão tentando fazer coisas monstruosas com os dados, operar em dezenas de terabytes, analisar bilhões e trilhões de linhas de dados.
Para os dois tipos de carga descritos acima, o Snowflake permite que você levante vários clusters de computação independentes de diferentes capacidades. Além disso, esses clusters computacionais operam de forma independente, mas com dados consistentes comuns.
Para um grande número de consultas leves, você pode gerar 2-3 pequenos clusters, de tamanho convencional, 2 máquinas cada. Este comportamento é realizável, entre outras coisas, usando configurações automáticas. Ou seja, você diz: “Floco de neve, eleve um pequeno cacho. Se a carga crescer mais do que um determinado parâmetro, aumente um segundo, terceiro semelhante. Quando a carga começar a diminuir - apague os extras. " Para que não importa quantos analistas venham e comecem a olhar os relatórios, todos têm recursos suficientes.
Ao mesmo tempo, se os analistas estiverem dormindo e ninguém estiver olhando os relatórios, os clusters podem ser totalmente desativados e você para de pagar por eles.
Ao mesmo tempo, para consultas pesadas (de cientistas de dados), você pode gerar um cluster muito grande por 32 máquinas condicionais. Este cluster também será cobrado apenas pelos minutos e horas em que sua solicitação gigante estiver em execução lá.
A funcionalidade acima descrita permite dividir em clusters não apenas 2, mas também mais tipos de carga (ETL, monitorização, materialização de relatórios, ...).
Vamos resumir o floco de neve. A base combina uma bela ideia e uma implementação viável. No ManyChat, usamos o Snowflake para analisar todos os dados que temos. Não temos três clusters, como no exemplo, mas de 5 a 9, de tamanhos diferentes. Temos 16 máquinas condicionais, 2 máquinas, e também 1 máquina super pequena para algumas tarefas. Eles distribuem a carga com sucesso e nos permitem economizar muito.
A base dimensiona com sucesso a carga de trabalho de leitura e gravação. Esta é uma diferença enorme e um grande avanço em comparação com o mesmo "Aurora", que puxou apenas a carga de leitura. O Snowflake permite que esses clusters de computação escalonem e gravem cargas de trabalho. Ou seja, como mencionei, usamos vários clusters no ManyChat, clusters pequenos e super-pequenos são usados principalmente para ETL, para carregar dados. E os analistas já vivem em clusters de tamanho médio que absolutamente não são afetados pela carga de ETL, portanto, eles trabalham muito rapidamente.
Conseqüentemente, a base é adequada para tarefas OLAP. Ao mesmo tempo, infelizmente, ainda não é aplicável para cargas de trabalho OLTP. Em primeiro lugar, esta base é colunar, com todas as consequências daí decorrentes. Em segundo lugar, a abordagem em si, quando para cada solicitação, se necessário, você levanta um cluster computacional e derrama-o com dados, infelizmente, para cargas de trabalho OLTP ainda não é rápido o suficiente. Esperar segundos para tarefas OLAP é normal, mas para tarefas OLTP é inaceitável, 100 ms seria melhor, e ainda melhor - 10 ms.
Resultado
O banco de dados sem servidor é possível separando o banco de dados em partes sem estado e com estado. Você deve ter notado que em todos os exemplos dados, a parte Stateful está, relativamente falando, armazenando micropartições no S3, e Stateless é um otimizador, trabalhando com metadados, lidando com questões de segurança que podem ser levantadas como independentes leves Serviços sem estado.
A execução de consultas SQL também pode ser considerada como serviços de estado leve que podem surgir no modo sem servidor, como clusters de computação Snowflake, baixar apenas os dados de que você precisa, executar a consulta e sair.
Bancos de dados de nível de produção sem servidor já estão disponíveis para uso, eles estão funcionando. Esses bancos de dados sem servidor já estão prontos para lidar com tarefas OLAP. Infelizmente, eles são usados para tarefas OLTP ... com nuances, uma vez que existem limitações. Por um lado, isso é um sinal de menos. Mas, por outro lado, é uma oportunidade. Talvez alguns dos leitores encontrem uma maneira de tornar a base OLTP completamente sem servidor, sem as limitações do Aurora.
Espero que você tenha achado interessante. Sem servidor é o futuro :)