Anotações sobre NoSQL

Mario Guedes
ArrayOf.io
Published in
5 min readApr 6, 2021

Olá! Compartilho aqui as minhas anotações sobre a minha leitura do livro:

NoSQL Essencial: um Guia Conciso Para o Mundo Emergente da Persistência Poliglota

A persistência “poliglota”, onde utilizamos vários paradigmas de armazenamento de dados para diferentes circunstâncias, oferece produtividade no desenvolvimento de aplicativos por eliminar o esforço em mapear os dados entre as estruturas de dados da linguagem e o banco de dados relacional.

Incompatibilidade de Impedância

O modelo de dados relacional organiza os dados em uma estrutura de tabelas e linhas: relações e tuplas.

A incompatibilidade surge no momento em que é necessário “traduzir” o modelo relacional para as estruturas de dados em memória, ficando mais evidente em estruturas mestre/detalhe.

Os ORMs visam mitigar o problema do ponto de vista do programador mas tendem a comprometer os desempenhos das pesquisas dependendo de como este recurso é utilizado.

Há um movimento na direção contrária à utilização de banco de dados como ponto de integração. Em vez disso, defende-se o encapsulamento de banco de dados em aplicativos e a integração por meio de serviços.
— Página 39

Modelo Relacional X Modelo de Dados Agregados

Um agregado é um conjunto de objetos relacionados que desejamos tratar como uma unidade.

O fato dos bancos de dados não oferecerem controle de transações não deve ser um problema na maior parte do tempo pois a atomicidade é sobre um agregado e espera-se que este tenha as informações suficientes e auto contidas.

Pelo fato de não existir um esquema podemos armazenar o que julgarmos necessário podendo incluir e descartar informações sem grandes prejuízos.

Porém por mais livre de esquema o banco seja existe certamente um esquema implícito que são as suposições sobre a estrutura dos dados no código fonte.

Basicamente, um banco de dados sem esquema transfere o esquema para o código do aplicativo que o acessa. Isso é um problema quando vários aplicativos acessam o mesmo banco de dados.

Uma abordagem interessante é criar um serviço que encapsula o banco de dados NoSQL.

Visão Materializada

Diferentemente de um banco relacional um banco NoSQL não possui o recurso de view, prejudicando a obtenção de valores com funções de agregação, como count ou sum por exemplo.

Apesar disto há algumas possibilidades:

  • Computação map/reduce.
  • Abordagem antecipada: Atualiza-se um agregado de resumo e o agregado básico fundamental.
  • Atualizações em lote: Alivia a sobrecarga computacional mas cria atrasos.
  • Um resumo nos próprios agregados básicos.

Ao modelar um agregado de dados devemos ter em mente a frequência leitura, de gravação, e quais os interesses da aplicação.

Essa decisão implica em três escolhas:

  • Um grande agregado?
  • Dois agregados com referências circulares?
  • Três agregados sendo um específico para o relacionamento?

Distribuição

Existem dois modelos no que se refere à distribuição de dados:

  • Replicação: Primário/Secundários ou Ponto a Ponto
  • Fragmentação (sharding)

A replicação obtém os mesmo dados e os copia em múltiplos nodos. A fragmentação coloca dados diferentes em nodos diferentes. São técnicas ortogonais podendo-se adotar uma ou ambas.

Implementação

Sem distribuição

Podemos implementar em um único servidor por ser a solução mais óbvia em todos os aspectos envolvidos: desenvolvimento, manutenção e etc.
É a melhor escolha se os requisitos assim o permitirem .

Fragmentação (sharding)

Há casos em que um armazenamento de dados fica extremamente ocupado pois vários processos estão acessando partes diferentes do conjunto de dados.

Para dirimir este cenário podemos utilizar a fragmentação que é o fato de colocarmos dados diferentes em nodos diferentes.

O desafio neste cenário é o de determinar a melhor divisão a ser feita pois poderá penalizar a aplicação cliente no processo de recuperação de dados.

Uma fragmentação óbvia seria por um critério geográfico (pensando em uma grande plataforma).

A palavra chave neste ponto da discussão é desempenho na escrita e consequentemente a leitura é beneficiada.

A perda está na resiliência do sistema pois se um nodo ficar indisponível a solução como um todo fica comprometida.

Portanto a fragmentação não deve ser aplicada isoladamente.

Replicação Primário/Secundários

No esquema primário/secundários é eleito um nodo primário que suportará toda a carga de escrita.

Um processo automatizado propaga as alterações para os nodos secundários que, por sua vez, concentram as cargas de leituras.

Isso melhora o cenário do ponto de vista da carga de escrita porém cria inconsistências nas leituras pois sempre há uma demora, por mínima que seja, na replicação dos dos.

Replicação Ponto a Ponto

Na Replicação Ponto a Ponto um processo garante a sincronia entre todos os nodos não havendo a figura do nodo primário.

É necessário lidar com um problema importante que é o fato das aplicações clientes manipularem os mesmos dados em nodos diferente podendo criar uma inconsistência na escrita.

Há um dilema ser resolvida: consistência ou disponibilidade?

Sobre consistência e Durabilidade

Consistência refere-se à confiabilidade dos dados no momento da escrita ou leitura. Um banco de dados relacional resolve este problema com transações.

Existem duas abordagens para evitar conflitos:

  • Otimista: Aceita os conflitas e os trata
  • Pessimista: Evita os conflitos

Exemplo de uma abordagem otimista:

  • Atualização condicional: Testa o valor antes de efetuar a alteração.

A programação concorrente envolve um equilíbrio entre:

  • Segurança: Abordagem pessimista
  • Disponibilidade: Abordagem otimista

Banco de dados orientados à agregados (também descrito como orientado a documentos) suportam atualizações atômicas dentro de um único agregado.

Devemos então modelar os agregados com isto em mente.

Janela de Inconsistência

Em banco de dados NoSQL temos o conceito de “Janela de Inconsistência” que é justamente aquele período crítico de atualização de múltiplos agregados.

Fica a cargo da aplicação garantir a consistência lógica que refere-se justamente à consistência entre múltiplos agregados.

Consistência de Replicação

Existe um problema real quando se trabalha em cluster que é a “Consistência de Replicação”.

Trata-se em garantir que o mesmo item de dados tenha o mesmo valor quando lido de diferentes réplicas.

Quando um nodo é atualizado leva-se um período para a replicação em outros nodos. Esta situação é chamada de “Eventualmente Consistente”, onde a palavra “eventualmente” tem o mesmo sentido de que “em algum momento”.

Este conceito também contribui para a “Janela de Inconsistência”.

Consistência de Sessão

Uma necessidade que pode surgir é o de se criar uma “Consistência de Sessão”. Isso porque entre o backend e o frontend pode existir um balanceador de carga. Com isso a escrita pode se dar em um nodo e a leitura em outro nodo ainda desatualizado deixando o usuário confuso. Um exemplo clássico seria uma solução de blogging.

Cria-se, então, uma afinidade de sessão porém isto tira a capacidade do balanceador de carga executar plenamente o seu trabalho.

--

--

Mario Guedes
ArrayOf.io

Artesão de Software desde 1999, com conhecimentos em Delphi, Python, Lua e JavaScript com bancos noSQL.