Apache Cassandra: Modelando os dados de sua aplicação NoSQL

Aprenda nesse artigo como organizar os dados de suas aplicações Java para persistência no Apache Cassandra

Fique por dentro
O Apache Cassandra é um dos melhores bancos de dados de arquitetura distribuída, principalmente para projetos de Big Data, nos quais se espera alta disponibilidade, escalabilidade linear e capacidade de operar em múltiplos centros de processamento simultaneamente, como um único repositório de dados.

Devido a essas características, esta solução NoSQL está sendo adotada cada vez mais em sistemas de escala global, que requerem uma distribuição geográfica em várias localidades. Entre esses sistemas, estão os de processamento de transações online de larga escala, como ocorre com a loja virtual da Amazon.

Os tradicionais bancos de dados relacionais não lidam tão bem com os requisitos de sistemas dessa magnitude. Apesar disso, no exterior, assim como no Brasil, o Cassandra não é tão popular quanto os bancos relacionais, mas tem sido reconhecido como um banco promissor, capaz de ocupar um espaço que as soluções padrão não atendem com excelência. Sabendo disso, vamos explorar esse assunto neste artigo, abordando primeiramente um ponto fundamental: a modelagem de dados para o Cassandra.

Atualmente, grande parte dos sistemas já opera através da Internet. Como consequência disso, eleva-se a quantidade potencial de usuários e passa-se a expor as limitações das tecnologias tradicionais.

Em muitos casos essa exposição se deu pelo fato dos sistemas terem apresentado um crescimento bastante elevado do número de acessos, o que culminou em um aumento exponencial do volume de dados a tal ponto que os bancos relacionais passaram a ter dificuldades em processar as requisições com um tempo de resposta satisfatório.

A solução, então, seria escalar o banco de dados verticalmente, adicionando mais recursos de hardware numa mesma máquina, de forma a garantir um desempenho aceitável para o sistema.

Entretanto, os custos com isso podem se tornar proibitivos, assim como em algum momento o limite dessa escalabilidade pode ser alcançado. Diante disso, os bancos de dados relacionais se tornaram um gargalo na arquitetura desses sistemas.

Essas limitações fizeram com que os pesquisadores buscassem alternativas para melhorar o desempenho e, a partir daí, criaram opções de replicação de dados dos bancos relacionais em vários nós (mestre-escravo, mestre-mestre) e os particionamentos vertical e horizontal.

Dessa forma, foi criada a possibilidade de se escalar horizontalmente um banco de dados relacional. Entretanto, os pesquisadores notaram que para grandes volumes de dados, o custo de se manter uma estrutura de hardware para escalar horizontalmente de forma satisfatória era proibitivo.

Esse elevado custo se dava por conta das características ACID (Atomicidade, Consistência, Integridade e Disponibilidade) do banco de dados. Para garantir essas propriedades, o banco terminava por fazer pesquisas em todos os nós do cluster de dados a fim de realizar as operações de JOIN, precisava fazer leituras (muitas vezes em vários nós) antes de escrever ou atualizar os dados, entre outros detalhes.

Todo esse comportamento levou a um custo muito alto para se realizar consultas, aumentando o tempo das mesmas de tal forma que se tornaram inviáveis. Nesse momento, negócios que necessitavam de respostas rápidas, principalmente os de operações críticas, começaram a sofrer com essas dificuldades e tiveram que buscar alternativas.

A opção que se encontrou foi baseada no teorema de CAP, o qual conceitua que é impossível, para um sistema distribuído, garantir as características de consistência (só existe um único valor em todo o cluster para um mesmo registro), disponibilidade (é possível executar operações com sucesso a qualquer momento/tempo razoável) e tolerância a falhas (sistema continua a operar mesmo se um nó tiver falha de rede).

Portanto, só é possível construir sistemas distribuídos que atendam a no máximo duas das características do teorema de CAP, sendo necessário, portanto, flexibilizar as regras de armazenamento de dados em troca de maior escalabilidade e performance.

Esse conceito é válido até mesmo para os bancos de dados relacionais, quando se opta por escalá-los horizontalmente, pois se houver falha de rede em algum nó, algumas consultas podem não ser executadas.

Obviamente, com o aumento do volume de dados, se faz necessário escalonar horizontalmente, a fim de aumentar a capacidade de processamento e armazenamento, diminuir custos (nós simples em vez de máquinas poderosas) e aumentar a disponibilidade.

Essa necessidade fez com que surgissem os bancos de dados NoSQL, como o Cassandra, o qual faz uso do conceito de consistência eventual, garantindo apenas a disponibilidade e tolerância a falhas.

A consistência eventual significa que se nenhuma atualização for feita a um registro a partir de determinado momento, eventualmente, ou seja, quando todas as atualizações anteriores tiverem sido replicadas em todos os nós do cluster, todos os acessos àquele registro retornarão o valor mais atualizado.

O problema é que antes que o dado mais atualizado esteja disponível em todos os nós do cluster de dados, não necessariamente o valor retornado a uma consulta será o mais atualizado, pois a replicação dos dados demora um certo tempo para ocorrer, criando uma janela de inconsistência.

Por exemplo, se um cluster Cassandra possui três nós e houver uma atualização em um registro trocando a letra “A” por “B”, enquanto o valor B não for atualizado em todos os nós, uma consulta pode consultar um nó em que o valor ainda seja “A” (a escolha do nó é aleatória), pois a replicação não terminou, ocasionando uma inconsistência.

O Cassandra possui formas de contornar essa limitação ao possibilitar a configuração do nível de consistência. Entretanto, não chega a garantir a consistência, como nos sistemas relacionais.

Dessa forma, esta solução NoSQL é a melhor opção para situações em que se tenha um grande volume de dados, necessite de alta disponibilidade, tolerância a falhas e que não seja necessário trabalhar sempre com o dado mais recente.

Um bom exemplo de aplicação que pode tirar proveito dessa característica é o carrinho de compras da Amazon. O modelo de negócio da empresa assume que é melhor pedir desculpa ao usuário por um eventual erro, no caso de qualquer inconsistência (nos dados, compra efetuada de forma errada, falha na compra, etc.), do que arcar com os custos de garantir a consistência com um banco de dados relacional.

Quando ocorre esse tipo de situação, a empresa pede desculpas e oferece uma série de vantagens ao cliente, como bons descontos em produtos ou créditos para serem gastos na loja. Dessa forma, além de incentivar uma nova compra, a empresa tem o custo de operação diminuído significativamente ao adotar essa estratégia. O “custo” dos incentivos aos clientes que passaram pelo problema é diluído pelo maior volume de compras que o sistema pode lidar.

Além disso, existem vários casos de sucesso da utilização do Cassandra, em vários ramos de negócio, como, por exemplo: catálogo de produtos, redes sociais, detecção de fraudes e aplicações analíticas no geral. Devido a isso, tem sido adotado por milhares de empresas de diferentes áreas, como a Amazon (comércio eletrônico), eBay (comércio eletrônico), Netflix (serviço de assinatura de filmes e séries de TV), Facebook (rede social), CERN (centro de pesquisa nuclear), FedEx (logística), Globo.com (portal de notícias), Microsoft (software), Credit Suisse (banco de investimento) e até mesmo a NASA (agência espacial estadunidense).

Como era de se esperar, o Cassandra não foi escolhido por acaso. Ele é altamente escalável, possui uma arquitetura P2P tolerante a falhas, um modelo de dados versátil e flexível e uma linguagem de consulta com baixa curva de aprendizado. Todas essas características fazem com que o Cassandra seja o repositório perfeito para aplicações que precisam estar sempre disponíveis e que operam com grandes volumes de escrita e leitura de dados. Com esta solução NoSQL é possível atender a milhões de transações por segundo, em grandes volumes de dados, fazendo uso de milhares de servidores.

No entanto, um dos grandes desafios que novos projetos encontram ao adotar o Apache Cassandra é que a modelagem de dados é bem diferente. As abordagens tradicionais se baseiam em bancos relacionais e já possuem uma metodologia bem estabelecida, fruto de décadas de pesquisas.

Por sua vez, por ter uma abordagem diferente e recente, existem poucas metodologias para a modelagem de dados não-relacionais. A primeira tentativa e a mais utilizada até o momento, foi criada por três pesquisadores da Wayne State University, entre os quais se destaca Artem Chebotko, arquiteto de soluções da DataStax, uma empresa de software que fornece uma versão comercial do Apache Cassandra. Essa abordagem que será demonstrada ao longo deste artigo.

O processo de modelagem relacional é bastante focado nos dados, pois procura entender e organizar os dados de forma relacionada, de tal forma a minimizar a redundância e duplicação dos mesmos. Além disso, as consultas feitas ao banco de dados, a princípio, não interferem no processo de modelagem, ou seja, não se modela pensando nas consultas que a aplicação deseja fazer. " [...] continue lendo...

Artigos relacionados