Anotações sobre NoSQL
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.