Por que o cluster do RDBM não pode do jeito que o NoSQL faz?

88

Uma das grandes vantagens do DBMS nosql é que eles podem se agrupar mais facilmente. Supostamente com o NoSQL, você pode criar centenas de máquinas baratas que armazenam diferentes dados e consultam tudo de uma vez.

Minha pergunta é esta, por que o DBMS relacional não pode fazer isso como mysql ou sql server? Será que os fornecedores simplesmente não descobriram uma maneira técnica de fazer isso com o produto existente ou há algum problema no modelo relacional que impede que isso seja viável? O que há de tão bom na maneira NoSQL de armazenar e acessar dados (chave / valor, documentos, etc.) que facilita o agrupamento, se isso é verdade?

fregas
fonte
8
Armazenar diferentes bits de dados em diferentes máquinas (sharding) é tecnicamente incrivelmente fácil, comparado a algo como o Oracle RAC, que pode ser executado em até 63 nós, cada um apresentando o mesmo banco de dados, todos compatíveis com ACID, etc. "Clustering" no NoSQL é fácil porque não há ACID, eles usam suas próprias APIs proprietárias e são relativamente simples.
Philᵀᴹ
6
O RAC ainda é uma arquitetura de disco compartilhado. Ele ainda requer um comutador SAN central para que qualquer um dos nós do DBMS possa ver qualquer armazenamento. Você pode ter vários controladores SAN, tornando-a uma arquitetura M: M. O Teradata é uma arquitetura de nada compartilhado, mas é otimizada para aplicativos de data warehouse e você ainda pode replicar partes do banco de dados (por exemplo, tabelas de dimensões) em todos os nós. Netezza é ainda menos útil. Você precisa carregar os segmentos individuais de uma tabela particionada separadamente.
ConcernedOfTunbridgeWells
1
Então, eu li e entendi (a maioria) resposta em questão abaixo. A questão parece ter muito mais a ver com o ACID do que com o modelo relacional. Existem soluções que usam o modelo relacional, mesmo que não sejam totalmente compatíveis com ácidos, da mesma forma que o NoSQL? Parece que NoSQL deve realmente ser chamado NoACID como ele não tem nada a ver com SQL ou modelo relacional, e tudo a ver com coerência, atomicidade, acesso a dados e locais de armazenamento, etc.
fregas
6
@fregas - NoSQL não possui nenhuma definição formal. É apenas uma palavra de ordem aplicada a vários sistemas de gerenciamento de banco de dados. A replicação de quorum (AKA consistência eventual) é usada por muitos desses sistemas (embora de modo algum todos) como uma otimização de desempenho. Não conheço nenhum produto RDBMS que use replicação de quorum - certamente nenhum dos principais. Não há razão teórica para que isso não possa ser feito, mas seria bastante complexo e de valor questionável, dado o nível de escalabilidade que pode ser alcançado pelos sistemas de disco compartilhados de qualquer maneira.
ConcernedOfTunbridgeWells
A replicação de quorum @ConcernedOfTunbridgeWells é inconsistente com o ACID, e é por isso que isso não será feito.
22813 Chris Travers

Respostas:

141

Sistemas de banco de dados distribuídos 101

Ou, bancos de dados distribuídos - o que o FK realmente significa ' escala da web '?

Os sistemas de banco de dados distribuídos são criaturas complexas e apresentam uma variedade de sabores diferentes. Se eu me aprofundar nos meus estudos pouco lembrados sobre isso na universidade, tentarei explicar alguns dos principais problemas de engenharia para a construção de um sistema de banco de dados distribuído.

Primeiro, alguma terminologia

Propriedades ACID (Atomicidade, Consistência, Isolamento e Durabilidade): essas são as principais invariantes que devem ser aplicadas para que uma transação seja implementada de maneira confiável, sem causar efeitos colaterais indesejáveis.

A atomicidade requer que a transação seja concluída ou revertida completamente. As transações parcialmente concluídas nunca devem estar visíveis e o sistema deve ser construído de forma a impedir que isso aconteça.

A consistência requer que uma transação nunca viole quaisquer invariantes (como integridade referencial declarativa) garantidos pelo esquema do banco de dados. Por exemplo, se uma chave estrangeira existir, será impossível inserir um registro filho com uma reverência a um pai inexistente.

O isolamento requer que as transações não interfiram entre si. O sistema deve garantir os mesmos resultados se as transações forem executadas em paralelo ou sequencialmente. Na prática, a maioria dos produtos RDBMS permite modos que compensam o isolamento em relação ao desempenho.

A durabilidade exige que, uma vez confirmada, a transação permaneça no armazenamento persistente de maneira robusta à falha de hardware ou software.

Vou explicar alguns dos obstáculos técnicos que esses requisitos apresentam nos sistemas distribuídos abaixo.

Arquitetura de disco compartilhado: Uma arquitetura na qual todos os nós de processamento em um cluster têm acesso a todo o armazenamento. Isso pode apresentar um gargalo central para o acesso a dados. Um exemplo de sistema de disco compartilhado é Oracle RAC ou Exadata .

Arquitetura de nada compartilhado: uma arquitetura na qual os nós de processamento em um cluster possuem armazenamento local que não é visível para outros nós do cluster. Exemplos de sistemas com compartilhamento de nada são Teradata e Netezza .

Arquitetura de memória compartilhada: Uma arquitetura na qual várias CPUs (ou nós) podem acessar um conjunto compartilhado de memória. A maioria dos servidores modernos possui um tipo de memória compartilhada. A memória compartilhada facilita certas operações, como caches ou primitivas de sincronização atômica, que são muito mais difíceis de fazer em sistemas distribuídos.

Sincronização: um termo genérico que descreve vários métodos para garantir acesso consistente a um recurso compartilhado por vários processos ou threads. Isso é muito mais difícil de fazer em sistemas distribuídos do que em sistemas de memória compartilhada, embora algumas arquiteturas de rede (por exemplo, BYNET da Teradata) possuam primitivas de sincronização no protocolo de rede. A sincronização também pode vir com uma quantidade significativa de sobrecarga.

Semi-Join: Uma primitiva usada na junção de dados mantidos em dois nós diferentes de um sistema distribuído. Essencialmente, ele consiste em informações suficientes sobre as linhas para ingressar, sendo agrupadas e passadas por um nó ao outro para resolver a associação. Em uma consulta grande, isso pode envolver tráfego de rede significativo.

Consistência Eventual: Um termo usado para descrever a semântica de transações que negociam atualizações imediatas (consistência nas leituras) em todos os nós de um sistema distribuído para desempenho (e, portanto, maior rendimento da transação) nas gravações. A consistência eventual é um efeito colateral do uso da Replicação de Quorum como uma otimização de desempenho para acelerar confirmações de transação em bancos de dados distribuídos, onde várias cópias de dados são mantidas em nós separados.

Algoritmo de Lamport: um algoritmo para implementar exclusão mútua (sincronização) entre sistemas sem memória compartilhada. Normalmente, a exclusão mútua dentro de um sistema requer uma instrução atômica de leitura-comparação-gravação ou instrução semelhante de um tipo normalmente apenas prática em um sistema de memória compartilhada. Existem outros algoritmos de sincronização distribuídos, mas o Lamport foi um dos primeiros e é o mais conhecido. Como a maioria dos mecanismos de sincronização distribuídos, o algoritmo de Lamport depende muito do tempo exato e da sincronização do relógio entre os nós do cluster.

Confirmação em duas fases (2PC): Uma família de protocolos que garante que as atualizações do banco de dados envolvendo vários sistemas físicos sejam confirmadas ou revertidas de forma consistente. Se o 2PC é usado em um sistema ou em vários sistemas, por meio de um gerenciador de transações, ele carrega uma sobrecarga significativa.

Em um protocolo de confirmação de duas fases, o gerenciador de transações solicita aos nós participantes que persistam na transação, de forma que eles possam garantir que ela será confirmada e sinalize esse status. Quando todos os nós retornam um status 'feliz', ele sinaliza os nós para confirmar. A transação ainda é considerada aberta até que todos os nós enviem uma resposta indicando que a confirmação está concluída. Se um nó for desativado antes de sinalizar a conclusão da confirmação, o gerenciador de transações fará uma nova consulta ao nó quando voltar a funcionar até obter uma resposta positiva indicando que a transação foi confirmada.

Controle de simultaneidade de várias versões (MVCC): gerenciando contenções gravando novas versões dos dados em um local diferente e permitindo que outras transações vejam a versão antiga dos dados até que a nova versão seja confirmada. Isso reduz a contenção do banco de dados à custa de algum tráfego de gravação adicional para gravar a nova versão e depois marcar a versão antiga como obsoleta.

Algoritmo de eleição: Os sistemas distribuídos que envolvem vários nós são inerentemente menos confiáveis ​​que um único sistema, pois há mais modos de falha. Em muitos casos, é necessário algum mecanismo para os sistemas em cluster lidarem com a falha de um nó. Os algoritmos de eleição são uma classe de algoritmos usados ​​para selecionar um líder para coordenar uma computação distribuída em situações em que o nó 'líder' não é 100% determinado ou confiável.

Particionamento horizontal: uma tabela pode ser dividida em vários nós ou volumes de armazenamento por sua chave. Isso permite que um grande volume de dados seja dividido em partes menores e distribuído pelos nós de armazenamento.

Sharding: Um conjunto de dados pode ser particionado horizontalmente em vários nós físicos em uma arquitetura de nada compartilhado. Onde esse particionamento não é transparente (ou seja, o cliente deve estar ciente do esquema de partição e descobrir qual nó consultar explicitamente), isso é conhecido como sharding. Alguns sistemas (por exemplo, Teradata) dividem dados entre nós, mas o local é transparente para o cliente; o termo normalmente não é usado em conjunto com esse tipo de sistema.

Hashing consistente: um algoritmo usado para alocar dados para partições com base na chave. É caracterizada pela distribuição uniforme das chaves de hash e pela capacidade de expandir ou reduzir elasticamente o número de caçambas com eficiência. Esses atributos o tornam útil para particionar dados ou carregar em um cluster de nós em que o tamanho pode mudar dinamicamente com os nós sendo adicionados ou retirados do cluster (talvez devido a falha).

Replicação multimestre: Uma técnica que permite que gravações em vários nós em um cluster sejam replicadas para os outros nós. Essa técnica facilita o dimensionamento, permitindo que algumas tabelas sejam particionadas ou divididas entre servidores e outras sejam sincronizadas no cluster. As gravações devem ser replicadas para todos os nós, em oposição a um quorum, para que as confirmações de transação sejam mais caras em uma arquitetura replicada multimestre que em um sistema replicado por quorum.

Comutador sem bloqueio: Um comutador de rede que usa paralelismo interno de hardware para obter uma taxa de transferência proporcional ao número de portas sem gargalos internos. Uma implementação ingênua pode usar um mecanismo de barra cruzada, mas isso tem complexidade O (N ^ 2) para N portas, limitando-o a comutadores menores. Switches maiores podem usar mais uma topologia interna complexa chamada switch de abrangência mínima não-bloqueante para obter escala de throughput linear sem a necessidade de hardware O (N ^ 2).

Criando um DBMS distribuído - quão difícil pode ser?

Vários desafios técnicos tornam isso bastante difícil na prática. Além da complexidade adicional de criar um sistema distribuído, o arquiteto de um DBMS distribuído precisa superar alguns problemas complicados de engenharia.

Atomicidade em sistemas distribuídos: se os dados atualizados por uma transação estiverem espalhados por vários nós, a confirmação / reversão dos nós deverá ser coordenada. Isso adiciona uma sobrecarga significativa nos sistemas de nada compartilhado. Em sistemas de disco compartilhado, isso é menos problemático, pois todo o armazenamento pode ser visto por todos os nós, para que um único nó possa coordenar a confirmação.

Consistência em sistemas distribuídos: Para usar o exemplo de chave estrangeira citado acima, o sistema deve poder avaliar um estado consistente. Por exemplo, se o pai e o filho de um relacionamento de chave estrangeira pudessem residir em nós diferentes, algum tipo de mecanismo de bloqueio distribuído é necessário para garantir que informações desatualizadas não sejam usadas para validar a transação. Se isso não for imposto, você poderá ter (por exemplo) uma condição de corrida em que o pai é excluído após a verificação de sua presença antes de permitir a inserção do filho.

A imposição atrasada de restrições (ou seja, aguardar a confirmação para validar o DRI) exige que o bloqueio seja mantido durante a transação. Esse tipo de bloqueio distribuído vem com uma sobrecarga significativa.

Se várias cópias de dados forem mantidas (isso pode ser necessário em sistemas de nada compartilhado para evitar tráfego de rede desnecessário de semi-junções), todas as cópias dos dados deverão ser atualizadas.

Isolamento em sistemas distribuídos: onde os dados afetados em uma transação residem em vários nós do sistema, os bloqueios e a versão (se o MVCC estiver em uso) devem ser sincronizados entre os nós. Garantir a serialização das operações, particularmente em arquiteturas de compartilhamento de nada, onde cópias redundantes de dados podem ser armazenadas, requer um mecanismo de sincronização distribuído, como o Algorithm de Lamport, que também possui uma sobrecarga significativa no tráfego de rede.

Durabilidade em sistemas distribuídos: em um sistema de disco compartilhado, o problema de durabilidade é essencialmente o mesmo que um sistema de memória compartilhada, com a exceção de que os protocolos de sincronização distribuídos ainda são necessários entre os nós. O DBMS deve registrar em diário as gravações no log e gravar os dados de maneira consistente. Em um sistema de nada compartilhado, pode haver várias cópias dos dados ou partes dos dados armazenados em nós diferentes. É necessário um protocolo de confirmação de duas fases para garantir que a confirmação ocorra corretamente entre os nós. Isso também gera uma sobrecarga significativa.

Em um sistema de nada compartilhado, a perda de um nó pode significar que os dados não estão disponíveis para o sistema. Para mitigar esses dados, eles podem ser replicados em mais de um nó. A consistência nessa situação significa que os dados devem ser replicados para todos os nós em que normalmente residem. Isso pode gerar uma sobrecarga substancial nas gravações.

Uma otimização comum feita nos sistemas NoSQL é o uso de replicação de quorum e eventual consistência para permitir a replicação lenta dos dados, garantindo um certo nível de resiliência dos dados gravando em um quorum antes de relatar a transação como confirmada. Os dados são replicados preguiçosamente para os outros nós em que as cópias dos dados residem.

Observe que 'consistência eventual' é uma grande troca de consistência que pode não ser aceitável se os dados precisarem ser visualizados de maneira consistente assim que a transação for confirmada. Por exemplo, em um aplicativo financeiro, um saldo atualizado deve estar disponível imediatamente.

Sistemas de disco compartilhado

Um sistema de disco compartilhado é aquele em que todos os nós têm acesso a todo o armazenamento. Assim, o cálculo é independente da localização. Muitas plataformas DBMS também podem funcionar nesse modo - o Oracle RAC é um exemplo dessa arquitetura.

Os sistemas de disco compartilhado podem escalar substancialmente, pois podem suportar um relacionamento M: M entre nós de armazenamento e nós de processamento. Uma SAN pode ter vários controladores e vários servidores podem executar o banco de dados. Essas arquiteturas têm um comutador como gargalo central, mas os comutadores de barra cruzada permitem que esse comutador tenha muita largura de banda. Algum processamento pode ser transferido para os nós de armazenamento (como no caso do Exadata da Oracle), o que pode reduzir o tráfego na largura de banda de armazenamento.

Embora o switch seja teoricamente um gargalo, a largura de banda disponível significa que as arquiteturas de disco compartilhado serão dimensionadas com bastante eficiência para grandes volumes de transações. A maioria das arquiteturas de DBMS convencionais adotam essa abordagem porque oferece escalabilidade 'suficientemente boa' e alta confiabilidade. Com uma arquitetura de armazenamento redundante, como o Fibre Channel, não há um ponto único de falha, pois há pelo menos dois caminhos entre qualquer nó de processamento e qualquer nó de armazenamento.

Sistemas Shared-Nothing

Sistemas de compartilhamento de nada são sistemas em que pelo menos alguns dados são mantidos localmente em um nó e não são diretamente visíveis para outros nós. Isso remove o gargalo de um comutador central, permitindo que o banco de dados seja escalado (pelo menos em teoria) com o número de nós. O particionamento horizontal permite que os dados sejam divididos entre nós; isso pode ser transparente para o cliente ou não (consulte Sharding acima).

Como os dados são inerentemente distribuídos, uma consulta pode exigir dados de mais de um nó. Se uma junção precisar de dados de nós diferentes, uma operação de semi-junção será usada para transferir dados suficientes para suportar a junção de um nó para outro. Isso pode resultar em uma grande quantidade de tráfego de rede, portanto, otimizar a distribuição dos dados pode fazer uma grande diferença no desempenho da consulta.

Geralmente, os dados são replicados entre os nós de um sistema de nada compartilhado para reduzir a necessidade de semi-junções. Isso funciona muito bem em dispositivos de armazenamento de dados, pois as dimensões são geralmente muitas ordens de magnitude menores que as tabelas de fatos e podem ser facilmente replicadas entre os nós. Eles também são normalmente carregados em lotes, portanto a sobrecarga de replicação é menos problemática do que em um aplicativo transacional.

O paralelismo inerente a uma arquitetura de nada compartilhado os torna adequados para o tipo de consulta de varredura de tabela / consultas agregadas característica de um data warehouse. Esse tipo de operação pode ser dimensionado quase linearmente com o número de nós de processamento. Junções grandes entre nós tendem a gerar mais sobrecarga, pois as operações de semi-junção podem gerar muito tráfego de rede.

Mover grandes volumes de dados é menos útil para aplicativos de processamento de transações, onde a sobrecarga de várias atualizações torna esse tipo de arquitetura menos atraente que um disco compartilhado. Portanto, esse tipo de arquitetura tende a não ser amplamente utilizado em aplicativos de data warehouse.

Fragmento, Replicação de Quorum e Consistência Eventual

A Replicação de Quorum é um recurso em que um DBMS replica dados para alta disponibilidade. Isso é útil para sistemas destinados a trabalhar em hardware básico mais barato que não possui recursos internos de alta disponibilidade, como uma SAN. Nesse tipo de sistema, os dados são replicados em vários nós de armazenamento para desempenho de leitura e armazenamento redundante para tornar o sistema resiliente à falha de hardware de um nó.

No entanto, a replicação de gravações em todos os nós é O (M x N) para M nós e N gravações. Isso torna as gravações caras se a gravação precisar ser replicada para todos os nós antes que uma transação possa confirmar. A replicação de quorum é um compromisso que permite que as gravações sejam replicadas em um subconjunto dos nós imediatamente e depois gravadas preguiçosamente nos outros nós por uma tarefa em segundo plano. As gravações podem ser confirmadas mais rapidamente, fornecendo um certo grau de redundância, garantindo que sejam replicadas para um subconjunto mínimo (quorum) de nós antes que a transação seja relatada como confirmada no cliente.

Isso significa que a leitura de nós fora do quorum pode ver versões obsoletas dos dados até que o processo em segundo plano termine de gravar os dados no restante dos nós. A semântica é conhecida como 'Consistência Eventual' e pode ou não ser aceitável, dependendo dos requisitos do seu aplicativo, mas significa que os commits de transação estão mais próximos de O (1) que O (n) no uso de recursos.

O compartilhamento exige que o cliente esteja ciente do particionamento de dados nos bancos de dados, geralmente usando um tipo de algoritmo conhecido como 'hash consistente'. Em um banco de dados fragmentado, o cliente faz o hash da chave para determinar em qual servidor do cluster emitir a consulta. Como as solicitações são distribuídas entre nós no cluster, não há gargalo com um único nó coordenador de consulta.

Essas técnicas permitem que um banco de dados seja escalado a uma taxa quase linear, adicionando nós ao cluster. Teoricamente, a replicação de quorum é necessária apenas se o meio de armazenamento subjacente for considerado não confiável. Isso é útil se os servidores comuns forem usados, mas terá menos valor se o mecanismo de armazenamento subjacente tiver seu próprio esquema de alta disponibilidade (por exemplo, uma SAN com controladores espelhados e conectividade de vários caminhos para os hosts).

Por exemplo, o BigTable do Google não implementa a Replicação de Quorum por si só, embora assente no GFS, um sistema de arquivos em cluster que usa replicação de quorum. O BigTable (ou qualquer sistema que não compartilha nada) pode usar um sistema de armazenamento confiável com vários controladores e particionar os dados entre os controladores. O acesso paralelo seria alcançado através do particionamento dos dados.

Voltar para plataformas RDBMS

Não há razão inerente para que essas técnicas não possam ser usadas com um RDBMS. No entanto, o gerenciamento de bloqueio e versão seria bastante complexo em um sistema desse tipo e qualquer mercado para esse sistema provavelmente será bastante especializado. Nenhuma das plataformas RDBMS convencionais usa replicação de quorum e não estou especificamente ciente de qualquer produto RDBMS (pelo menos não um com qualquer aceitação significativa) que o faça.

Os sistemas de disco compartilhado e nada compartilhado podem escalar cargas de trabalho muito grandes. Por exemplo, o Oracle RAC pode suportar 63 nós de processamento (que podem ser grandes máquinas SMP por si só) e um número arbitrário de controladores de armazenamento na SAN. Um IBM Sysplex (um cluster de mainframes do zSeries) pode suportar vários mainframes (cada um com capacidade de processamento substancial e largura de banda de E / S própria) e vários controladores SAN. Essas arquiteturas podem suportar volumes de transações muito grandes com semântica ACID, embora eles assumam armazenamento confiável. Teradata, Netezza e outros fornecedores criam plataformas analíticas de alto desempenho baseadas em projetos de compartilhamento de nada que escalam para volumes de dados extremamente grandes.

Até agora, o mercado de plataformas de baixo custo, mas ultra-altas e totalmente ACID RDBMS é dominado pelo MySQL, que suporta fragmentação e replicação multimestre. O MySQL não usa replicação de quorum para otimizar a taxa de transferência de gravação, portanto, as confirmações de transação são mais caras do que em um sistema NoSQL. O sharding permite taxas de transferência de leitura muito altas (por exemplo, o Facebook usa o MySQL extensivamente); portanto, esse tipo de arquitetura se adapta bem a cargas de trabalho com muita leitura.

Um debate interessante

BigTable é uma arquitetura de nada compartilhado (essencialmente um par de valor-chave distribuído), como apontado por Michael Hausenblas abaixo . Minha avaliação original incluiu o mecanismo MapReduce, que não faz parte do BigTable, mas normalmente seria usado em conjunto com ele em suas implementações mais comuns (por exemplo, Hadoop / HBase e a estrutura MapReduce do Google).

Comparando essa arquitetura com o Teradata, que possui afinidade física entre armazenamento e processamento (ou seja, os nós têm armazenamento local em vez de uma SAN compartilhada), você pode argumentar que BigTable / MapReduce é uma arquitetura de disco compartilhada por meio do sistema de armazenamento paralelo visível globalmente.

A taxa de transferência de processamento de um sistema de estilo MapReduce, como o Hadoop, é restringida pela largura de banda de um comutador de rede sem bloqueio. 1 Os switches sem bloqueio podem, no entanto, lidar com grandes agregados de largura de banda devido ao paralelismo inerente ao projeto, de modo que raramente são uma restrição prática significativa ao desempenho. Isso significa que uma arquitetura de disco compartilhado (talvez mais conhecida como sistema de armazenamento compartilhado) pode ser dimensionada para grandes cargas de trabalho, mesmo que o comutador de rede seja teoricamente um gargalo central.

O ponto original era observar que, embora esse gargalo central exista em sistemas de disco compartilhado, um subsistema de armazenamento particionado com vários nós de armazenamento (por exemplo, servidores de tablets BigTable ou controladores SAN) ainda pode escalar até grandes cargas de trabalho. Uma arquitetura de comutador sem bloqueio pode (em teoria) lidar com tantas conexões atuais quanto portas.

1 Obviamente, o processamento e a taxa de transferência de E / S disponíveis também constituem um limite no desempenho, mas o comutador de rede é um ponto central pelo qual todo o tráfego passa.

ConcernedOfTunbridgeWells
fonte
10
Épico. Bom trabalho, garoto.
Mark-Storey-Smith
8
Resposta incrível!
Philᵀᴹ
1
Uau, acho que você quase o cobriu por lá!
Mr.Brownstone
2
@ Michael Hausenblas Pensando bem, se você tomar o BigTable DB isoladamente, eu concordaria com a reivindicação de nada compartilhado. Confluí-lo com toda a pilha MapReduce / Hadoop (onde não há afinidade específica entre processamento e armazenamento) neste artigo. Você poderia razoavelmente argumentar a inadequação dessa fusão.
ConcernedOfTunbridgeWells
3
Algumas reflexões técnicas. De fato, a replicação de quorum é o que é feito na replicação de streaming do PostgreSQL para configurações de mestre / escravo. Os dados devem confirmar o mestre apenas por padrão, mas você também pode exigir que eles também sejam gravados em n escravos antes que o commit seja retornado.
22813 Chris Travers
21

Bancos de dados relacionais podem agrupar-se como soluções NoSQL. Manter propriedades ACID pode tornar isso mais complexo e é preciso estar ciente das compensações feitas para manter essas propriedades. Infelizmente, exatamente quais são as compensações dependem da carga de trabalho e, é claro, das decisões tomadas ao projetar o software do banco de dados.

Por exemplo, uma carga de trabalho principalmente de OLTP pode ter latência adicional de consulta única, mesmo que a taxa de transferência do cluster seja bem dimensionada. Essa latência extra pode passar despercebida ou pode ser um grande problema, dependendo da aplicação. Em geral, o armazenamento em cluster melhora a taxa de transferência e prejudica a latência, mas mesmo essa 'regra' é suspeita se as consultas de um aplicativo forem particularmente passíveis de processamento paralelo.

O que a empresa em que trabalho, Clustrix , oferece é uma série de nós de computação e armazenamento homogêneos conectados por uma rede de velocidade relativamente alta. Os dados relacionais são hash distribuídos pelos nós em uma base por índice em partes que chamamos de 'fatias'. Cada fatia terá duas ou mais réplicas espalhadas pelo cluster para maior durabilidade no caso de falha no nó ou no disco. Os clientes podem se conectar a qualquer nó no cluster para emitir consultas usando o protocolo de conexão MySQL.

É um pouco natural pensar nos componentes de um banco de dados ACID de forma independente, pois grande parte dele se encaixa, mas aqui vai:

Atomicidade - o Clustrix usa confirmações bifásicas para garantir a atomicidade. As operações UPDATE e DELETE também bloquearão linhas por meio de nosso gerenciador de bloqueios distribuídos, porque internamente transformamos essas operações em SELECT, seguidas pelas operações exatas UPDATE / DELETE.

A atomicidade obviamente aumenta a quantidade de mensagens entre os nós participantes de uma transação e aumenta a carga nesses nós para processar o protocolo de confirmação. Isso faz parte da sobrecarga de ter um sistema distribuído e limitaria a escalabilidade se todos os nós participassem de todas as transações, mas os nós só participariam de uma transação se eles tivessem uma das réplicas sendo gravadas.

Consistência - Chaves estrangeiras são implementadas como gatilhos, que são avaliadas no momento da confirmação. As operações UPDATE e DELETE de grande alcance podem prejudicar nosso desempenho devido ao bloqueio, mas felizmente não as vemos com tanta frequência. É muito mais comum ver uma transação atualizar / excluir algumas linhas e depois confirmar.

A outra parte da consistência é manter um quorum por meio do protocolo de consenso do PAXOS, o que garante que apenas os clusters com a maioria dos nós conhecidos possam realizar gravações. É claro que é possível que um cluster tenha quorum, mas ainda haja dados ausentes (todas as réplicas de uma fatia offline), o que causará falhas nas transações que acessam uma dessas fatias.

Isolamento - O Clustrix fornece isolamento de MVCC no nível do contêiner. Nossa atomicidade garante que todas as réplicas aplicáveis ​​recebam uma gravação específica antes de relatarmos a transação confirmada, principalmente reduzindo o problema de isolamento ao que você teria no caso sem cluster.

Durabilidade - Cada fatia de dados relacionais é armazenada em dois ou mais nós para fornecer resiliência em caso de falha no nó ou no disco. Provavelmente também vale a pena notar aqui que a versão do dispositivo do nosso produto possui uma placa NVRAM em que o WAL é armazenado por motivos de desempenho. Muitos bancos de dados de instância única melhorarão o desempenho de seus WALs, verificando os intervalos em vez de cada confirmação. Essa abordagem é problemática em um sistema distribuído porque faz 'repetição para onde?' uma pergunta complicada. Contornamos isso no aparelho, fornecendo uma garantia de durabilidade rígida.

Matt
fonte
2
Obrigado @Matt - este é exatamente o tipo de resposta que buscávamos. Como um aparte, eu concordaria que separar os componentes do ACID não é muito natural, pois encontrei algo semelhante ao escrever meu artigo. Mais uma vez, obrigado pelo seu tempo e teremos o maior prazer em receber mais contribuições de você e sua equipe.
precisa
14

A resposta fundamental é que o modelo de consistência é diferente. Estou escrevendo isso para expandir a resposta da ConcernedOfTunbridge, que realmente deve ser o ponto de referência para isso.

O ponto básico do modelo de consistência do ACID é que ele oferece várias garantias fundamentais quanto ao estado dos dados globalmente no sistema. Essas garantias estão sujeitas às limitações do teorema da CAP, o que significa, basicamente, que para fazê-las funcionar, é necessário ter todas as fontes autorizadas na mesma página antes de informar ao aplicativo que você cometeu uma transação. A replicação multimestre é, portanto, muito difícil de executar sem se deparar com essas restrições. Certamente, quando você começa a fazer replicação assíncrona em um ambiente multimestre, essas garantias são eliminadas. O modelo de consistência ACID é um modelo de consistência forte, destinado a informações importantes ou críticas.

O modelo de consistência BASE é um modelo de consistência fraca destinado a informações não críticas. Como as garantias são significativamente mais fracas, a capacidade de oferecer garantias tão fracas em sistemas multimestre é mais facilmente alcançável porque as garantias são, bem, fracas.

No entanto, os RDBMS podem escalar e fazer o mesmo que soluções NoSQL!

No entanto, há casos em que os RDBMS podem e podem escalar até uma extensão que o NoSQL pode nem ser capaz de corresponder. Isso é diferente. Examinarei o Postgres-XC como o exemplo de como a expansão é possível sem sacrificar fortes garantias de consistência.

A maneira pela qual esses RDBMSs específicos o fazem é implementar algo como uma solução de sharding com um proxy e um tipo de arquitetura de disco compartilhado, mas significativamente mais complexo do que qualquer um. Elas não são dimensionadas da mesma maneira que as soluções NoSQL e, portanto, as vantagens e desvantagens são diferentes.

Entendo, o modelo do Postgres-XC é inspirado no Teradata. Consiste em nós em duas funções diferentes, como nós de armazenamento ou coordenadores. Os coordenadores são multimestre (não há replicação real envolvida) e se conectam aos nós de armazenamento para lidar com o processamento de dados real. Os nós de armazenamento são replicados em uma configuração mestre-escravo. Cada nó de armazenamento contém o que é essencialmente um fragmento do banco de dados, mas os coordenadores mantêm uma imagem consistente dos dados.

Uma separação significativa de responsabilidades está envolvida aqui. Os nós de armazenamento gerenciam dados, verificam restrições, restrições de chave estrangeira aplicáveis ​​localmente e manipulam pelo menos alguma agregação de dados. Os coordenadores lidam com as chaves estrangeiras que não podem ser aplicadas localmente, bem como com as janelas e outras considerações de dados que podem extrair de vários nós de dados. Em essência, os coordenadores tornam o ACID possível em transações distribuídas em uma configuração multimestre em que o usuário nem sabe que as transações são distribuídas.

Nesse sentido, o Postgres-XC oferece algo parecido com as opções de dimensionamento do NoSQL, mas há uma complexidade adicional devido às garantias adicionais de consistência. Entendo que existem RDBMSs comerciais que oferecem esse tipo de escalabilidade por aí. Teradata faz isso. Além disso, os sistemas de disco compartilhado podem ser expandidos de maneira semelhante e o DB2 e o Oracle oferecem essas soluções. Portanto, é totalmente injusto dizer que os RDBMS não podem fazer isso. Eles podem. No entanto, a necessidade foi tão pequena no passado que as economias de escala foram insuficientes para tornar as soluções proprietárias muito acessíveis para a maioria dos participantes.

Finalmente, uma nota sobre o VoltDB. Como as soluções NoSQL, vejo o VoltDB como uma ferramenta muito especializada. É muito rápido, mas às custas de transações de ida e volta e durabilidade no disco. Isso significa que você tem um conjunto muito diferente de preocupações. O VoltDB é o que você obtém quando os pioneiros do RDBMS criam uma solução NoSQL ;-). O VoltDB é rápido em parte porque define simultaneidade e durabilidade da equação. A durabilidade se torna uma propriedade de rede, não uma propriedade intra-host e a simultaneidade é gerenciada executando consultas uma por vez, paralelamente internamente, em ordem seqüencial. Não é um RDBMS tradicional (e isso é bom, já que ele pode ir a lugares que o RDBMS tradicional não pode, mas o inverso também é verdadeiro).

Editar: Também é importante considerar a implicação de junções. Em sistemas em cluster, as junções se tornam um problema de desempenho muito diferente. Se tudo estiver no mesmo nó, eles podem melhorar o desempenho, mas se você precisar fazer uma viagem de ida e volta para um nó diferente, isso impõe um custo muito alto. Portanto, os modelos de dados fazem diferenças e a abordagem de cluster tem impactos no desempenho. Abordagens como o Postgres-XC e o Postgres-XL pressupõem que você pode gastar um bom tempo pensando sobre as coisas, para que você possa compartilhar seus dados adequadamente e manter os dados unidos. Mas isso impõe sobrecarga de design. Por outro lado, isso é muito melhor do que muitas soluções NoSQL e pode ser ajustado adequadamente. Por exemplo, nós (no Adjust) usamos uma estratégia de agrupamento semelhante ao NoSQL para nossos 3,5 PB de dados no PostgreSQL que é basicamente análise de log. E muito do nosso design é profundamente inspirado pelas estratégias de cluster NoSQL. Às vezes, o modelo de dados também restringe o modelo de cluster.

Chris Travers
fonte
6

Minha resposta não será tão bem escrita quanto a anterior, mas aqui vai.

Michael Stonebraker, da Ingres fame, criou um armazenamento de colunas MPP (nada compartilhado) (Vertica) e um banco de dados New SQL (VoltDB) MPP que nada compartilhou, que distribui dados entre nós diferentes em um cluster e mantém o ACID. Vertica já foi comprada pela HP.

Acredito que outros bancos de dados New SQL também mantenham o ACID, embora não tenha certeza de quantos deles distribuem suas linhas por um cluster, etc.

Aqui está uma palestra que Stonebraker deu sobre o New SQL em relação ao NoSQL e "Old SQL". http://www.youtube.com/watch?v=uhDM4fcI2aI

geoffrobinson
fonte
2
O que é esse "New SQL" e "Old SQL"? Gostaria de esclarecer?
ypercubeᵀᴹ
1
"Old SQL" seria SQL Server, Oracle, MySQL, PostgreSQL, etc. Aqui está a definição da Wikipedia para NewSQL que é bastante boa: "NewSQL é uma classe de sistemas modernos de gerenciamento de banco de dados relacional que buscam fornecer o mesmo desempenho escalável do NoSQL sistemas para cargas de trabalho OLTP, mantendo as garantias ACID de um sistema tradicional de banco de dados de nó único ". Eu recomendo o vídeo que publiquei se estiver interessado em aprender mais.
geoffrobinson
Como observação aqui, e como expliquei em minha resposta, o VoltDB lida com escalabilidade definindo durabilidade e simultaneidade fora da equação. Em essência, com o VoltDB, você não obtém durabilidade intra-sistema nem acesso simultâneo aos dados. O novo SQL é como um carro de corrida Indie 500, mas o Old SQL ainda é o caminhão semi ou talvez o motor do trem de carga.
Chris Travers
1

O clustering do MySQL pode fragmentar usando a replicação multi-masterização e hash shards pelo cluster.

Jeremy Singer
fonte