Você está na página 1de 206

Banco de Dados

para Big Data


Prof. Geomar André Schreiner

Indaial – 2020
1a Edição
Copyright © UNIASSELVI 2020

Elaboração:
Prof. Geomar André Schreiner
Prof. Daniel dos Santos Brandão
Prof. Fabiano Berlinck Neumann
Prof.ª Mariana Araújo Pereira

Este livro foi feito com a parceira com a Sagah

Revisão, Diagramação e Produção:


Centro Universitário Leonardo da Vinci – UNIASSELVI

Ficha catalográfica elaborada na fonte pela Biblioteca Dante Alighieri


UNIASSELVI – Indaial.

S378b

Schreiner, Geomar André

Banco de dados para big data. / Geomar André Schreiner. – Indaial:


UNIASSELVI, 2020.
206 p.; il.
ISBN 978-65-5663-123-3
ISBN Digital 978-65-5663-117-2
1. Big data. - Brasil. 2. Banco de dados. – Brasil. Centro Universitário
Leonardo Da Vinci.

CDD 004

Impresso por:
Apresentação
Caro acadêmico!

No decorrer deste material exploraremos as diferentes facetas dos


problemas e soluções para armazenar e manipular grandes quantidades de
dados. Consideramos Big Data uma grande quantidade de dados que são
acessadas ou inseridas constantemente por diversas fontes. Bancos de Dados
Relacionais são utilizados há décadas para armazenar e consultar dados de
maneira segura e confiável. No entanto, com o surgimento do Big Data, os
bancos de dados relacionais foram colocados em xeque, já que foram desen-
volvidos em um contexto de armazenamento diferente e não são adequados
para os novos requisitos que tais dados exigem.

Dessa forma, é natural que novas soluções emergissem para tratar


de problemas que o modelo relacional de dados não é mais capaz de tratar.
Nesse sentido, esses novos modelos surgem com o intuito de tratar proble-
mas que o modelo de dados relacional não é adequado para tratar, e não para
substituir esses BDs. Vários novos BDs foram surgindo nos últimos anos,
assim como arquiteturas capazes de lidar com as características do Big Data.
Neste livro didático, estudaremos as características dessas novas soluções
para entendermos quando e como devemos utilizá-las.

O livro de Banco de Dados para Big Data está dividido em três unida-
des. A Unidade 1 apresenta conceitos gerais sobre bancos de dados NoSQL
(Not Only SQL), a descrição das principais famílias, bem como a descrição de
cada uma delas. Na Unidade 2, estudaremos o papel do particionamento de
dados e das arquiteturas distribuídas frente aos desafios impostos por cená-
rios de Big Data. Por fim, a Unidade 3 apresenta o conceito de sharding e seu
papel na distribuição e processamento de dados semiestruturados.

Aproveitamos a oportunidade para destacar a importância de desen-


volver as autoatividades, lembrando que essas atividades não são opcionais.
Elas objetivam a fixação dos conceitos apresentados. Em caso de dúvida na
realização das atividades, sugerimos que você entre em contato com seu tu-
tor externo ou com a tutoria interna da UNIASSELVI, não prosseguindo as
atividades sem ter sanado todas as dúvidas que irão surgindo.

Bons estudos!

III
NOTA

Você já me conhece das outras disciplinas? Não? É calouro? Enfim, tanto para
você que está chegando agora à UNIASSELVI quanto para você que já é veterano, há
novidades em nosso material.

Na Educação a Distância, o livro impresso, entregue a todos os acadêmicos desde 2005, é


o material base da disciplina. A partir de 2017, nossos livros estão de visual novo, com um
formato mais prático, que cabe na bolsa e facilita a leitura.

O conteúdo continua na íntegra, mas a estrutura interna foi aperfeiçoada com nova
diagramação no texto, aproveitando ao máximo o espaço da página, o que também
contribui para diminuir a extração de árvores para produção de folhas de papel, por exemplo.

Assim, a UNIASSELVI, preocupando-se com o impacto de nossas ações sobre o ambiente,


apresenta também este livro no formato digital. Assim, você, acadêmico, tem a possibilidade
de estudá-lo com versatilidade nas telas do celular, tablet ou computador.
 
Eu mesmo, UNI, ganhei um novo layout, você me verá frequentemente e surgirei para
apresentar dicas de vídeos e outras fontes de conhecimento que complementam o assunto
em questão.

Todos esses ajustes foram pensados a partir de relatos que recebemos nas pesquisas
institucionais sobre os materiais impressos, para que você, nossa maior prioridade, possa
continuar seus estudos com um material de qualidade.

Aproveito o momento para convidá-lo para um bate-papo sobre o Exame Nacional de


Desempenho de Estudantes – ENADE.
 
Bons estudos!

IV
V
LEMBRETE

Olá, acadêmico! Iniciamos agora mais uma disciplina e com ela


um novo conhecimento.

Com o objetivo de enriquecer seu conhecimento, construímos, além do livro


que está em suas mãos, uma rica trilha de aprendizagem, por meio dela você terá
contato com o vídeo da disciplina, o objeto de aprendizagem, materiais complementares,
entre outros, todos pensados e construídos na intenção de auxiliar seu crescimento.

Acesse o QR Code, que levará ao AVA, e veja as novidades que preparamos para seu estudo.

Conte conosco, estaremos juntos nesta caminhada!

VI
Sumário
UNIDADE 1 - BANCOS NOSQL............................................................................................................1

TÓPICO 1 - BANCOS NOSQL................................................................................................................3


1 INTRODUÇÃO........................................................................................................................................3
2 MOTIVAÇÃO...........................................................................................................................................3
3 MODELOS DE DADOS.........................................................................................................................9
RESUMO DO TÓPICO 1........................................................................................................................12
AUTOATIVIDADE..................................................................................................................................13

TÓPICO 2 - BANCOS CHAVE-VALOR...............................................................................................15


1 INTRODUÇÃO......................................................................................................................................15
2 MODELO DE DADOS E ARQUITETURA......................................................................................15
3 ATIVIDADE PRÁTICA REDIS...........................................................................................................20
RESUMO DO TÓPICO 2........................................................................................................................25
AUTOATIVIDADE..................................................................................................................................26

TÓPICO 3 - BANCOS ORIENTADOS A DOCUMENTOS.............................................................27


1 INTRODUÇÃO......................................................................................................................................27
2 MODELO DE DADOS E ARQUITETURA......................................................................................28
3 ATIVIDADE PRÁTICA MONGODB................................................................................................37
RESUMO DO TÓPICO 3........................................................................................................................42
AUTOATIVIDADE..................................................................................................................................43

TÓPICO 4 - BANCOS ORIENTADOS A COLUNAS.......................................................................45


1 INTRODUÇÃO......................................................................................................................................45
2 MODELO DE DADOS E ARQUITETURA......................................................................................46
3 ATIVIDADE PRÁTICA CASSANDRA............................................................................................52
RESUMO DO TÓPICO 4........................................................................................................................56
AUTOATIVIDADE..................................................................................................................................57

TÓPICO 5 - BANCOS ORIENTADOS A GRAFOS...........................................................................59


1 INTRODUÇÃO......................................................................................................................................59
2 MODELO DE DADOS E ARQUITETURA......................................................................................60
3 ATIVIDADE PRÁTICA NEO4J..........................................................................................................64
RESUMO DO TÓPICO 5........................................................................................................................74
AUTOATIVIDADE..................................................................................................................................75

UNIDADE 2 - PARTICIONAMENTO DE BANCO DE DADOS...................................................77

TÓPICO 1 - PARTICIONAMENTO DE DADOS..............................................................................79


1 INTRODUÇÃO......................................................................................................................................79
2 DESAFIOS DO BIG DATA..................................................................................................................79
3 LIMITAÇÕES DO PARTICIONAMENTO DE DADOS...............................................................81
4 BENEFÍCIOS DO PARTICIONAMENTO DE DADOS................................................................83

VII
5 GERENCIAMENTO DE PARTICIONAMENTO............................................................................84
6 DESAFIOS DO PARTICIONAMENTO DE DADOS....................................................................86
7 ESTRATÉGIA DE PARTIÇÃO............................................................................................................87
RESUMO DO TÓPICO 1........................................................................................................................89
AUTOATIVIDADE..................................................................................................................................90

TÓPICO 2 - APLICAÇÕES SIMPLES UTILIZANDO FRAMEWORKS DE BIG DATA...........93


1 INTRODUÇÃO......................................................................................................................................93
2 FUNCIONAMENTO DO MAPREDUCE..........................................................................................93
3 INTERFACES PARA UTILIZAÇÃO DO HADOOP MAPREDUCE...........................................95
4 CONCEITO DO CONTADOR DE PALAVRAS COM MAPREDUCE.......................................96
5 APLICAÇÃO COM O HADOOP MAPREDUCE............................................................................97
6 APLICAÇÃO COM O MAPREDUCE NO SPARK.......................................................................100
RESUMO DO TÓPICO 2......................................................................................................................103
AUTOATIVIDADE................................................................................................................................104

TÓPICO 3 - OVERVIEW DE FRAMEWORKS DE STREAM DE BIG DATA............................105


1 INTRODUÇÃO....................................................................................................................................105
2 CONHECENDO O SPARK STREAMING.....................................................................................105
3 FLUXOS DISCRETIZADOS (DSTREAMS)...................................................................................107
4 SPARK STREAMING E OUTROS FRAMEWORKS....................................................................109
4.1. SPARK STREAMING E SPARK STRUCTURED STREAMING..............................................109
4.2. SPARK STREAMING, APACHE FLINK E APACHE STORM................................................110
5 INGESTÃO DE DADOS COM O SPARK STREAMING EM JAVA.........................................112
6 ETAPAS PARA CRIAR UM PROGRAMA COM SPARK STREAMING.................................112
RESUMO DO TÓPICO 3......................................................................................................................117
AUTOATIVIDADE................................................................................................................................118

TÓPICO 4 - FRAMEWORKS DE ARMAZENAMENTO NÃO ESTRUTURADOS..................119


1 INTRODUÇÃO....................................................................................................................................119
2 ECOSSISTEMA HADOOP E HDFS................................................................................................119
3 ARQUITETURA...................................................................................................................................120
4 TOLERÂNCIA A FALHAS................................................................................................................121
5 ARMAZENAMENTO EM NUVEM.................................................................................................122
5.1. AMAZON S3..................................................................................................................................123
5.2 MICROSOFT AZURE STORAGE.................................................................................................124
5.3 GOOGLE CLOUD STORAGE.......................................................................................................125
5.4 IBM CLOUD STORAGE................................................................................................................125
6 HDFS ON-PREMISE E ARMAZENAMENTO EM NUVEM......................................................126
7 OPERAÇÕES SOBRE DADOS NÃO ESTRUTURADOS...........................................................128
RESUMO DO TÓPICO 4......................................................................................................................130
AUTOATIVIDADE................................................................................................................................131

UNIDADE 3 - DADOS SEMI-ESTRUTURADOS E SHARDING................................................133

TÓPICO 1 - FRAMEWORKS DE ARMAZENAMENTO SEMIESTRUTURADOS..................135


1 INTRODUÇÃO....................................................................................................................................135
2 CARACTERÍSTICAS DOS BANCOS DE DADOS NoSQL.......................................................135
3 ONDE GUARDAR DOCUMENTOS E GRAFOS.........................................................................137
4 OPERAÇÕES COM DADOS SEMIESTRUTURADOS...............................................................140
RESUMO DO TÓPICO 1......................................................................................................................144
AUTOATIVIDADE................................................................................................................................145

VIII
TÓPICO 2 - SHARDING.......................................................................................................................147
1 INTRODUÇÃO....................................................................................................................................147
2 O QUE É SHARDING?.......................................................................................................................147
3 UTILIZANDO SHARDING EM CLUSTERS................................................................................151
3.1 CLUSTER LOCAL E REMOTO....................................................................................................153
3.2 RELAÇÃO ENTRE SHARDING E ÍNDICES.............................................................................154
3.3 UTILIZANDO ÍNDICES EM BANCOS DE DADOS.................................................................155
RESUMO DO TÓPICO 2......................................................................................................................158
AUTOATIVIDADE................................................................................................................................159

TÓPICO 3 - FRAMEWORKS QUE UTILIZAM SHARDING COMO


FORMA DE DISTRIBUIÇÃO.......................................................................................161
1 INTRODUÇÃO....................................................................................................................................161
2 ARQUITETURA DO SHARDING...................................................................................................161
3 SHARDING BASEADO EM HASH................................................................................................164
4 SHARDING BASEADO EM INTERVALOS..................................................................................165
5 SHARDING BASEADO EM DIRETÓRIO....................................................................................165
6 FRAGMENTAÇÃO NO APACHE CASSANDRA........................................................................166
7 HASH CONSISTENTE.......................................................................................................................168
8 FRAGMENTAÇÃO NO MONGODB.............................................................................................170
RESUMO DO TÓPICO 3......................................................................................................................185
AUTOATIVIDADE................................................................................................................................186
REFERÊNCIAS........................................................................................................................................189

IX
X
UNIDADE 1

BANCOS NOSQL

OBJETIVOS DE APRENDIZAGEM
A partir do estudo desta unidade, você deverá ser capaz de:

• conhecer a motivação para o surgimento dos Banco de Dados (BDs) NoSQL;

• caracterizar de maneira geral os BDs NoSQL e suas principais diferenças para


o modelo relacional;

• apresentar os diferentes modelos de BDs NoSQL;

• dialogar sobre os diferentes modelos de dados de BDs NoSQL e suas


aplicações.

PLANO DE ESTUDOS
Esta unidade está dividida em cinco tópicos. No decorrer da unidade
você encontrará autoatividades com o objetivo de reforçar o conteúdo
apresentado.

TÓPICO 1 – BANCOS NOSQL

TÓPICO 2 – BANCOS CHAVE-VALOR

TÓPICO 3 – BANCOS ORIENTADOS A DOCUMENTOS

TÓPICO 4 – BANCOS ORIENTADOS A COLUNAS

TÓPICO 5 – BANCOS ORIENTADOS A GRAFOS

CHAMADA

Preparado para ampliar seus conhecimentos? Respire e vamos


em frente! Procure um ambiente que facilite a concentração, assim absorverá
melhor as informações.

1
2
UNIDADE 1
TÓPICO 1

BANCOS NOSQL

1 INTRODUÇÃO
Os Bancos de Dados (BDs) sempre tiveram um lugar de destaque em se
tratando de sistemas da computação, porém, atualmente, com as grandes quan-
tidades de dados a serem armazenados (Big Data), os BDs ganham ainda mais
destaque (STONEBRAKER, 2012). Praticamente, todas as aplicações acessadas
utilizam algum meio de armazenamento de dados. Durante décadas, os dados fo-
ram armazenados através do modelo relacional de dados. Com o surgimento da
Web e a popularização da internet, cada vez mais pessoas utilizam as aplicações
de maneira on-line, trazendo à tona os limites do modelo relacional.

Com essa motivação foram surgindo novos modelos de dados com foco
na grande escalabilidade e alta disponibilidade dos sistemas, criando um novo
paradigma de armazenamento de dados (CATTELL, 2011). Esse novo paradigma
de armazenamento foi batizado de NoSQL (Not Only SQL). Esses BDs não se-
guem o modelo de dados relacional, propondo novas formas de armazenamento
(BERMAN, 2013).

No decorrer desta unidade, iremos explorar o paradigma de BDs não rela-


cionais, apresentando de maneira mais detalhada a motivação para o surgimento
desses novos BDs. Desse modo, suas principais características serão exploradas e
comparadas com as do já conhecido modelo relacional de armazenamento. Além
disso, serão apresentados os novos modelos de dados e quais as principais carac-
terísticas de cada um deles.

2 MOTIVAÇÃO
Em geral, BDs relacionais são utilizados há décadas em grande escala
para o armazenamento e manipulação eficiente dos mais variados domínios de
aplicação (SADALAGE; FOWLER, 2019). O modelo relacional de dados foi pro-
posto por Edward Codd em 1970. Nesse sentido, o modelo de dados relacional é
baseado em uma abstração sobre os dados que definem uma estrutura de entida-
des (tabelas) e seus relacionamentos.

Como você já deve saber, grande parte do sucesso do modelo relacional


deve-se à padronização imposta por ele e de sua poderosa linguagem de consul-
tas: a SQL (Structured Query Language) (SILBERSCHATS; KORTH; SUDARSHAN,
2012). A linguagem SQL é baseada na teoria de conjuntos e permite que o usuário

3
UNIDADE 1 | BANCOS NOSQL

manipule os dados a fim de obter os resultados desejados. Graças ao modelo de


dados relacional e à SQL, todos os BDs relacionais compartilham diversas carac-
terísticas. Dessa forma, aprendendo os fundamentos sobre o modelo relacional e
a SQL somos capazes de utilizar as ferramentas de qualquer Sistema Gerenciador
de Banco de Dados (SGBD) relacional. Cada SGBD possui suas peculiaridades e
seu dialeto de SQL, porém, como dito, todos possuem uma mesma base.

Outra característica importante do modelo relacional, compartilhada pe-


los SGBDs, é a possibilidade de o usuário executar transações. Uma transação
é uma série de operações consideradas críticas que devem ser executadas com
um bloco único e indivisível (bloco atômico) (SILBERSCHATS; KORTH; SUDAR-
SHAN, 2012). Essas operações devem ser executadas em sua totalidade. Assim,
caso algum erro ocorra durante a execução uma transação, esta deve falhar e as
operações que já haviam sido executadas com êxito devem ser desfeitas.

Imagine a seguinte situação: você está sacando seu dinheiro de um caixa


eletrônico. A operação de saque é uma transação que será executada no sistema do
seu banco, que possivelmente é um BD relacional. Você passa algumas informações
e, através delas, algumas operações serão executas para que o caixa eletrônico lhe
dê seu dinheiro. De maneira geral, o sistema executará as seguintes operações:
(i) validar suas informações pessoais (conta, agência e senha);
(ii) verificar seu saldo;
(iii) se o saldo for suficiente, reduzir o montante do saque do saldo atual;
(iv) salvar o novo saldo;
(v) efetivar o saque liberando o dinheiro.

Agora, imagine que entre os passos (iv) e (v) falte energia, desse modo, a
transação teria retirado o dinheiro do saque de sua conta, porém o caixa eletrônico
não iria mais liberar o dinheiro já que a transação terminou. Erros desse tipo
não podem ser tolerados em uma instituição financeira, bem como em outras
aplicações. Dessa forma, todo banco relacional deve possuir suporte às transações
compatíveis com as propriedades ACID (Atomicidade, Consistência, Isolamento
e Durabilidade) (SILBERSCHATS; KORTH; SUDARSHAN, 2012).

Cada uma das propriedades ACID garantem que o comportamento das


transações em um BD relacional seja sempre o mesmo (ABADI, 2009). Cada letra
da sigla ACID tem o seguinte significado:

• A: a propriedade de atomicidade deve garantir que a transação seja executada


como um todo, ou seja, caso exista uma falha, as operações executadas devem
ser desfeitas (rollback).
• C: a consistência assegura que os dados respeitem as restrições de integridade
criadas pelo usuário (tipos de dados, chaves primárias, chaves estrangeiras,
entre outras).
• I: o isolamento garante que as transações sejam executadas em paralelo, sem
que nenhuma afete a execução da outra, normalmente essa propriedade é im-
plementada através de locks e latches.

4
TÓPICO 1 | BANCOS NOSQL

• D: a propriedade de durabilidade diz respeito ao armazenamento efetivo das


informações, ou seja, o resultado das operações da transação deve ter sido ar-
mazenado no disco para que a transação seja efetivada.

E
IMPORTANT

Locks e Latches são importantes mecanismos de controle dos Bancos de


Dados. Locks são estruturas lógicas utilizadas pelo SGBD para manter a consistência entre
transações, não permitindo que duas transações escrevam o mesmo dado. Latches são
bloqueios criados sobre estruturas de dados físicas armazenadas no disco.

As propriedades ACID são um dos principais atrativos dos BDs relacio-


nais, porém elas acarretam em processamento extra. Por exemplo, a propriedade
de atomicidade necessita de logs e outros mecanismos para permitir, caso ne-
cessário, que o sistema realize um rollback. Já a propriedade isolamento acarreta
operações de locks, que deixam outras transações (usuários) esperando sua vez
para acessar aos recursos.

Os BDs Relacionais foram criados, como vimos, há décadas e sua essên-


cia continua a mesma. Ao longo dos anos, o paradigma foi sendo modificado,
algoritmos melhorados e novas funcionalidades foram sendo desenvolvidas. No
entanto, sua arquitetura com crescimento vertical (para melhorar o sistema, deve
ser melhorado o hardware) e operações baseadas em disco (todas as transações
dependem da gravação no disco para obterem êxito) permanecem inalteradas
(STONEBRAKER, 2012).

Com o surgimento da Web, muitas demandas mudaram. Atualmente,


muitas aplicações necessitam lidar com grandes quantidades de dados que,
geralmente, caracterizam-se por serem heterogêneos e não possuírem um es-
quema bem definido. Esses dados são comumente denominados de Big Data
(BERNAN, 2013).

Em termos gerais, Big Data são grandes quantidades de dados gerados


com certa velocidade por fontes diferente, esse conceito será melhor descrito na
Unidade 3. Apesar de os BDs relacionais serem usados há décadas como meio
seguro de armazenamento, eles se mostram ineficientes para o gerenciamento
de Big Data (STONEBRAKER, 2012). Isso se deve principalmente pelo compro-
metimento do desempenho com verificações de consistência dos dados, proces-
samento de consultas complexas, manutenção das propriedades ACID, entre
outras, e a representação rígida e estruturada dos dados através de esquemas
(ABADI, 2009).

5
UNIDADE 1 | BANCOS NOSQL

Dessa forma, para suprir os requisitos impostos pelo processamento de


Big Data, novas arquiteturas de BDs foram propostas (STONEBRAKER, 2012).
Geralmente, essas novas arquiteturas utilizam recursos de alta disponibilidade
e escalabilidade atrelados ao paradigma da computação na nuvem, paradigma
baseado na capacidade de processamento e armazenamento de grandes volumes
de dados por centros distribuídos geograficamente (ABOUZEID, 2009).

A quantidade de dados gerados, armazenados e processados atingiu es-


calas inéditas com a Web 2.0, a partir disso nasceram os chamados BDs NoSQL
(DIANA; GEROSA, 2010). Perceba que estamos falando em um contexto especí-
fico, todas as aplicações, pelo menos a maioria, utilizavam o modelo relacional
de dados, conforme o volume e a variedade dos dados foi aumentando, o mo-
delo relacional começou a apresentar alguns problemas dada sua natureza de
processamento.

Os desenvolvedores começaram a questionar o uso de uma estrutura tão


rígida para o armazenamento de dados, sendo que algumas aplicações não neces-
sitam dessa rigidez. Aliado a isso, ainda temos o fato de que a escalabilidade do
modelo relacional é baseada no crescimento vertical (escalonamento vertical), ou
seja, a melhora do desempenho do SGBD pode ser efetuada acrescentando mais
recursos ao servidor, o que torna o processo caro.

NOTA

Escalabilidade horizontal: consiste em adicionar uma nova máquina no clus-


ter, visando aumentar a capacidade do sistema distribuído.

Escalabilidade vertical: trata-se do upgrade em um servidor já existente na rede, podendo ser


a substituição, a reposição ou a adição de novos recursos, como memória ou discos rígidos.

FONTE: <https://bit.ly/2X5p0uD>. Acesso em: 28 mar. 2020.

Considerando os pontos falhos dos BD relacionais, os BDs NoSQL


foram propostos como BDs essencialmente distribuídos, que são baseados no
crescimento horizontal (escalonamento horizontal). Desse modo, para melhorar
o desempenho do sistema, o usuário pode adicionar máquinas ao conjunto que
compõe o BD (cluster).

Na construção do cluster, máquinas um pouco mais antigas que estavam


em desuso podem ser utilizadas para melhorar o desempenho do SGBD. Esses
novos BDs podem ser definidos como BDs que não seguem o modelo relacional
de dados e possuem seis propriedades (CATELL, 2011):

6
TÓPICO 1 | BANCOS NOSQL

I. Escalonamento horizontal.
II. Armazenamento de dados complexos de maneira distribuída.
III. Interface de acesso ou protocolo de acesso simples para manipulação dos
dados.
IV. Sem suporte ou relaxamento das propriedades ACID.
V. Alta disponibilidade.
VI. Esquema flexível ou até ausência de esquema.

No entanto, é importante compreender que não se trata de afirmar que os


BDs NoSQL são perfeitos e vieram para substituir os BDs relacionais, pelo contrário,
os BDs são na verdade complementares. Os BDs NoSQL surgiram para suportar re-
quisitos que o modelo relacional não conseguia, porém eles não tratam do mesmo
tipo de problema. Como dito, os BDs NoSQL não possuem suporte da ACID, assim,
não podem ser utilizados em ambientes que necessitam de transações.

O termo NoSQL, da forma que é conhecido atualmente, surgiu em 2009


cunhado por Johan Oskarsson (SADALAGE; FOWLER, 2019). Na época, o surgi-
mento do Big Table (desenvolvido pela Google) e Dynamo (desenvolvido pela Ama-
zon) com suas arquiteturas distribuídas, baseadas em alta disponibilidade e cres-
cimento horizontal, inspiraram o surgimento de diversos projetos de BDs NoSQL.

Esses projetos já eram discutidos em algumas conferências, mas Johan


queria conhecer mais sobre o assunto, discutindo suas vantagens e desvantagens.
Desse modo, pensou na época em organizar uma “reunião” para discutir essas
novas tecnologias de BDs não relacionais. Johan precisava de um nome para esse
encontro, e através de um canal de IRC (Internet Relay Chat) do banco de dados
Cassandra pediu sugestões. O nome NoSQL foi sugerido por Eric Evans e foi
adotado de imediato (SADALAGE, 2012).

O termo NoSQL, apesar de ter um impacto negativo por ser visto como a
negação do SQL, resume bem os BDs desenvolvidos para esse movimento. Vale
ressaltar também que não existe uma descrição formal para os BDs NoSQL, desse
modo, para caracterizar um banco como NoSQL, devemos observar as caracterís-
ticas citadas anteriormente.

Como esses BDs não seguem o modelo relacional, a linguagem de consul-


ta SQL não é aplicável a eles (CATTELL, 2011). Assim, não existe um padrão de
consulta que possa ser utilizado em todos os BDs NoSQL, cada um possui uma
forma diferente de consulta (SOTENEBREAKER, 2012).

O BD NoSQL Cassandra, por exemplo, possui uma linguagem de consul-


ta própria denominada de CQL (Cassandra Query Language). Essa linguagem de
consulta se assemelha em muitos aspectos ao SQL, porém não possui a mesma
expressividade, e o tratamento das informações se dá de forma diferente já que o
Cassandra utiliza um modelo de dados diferente.

Outro exemplo de linguagem de consulta é o MongoDB (Figura 1). No


exemplo é visto uma consulta sendo realizada tanto em linguagem SQL, bem

7
UNIDADE 1 | BANCOS NOSQL

como utilizando o MongoDB. O MongoDB é um NoSQL muito conhecido, e sua


linguagem de consulta é baseado em documentos JSON. No decorrer dos nossos
estudos, vamos aprender mais sobre o MongoDB e sua linguagem de consulta. No
entanto, como pode ser observado, ela se difere consideravelmente do padrão SQL.

FIGURA 1 – MAPEAMENTO SQL PARA LINGUAGEM DO MONGODB

FONTE: O autor

Na Figura 1 (A), a tabela pessoas é mapeada para a coleção de documentos


“pessoas” do Mongo – Figura 1 (B). Perceba também que a seleção da SQL (WHE-
RE) é mapeado para o primeiro parâmetro do “find”. Mais detalhes sobre a lingua-
gem de consulta do MongoDB serão apresentados no Tópico 3 desta Unidade.

O mais próximo de um padrão de consulta que os BDs NoSQL possuem


é o engajamento da comunidade – de desenvolvedores – de prover acesso aos
dados através de uma API (Application Programming Interface) de acesso baseada
em REST (Representational State Transfer). A API REST define um gerenciamento
de dados unificado através da Web, utilizando as interfaces de acesso get, put,
delete e post. No entanto, é importante ressaltar que isso não pode ser considerado
um padrão, já que alguns BDs NoSQL não têm acesso via REST. Essa falta de pa-
dronização se deve ao fato de não existir um conceito totalmente fechado acerca
deste paradigma. Como já dito, definimos se o BD é ou não um NoSQL baseado
em um conjunto de propriedades.

DICAS

Para entender um pouco mais sobre o conceito de API REST confira o artigo O
que é API? REST e RESTful? Conheça as definições e diferenças! que está disponível em:
https://becode.com.br/o-que-e-api-rest-e-restful/.

8
TÓPICO 1 | BANCOS NOSQL

Agora conhecemos a motivação para o surgimento dos BDs NoSQ e


também as principais funcionalidades que um BD NoSQL deve possuir. Além
disso, sabemos que os BDs NoSQL não seguem o modelo relacional. Já que
não seguem, qual o modelo de dados que os NoSQL possuem? O que é um
modelo de dados afinal? Essas perguntas são de suma importância para um bom
entendimento dos BDs NoSQL e serão respondidas no próximo tópico.

3 MODELOS DE DADOS
Um modelo de dados pode ser conceituado como uma combinação de
estruturas para organizar um conjunto de dados (ATZENI; BUGIOTTI; ROSSI,
2012). Dessa forma, vemos o modelo de dados como a forma com que o BD
organizará e armazenará seus dados fisicamente. Como você deve estar imagi-
nando, já que o modelo de dados é como o BD organiza seus dados, ele interfere
diretamente no desempenho do BD. Desse modo, temos que conhecer a fundo
os modelos de dados existentes e entender qual o mais adequado para cada tipo
de problema.

Normalmente, somos apresentados ao modelo relacional de dados,


aprendemos suas abstrações (organização dos dados em tabelas) e como utilizá-
-lo (SQL), e o usamos em todas as situações. Como visto anteriormente, ele não é
o mais indicado para tratar grandes quantidades de dados. Os BDs NoSQL não
seguem o modelo relacional e, para variar, não possuem um modelo de dados
padrão, ou seja, cada BD NoSQL tem seu modelo de dados e suas especificações.

Felizmente, os modelos de dados utilizados na implementação de BDs


NoSQL podem ser sumarizados em quatro modelos de dados principais: chave-
-valor, orientado a colunas, orientado a documentos e orientado a grafos (SADA-
LAGE; FOWLER, 2019). Dessa forma, qualquer modelo de dados de NoSQL pode
ser classificado em uma dessas categorias, mesmo que internamente ele trabalhe
de forma diferente dos demais.

O modelo de dados chave-valor é o mais simples de todos. Nesse mode-


lo, você apenas dispõe de pares chave-valor como estrutura de armazenamento.
A chave representa o identificador único para um determinado “valor”. Para a
maioria dos BDs, a chave pode ser representada por qualquer vetor de caracte-
res (exemplo: “pessoa.1”). O valor, que é atrelado à chave, é um valor atômico
(indivisível) que pode conter qualquer tipo de dado (outros pares chave–valor,
um inteiro, entre outros), sendo considerado uma “caixa-preta”. Uma impor-
tante característica desse modelo de dados é que os BDs apenas permitem pes-
quisar pela chave e não pelo valor já que este é uma incógnita e não segue um
padrão. Apesar de soar estranho não poder realizar busca pelo valor, essa sim-
plificação faz com que a busca por uma chave seja muito rápida. Geralmente,
a busca por uma chave em um BD chave-valor é O (1), ou seja, com uma única
operação é encontrada a chave procurada. Sendo assim, é ótimo para pesquisas
em que se possui a chave, mas não pode ser utilizado para buscas que envolvam
informações armazenadas no campo de valor.

9
UNIDADE 1 | BANCOS NOSQL

O modelo orientado a colunas é semelhante ao chave-valor. Na verdade,


podemos dizer que ele é uma especialização do modelo chave-valor. O modelo
orientado a colunas organiza seus dados com base em uma distribuição por co-
lunas (propriedades), esta organização é mais complexa que a anterior e permi-
te consultas com filtro em valores de colunas. Conforme descrito por Sadalage
(2012), esse modelo de dados é composto por uma keyspace (base de dados), fa-
mílias de colunas, conjuntos de colunas acessadas com base em uma chave única,
colunas e seus respectivos valores. Famílias de colunas tem a ideia de agrupar
colunas que possuam um domínio em comum (exemplo: conjunto de colunas que
representam pessoas). Cada conjunto de colunas possui uma chave de acesso,
como se fosse uma chave primária de um BD relacional, e este conjunto repre-
senta um conjunto de características de uma ocorrência (exemplo: informações
pessoais de uma pessoa). Por fim, cada coluna de um desses conjuntos possui
um nome e um valor. A principal diferença para o modelo chave-valor é que o
modelo orientado a colunas permite consultas mais complexas que envolvam o
valor das colunas.

O modelo de dados orientado a documentos armazena seus dados baseado


em uma organização de documentos. Ele utiliza o conceito de coleção de docu-
mentos, em que cada documento é acessado também a partir de uma chave única
e atômica (CATTELL, 2015). Da mesma forma que um objeto em um BD orientado
a objetos, um documento é composto por uma série de atributos, cujo valor pode
ser simples ou complexo. Considera-se um atributo simples aquele que possui um
valor atômico, e um atributo complexo aquele que possui um conteúdo multivalo-
rado ou um conteúdo organizado em uma estrutura, como uma lista, um registro
ou um conjunto. Esse modelo de dados é basicamente composto por um BD, um
conjunto de coleções de documentos, documentos, atributos e valores. Assim como
o modelo colunar, o modelo orientado a documentos permite consultas complexas
sobre os valores de cada atributo. Adicionalmente, a orientação a documento pos-
sui uma estrutura mais flexível facilitando a inclusão dos dados.

O modelo de dados orientado a grafos possui uma estrutura de armaze-


namento baseada em grafos de acesso (ABADI, 2009). Geralmente, dizemos que
os três primeiros modelos de dados são baseados em chave de acesso, pois todos
compartilham essa noção. O modelo orientado a grafos é consideravelmente dife-
rente dos demais. Sua estrutura, assim como uma estrutura de grafo tradicional,
é baseada em nós e arestas. Cada nó armazena um nome e uma série de atributos
e valores. Os nós são conectados por arestas que possuem um nome, e opcional-
mente uma série de atributos e valores. Devido a sua natureza de organização, o
modelo de grafos é o mais especializado de todos. Ele é muito indicado para mo-
delar relacionamentos entre objetos e para realizar consultas que envolvam esses
relacionamentos. No entanto, seu uso para o armazenamento de informações que
não possuam relacionamento é desencorajado, já que o processo de busca no gra-
fo pode se tornar custoso.

Como podemos ver cada um dos modelos de dados possui característi-


cas únicas e aplicações específicas. Claro que nestas poucas linhas não é possível

10
TÓPICO 1 | BANCOS NOSQL

entender a fundo como cada um desses modelos de dados trabalha e quando de


fato cada um deve ser utilizado. Dessa forma, nos próximos tópicos, trataremos
separadamente de cada um dos modelos de dados, abordando suas característi-
cas principais e quais os problemas que podem ser resolvidos por cada um deles.
Além disso, para cada modelo de dados que estudaremos, serão realizados al-
guns testes práticos para aprofundar os conceitos.

11
RESUMO DO TÓPICO 1
Neste tópico, você aprendeu que:

• Os BDs relacionais foram utilizados durantes anos como fonte segura de


armazenamento e consulta de dados, porém eles não são adequados para lidar
com os requisitos impostos pelo Big Data.

• Os BDs NoSQL possuem arquitetura distribuída baseada em alta disponibilidade


e crescimento horizontal. Eles surgiram para lidar com as demandas que os
BDs relacionais não eram capazes.

• Os BDs NoSQL não vão acabar com o uso de BDs relacionais, eles tratam de
problemas diferentes e são complementares.

• Os BDs NoSQL não seguem o modelo relacional de dados e, geralmente, não


possuem acesso via SQL. Além disso, não existe um padrão de consulta para
esses BDs.

• Os BDs NoSQL podem ser caracterizados em quatro diferentes modelos de


dados: chave-valor, orientado a colunas, orientado a documentos e orientado a
grafos.

12
AUTOATIVIDADE

1 Considere as seguintes características do projeto de um Banco de Dados:

I- Alta disponibilidade e esquema rígido.


II- Relaxamento das propriedades ACID aliado à alta disponibilidade.
III- Linguagem de consulta padrão.
IV- Escalonamento horizontal.

Sobre as características que os BDs NoSQL possuem, assinale a alternativa


CORRETA:

a) ( ) I, apenas.
b) ( ) III e IV, apenas.
c) ( ) II e I, apenas.
d) ( ) I, II e IV, apenas.

2 Disserte sobre os motivos que culminaram com o surgimento dos BDs


NoSQL e quais as estruturas de dados que esses BDs utilizam.

3 O surgimento dos BDs NoSQL diminui de alguma forma a relevância dos


BDs relacionais?

13
14
UNIDADE 1
TÓPICO 2

BANCOS CHAVE-VALOR

1 INTRODUÇÃO
No tópico anterior, conhecemos a motivação para a criação do
paradigma NoSQL, discutimos suas características básicas e quais os modelos
de dados existentes. Como dito anteriormente, é importante que você, como
bom profissional, consiga entender os modelos de dados e suas aplicações. Dessa
forma, quando confrontado com uma situação real será capaz de decidir qual o
modelo de dados mais se adequa aos seus problemas e qual o BD NoSQL (ou
mesmo relacional) irá usar.

Dentre os quatro modelos de dados dos BDs NoSQL, o chave-valor é


considerado o mais simples. Apesar desse modelo de dados ser simples, isso não
implica que ele seja ruim ou possa ser menosprezado. É devido à simplicidade desse
modelo que ele possui um desempenho excelente, quando utilizado corretamente.

Neste tópico, conheceremos mais a fundo o modelo de dados chave-valor


e explorar suas principais características entendendo seu funcionamento básico.
Ao estudar sobre o modelo chave-valor, você terá uma noção de como o modelo
de dados se comporta, traçando um paralelo com os BDs relacionais. Além disso,
vamos dar uma olhada no Redis, um BD NoSQL chave-valor, compreendendo
como ele trabalha, em quais plataformas pode ser utilizado e como é sua
linguagem de consulta.

2 MODELO DE DADOS E ARQUITETURA


De maneira geral, podemos dizer que um BD chave-valor é uma grande
tabela de hash, em que cada linha é um par chave-valor (SADALAGE; FOWLER,
2019). Sendo a chave um identificador único e o valor um conjunto de informações
visto como atômico (CATTELL, 2011). Sendo assim, ele é muito indicado para
quando as buscas no BD são por um valor específico e único (uma chave primária).

O Quadro 1 apresenta um mapeamento simples entre os conceitos básicos


de um BD relacional com os envolvidos em um banco chave-valor. Perceba
que um BD relacional pode suporta mais de uma base de dados em uma única
instalação, porém, geralmente, BDs chave-valor não possuem múltiplas bases de
dados. O conceito de tabela relacional não se relaciona diretamente com nenhum
conceito comum a todos os BDs NoSQL chave-valor. Assim, todos os dados
15
UNIDADE 1 | BANCOS NOSQL

(pares chave-valor) são armazenados diretamente no cluster. Alguns BDs NoSQL,


como o Redis, criam uma estrutura que se assemelha ao conceito de tabela. Essa
estrutura é chamada de bucket, porém é encontrada em poucos BDs.

E
IMPORTANT

Perceba que os BDs chave-valor apenas permitem consultas nas chaves. As


consultas sobre os valores se tornariam muito custosas, pois exigem que todos os registros
sejam analisados. Por isso dizemos que o valor armazenado para uma determinada chave é
uma caixa-preta: pode possuir qualquer estrutura interna, mas não podemos realizar filtros
nessas estruturas.

QUADRO 1 – MAPEAMENTO RELACIONAL PARA CHAVE-VALOR

Banco Relacional NoSQL Chave-Valor


Base de dados Cluster
Tabela (relação) –
Linha (tupla) Par chave-valor
Identificador da tupla Chave
FONTE: O autor

Como vimos no Quadro 1, um par chave-valor do modelo é visto como


uma tupla para o modelo relacional, e o identificador de uma tupla, ou mesmo o
conjunto de chaves primárias de uma determinada tupla, é visto como a chave.
A Figura 2 apresenta uma visão de um BD NoSQL, o qual possui quatro pares
chave-valor.

FIGURA 2 − VISÃO DE UM BD CHAVE-VALOR

FONTE: O autor

16
TÓPICO 2 | BANCOS CHAVE-VALOR

Apesar de estarmos traçando este paralelo entre o modelo relacional e


o chave-valor, é importante ressaltar que eles se diferem em muitos aspectos.
Mesmo que uma tupla relacional possa ser mapeada para um par chave-valor
não devemos considerar, necessariamente, esse mapeamento ao criar nossa base
de dados. A construção, ou definição de uma chave para o BD chave-valor, é
crítica e deve ser devidamente planejada.

Além disso, sempre é importante manter em mente que o valor armazenado


pode ser de qualquer tipo. Pode ser um texto puro, um vetor de números, outros
pares chave-valor e assim por diante. Dessa forma, o valor sempre é visto como
uma caixa-preta.

Como vimos anteriormente, em um BD chave-valor, uma chave deve


ser única e, usualmente, somente são permitidas consultas sobre as chaves e
não sobre os valores atrelados a elas. Assim, imagine que você foi incumbido de
projetar um BD chave-valor para armazenar os dados de um BD relacional. Você
possui duas tabelas: Diretores (id, nome, prêmios) e Filmes (id, nome, diretor –
chave estrangeira para Diretores –, ano) sendo id a chave primária de ambas as
tabelas (Figura 3). Considerando essas duas tabelas, imagine que você propõe o
mapeamento direto de tuplas. Desse modo, chaves primárias serão mapeadas
para chaves (do par chave-valor) e os dados da tupla serão compactados e
armazenados no valor (do par chave-valor). O primeiro problema enfrentado é
que como o atributo id é a chave primária das duas tabelas nada impede que
exista um id com valor 1 para Filmes e um id com valor 1 para a tabela Diretores.
Dessa forma, nossa estratégia não funciona.

FIGURA 3 – DB CINEMA

FONTE: O autor

Nesse sentido, a situação proposta trata-se de um problema simples de


contornar, pois podemos concatenar o valor da chave primária com o nome da
tabela, eliminando o problema. A Figura 4 apresenta uma visão dessa ideia.
Perceba que temos as chaves constituídas da concatenação do nome da tabela e

17
UNIDADE 1 | BANCOS NOSQL

um valor inteiro (que é o valor para o id). Como valor podemos criar um JSON
com todas as informações da tupla.

FIGURA 4 – MODELO CHAVE-VALOR BD CINEMA

FONTE: O autor

Agora imagine que necessitamos fazer algumas consultas nessa base de


dados. Por exemplo, realizar a busca de qual ano que o filme The Godfather foi
lançado. Como já discutimos anteriormente este tipo de consulta não pode ser
executada em um BD chave-valor. Como você sabe, esses BDs apenas permitem
a consulta na chave. Sendo assim, não é possível realizar essa consulta. Com
este modelo apenas poderíamos buscar a informação de um determinado filme,
por exemplo, mostrar as informações do Filme com id 1, em que buscando pela
chave ‘filme.1’ é possível obter o valor que nos possibilita mostrar ao usuário.
Geralmente, esses bancos permitem a execução de expressões regulares para
busca das chaves. Com isso, poderíamos listar todos os filmes com uma consulta
do tipo ‘Filmes.*’.

Dessa forma, imaginamos que você está se perguntado para que serve
este tipo de BD já que não nos possibilita fazer consultas complexas? De fato,
o uso desse tipo de BD é bem restrito. Normalmente, eles são utilizados para
realizar algum tipo de cache do sistema. A busca por uma chave neste BD se dá
em complexidade de O (1) mais rápida do que qualquer índice implementado
por algum BD relacional. A Oracle utiliza em seu BD relacional um BD chave-
valor (de desenvolvimento próprio) para gerenciar o buffer e otimizar o acesso a
algumas informações.
18
TÓPICO 2 | BANCOS CHAVE-VALOR

DICAS

A notação O (1) significa que é uma busca feita em tempo constante. A letra O
representa uma notação denominada “Big O” (grande O), que é empregada para mensurar a
complexidade de algoritmos de busca. Para entender melhor sobre o Grande O, leia o artigo
Notação Big O, disponível em: http://jkolb.com.br/notacao-big-o/.

Outra aplicação interessante é a utilização de um BD chave-valor para


armazenar o carrinho de compras em um e-commerce. Cada acesso de um usuário
gera um cookie de identificação de seção. Esse identificador pode ser utilizado
como a chave do par chave-valor. O valor seriam os produtos escolhidos pelo
cliente, o identificador de cada item e a quantidade de cada item.

A consistência desses BDs é outro ponto que devemos conhecer para ado-
tarmos seu uso. A consistência, como você deve imaginar, é feita de maneira distinta
de um BD relacional. BDs chave-valor, usualmente, apenas consideram operações
(inserção, leitura ou exclusão) sobre dados de uma única chave. Cada banco possui
sua implementação de consistência, mas geralmente estes BDs são conhecidos por
disponibilizar consistência eventual, ou seja, após a execução de uma determinada
operação, esta será replicada entre os elementos do cluster, mas essa replicação irá
demorar um curto espaço de tempo. Em um modelo fortemente consistente (rela-
cional), o usuário esperaria que o dado fosse replicado e então retornaria sucesso.
Em um BD com consistência eventual não existe essa espera, a operação retorna
sucesso e eventualmente a replicação seria completa. É importante ressaltar que
essa janela de inconsistência, enquanto a replicação ocorre, é curta.

Como dito no Tópico 1, BDs NoSQL possuem como uma das suas caracte-
rísticas a escalabilidade horizontal. No caso do BDs chave-valor, a escalabilidade
se dá baseada em particionamento dos dados, ou seja, cada um dos nós do cluster
armazena uma partição dos dados. Os dados são particionados baseados no valor
da chave. Quando novos nós são adicionados ao cluster, eles ficam responsáveis
por novas partições dos dados, mantendo o balanceamento de carga no sistema
(SADALAGE; FOWLER, 2019). A fim de atingir alta disponibilidade, os sistemas
replicam as partições entre os nós, facilitando o acesso aos dados.

Até agora discutimos como os BDs chave-valor armazenam seus valores,


como funcionam internamente e algumas situações em que podemos utilizar es-
ses BDs. No entanto, quando definitivamente não devemos utilizar esses BDs?

Uma situação clara em que não podemos utilizar esses BDs é quando ne-
cessitamos modelar qualquer tipo de relacionamento entre os dados já que eles
não suportam ligações entre diferentes chaves. Outra situação na qual não se
aconselha seu uso é em situações em que precisamos consultar os dados armaze-

19
UNIDADE 1 | BANCOS NOSQL

nados para uma determinada chave, pois esse tipo de BD não suporta esse tipo de
consulta, e, por fim, quando necessitamos armazenar múltiplas chaves ao mesmo
tempo. Como vimos, tais BDs apenas garantem consistência por chave. Assim, se
for necessário armazenar mais de uma chave por vez em uma transação, não há
garantias que todas as chaves serão de fato inseridas.

Agora passamos por todas as etapas necessárias: conhecemos o modelo


de dados chave-valor, sabemos como ele funciona e quando devemos ou não o
usar. É importante ressaltar que cada BD chave-valor possui suas peculiaridades
de funcionamento, e quando você optar por um desses produtos deve conhecer
suas características para melhor usar sua estrutura.

NTE
INTERESSA

Existem vários BDs chave-valor no mercado, dentre eles:

• Riak, que você poderá acessar através do link: https://riak.com/.


• Redis, que você poderá acessar através do link: https://redis.io/.
• Volrdemort, que você poderá acessar através do link: https://www.project-voldemort.com/.
• Memcached, que você poderá acessar através do link: https://memcached.org/.

Então está na hora de “colocarmos a mão na massa” e ver como é a


linguagem de um destes BDs na realidade. No próximo subtópico, faremos uma
atividade prática utilizando o Redis.

3 ATIVIDADE PRÁTICA REDIS


O Redis é um dos representantes mais famosos da família dos BDs
NoSQL chave-valor. É um projeto de código aberto disponibilizado desde 2009
de maneira gratuita. Como todo BD chave-valor, o Redis possui como principal
estrutura de armazenamento chaves e seus respectivos valores.

Um ponto interessante sobre o Redis é que ele possui uma arquitetura em


memória, isto é, seus dados são persistidos apenas na memória principal (RAM).
Opcionalmente, o usuário pode configurá-lo para persistir periodicamente seus
dados em disco, mas por padrão seus dados são mantidos apenas na memória
principal. Através de sua arquitetura em memória, o Redis se diferencia dos
demais BDs (orientados a disco), evitando a latência gerada pelas leituras e
escritas no disco. Dessa forma, escritas e leituras nesse BD são muito rápidas já
que não necessitam buscar informações no disco.

A linguagem de consulta implementada pelo Redis é simples e permite


apenas consultas baseadas na chave de acesso das informações. Assim, utilizando

20
TÓPICO 2 | BANCOS CHAVE-VALOR

o Redis não é possível realizar buscas com base nos valores armazenados para
uma chave. Isso faz com que seu uso seja limitado a buscas em que conhecemos
os elementos da chave.

Para o nosso exemplo, não será necessária a instalação do Redis em sua


máquina. Um ponto interessante desse BD é que ele disponibiliza uma interface
on-line com um tutorial para que os usuários possam conhecer sua linguagem
e ter o primeiro contato. Caso você tenha interesse de realizar a instalação em
sua máquina, a instalação é muito simples e rápida. Mais informações sobre a
instalação podem ser encontradas no link: https://redis.io/download.

Para dar início ao primeiro contato com o Redis, abra o seu navegador de
internet (não há restrição de navegador) e acesse o link de testes do Redis: http://
try.redis.io/. Após acessar o link, você visualizará a interface representada pela
Figura 5.

A parte inferior da Figura 5 (retângulo menor – 1) conta com uma entrada


de dados, na qual digitaremos nossos comandos. O segundo retângulo (retângulo
maior – 2) demarca a área de resposta, em que serão exibidos os resultados de
nossas consultas. Perceba que esse é um ambiente muito semelhante ao terminal
de comandos.

FIGURA 5 – INTERFACE DE ACESSO REDIS

FONTE: O autor

Para começar, digite na área de entrada de dados (retângulo 1) o comando


“HELP”. Esse comando apresentará todos os comandos que o Redis suporta
(Figura 6). Perceba que a lista de comandos não é muito grande comparada ao
número de elementos que a linguagem SQL permite. No entanto, tenha em mente
que o Redis possui uma linguagem de consulta mais simplista.

21
UNIDADE 1 | BANCOS NOSQL

FIGURA 6 – RESULTADO COMANDO HELP

FONTE: O autor

O primeiro passo para utilizarmos o Redis foi dado, mas precisamos


adicionar dados a essa nossa nova base de dados. Para acionar um par chave-
valor ao Redis, basta utilizar o comando SET. O comando SET é usado na forma
“SET nome_chave valor”. O comando retorna “OK” se a chave foi inserida com
sucesso (Figura 7, primeira linha). O comando “SET” também aceita a inclusão de
valores complexos (Figura 7, terceira linha). Outra característica importante do
comando SET é que é possível criar um timer que fará com que esse par-chave-
valor se apague automaticamente. A última linha da Figura 7 insere um valor que
será apagado automaticamente após 20 segundos.

FIGURA 7 – COMANDO SET

FONTE: O autor

Agora que inserimos dados precisamos verificar se esses dados foram de


fato armazenados na nossa base de dados. Para isso usaremos o comando GET.
O comando GET retorna o valor armazenado para uma determinada chave. Para
buscar o dado basta usar a sintaxe “GET nome_chave”. A primeira linha da Figura
8 apresenta a busca pela chave “curso”, e a última através da variável “valor_
complexo”. Vale ressaltar que a busca por uma chave é case sensitive, ou seja, faz
distinção entre caracteres maiúsculos ou minúsculos (segunda linha da Figura 8).
Perceba, pela Figura 8, que quando uma chave não é encontrada pelo sistema é
retornado o valor “nil”.

22
TÓPICO 2 | BANCOS CHAVE-VALOR

FIGURA 8 – RESULTADO COMANDO GET

FONTE: O autor

Outra operação muito importante no BD é como excluir uma informação


que já não serve mais. Para remover um valor no Redis basta utilizar o comando
“DEL”. O comando DEL irá, com base na chave ou chaves passadas por parâmetro,
apagar seus respectivos dados retornando o número de registros afetados. A
sintaxe do comando segue o formato “DEL nome_chave”. A primeira linha da
Figura 9 apresenta a exclusão do valor armazenado para a chave “curso”. Caso a
chave passada para o DEL não exista, ele retorna 0 (Figura 9, segundo comando).
Perceba que você pode passar mais de uma chave para o comando DEL, apagando
múltiplos registos ao mesmo tempo (Figura 9, quinta linha).

FIGURA 9 – COMANDO DEL

FONTE: O autor

Nesse momento, você deve estar se perguntando qual será o comando


para realizar atualizações nos dados, porém sistemas chave-valor geralmente não
possuem um comando para atualização. Como o valor armazenado para uma
determinada chave é tratado como atômico, não são permitidas atualizações nele.
Caso seja necessário realizar uma operação de atualização, é necessário excluir a
informação e depois inseri-la novamente.

23
UNIDADE 1 | BANCOS NOSQL

Obviamente os comandos do Redis não se limitam a apenas operações


básicas de CRUD (create, read, update e delete). Um comando muito útil quando
estamos utilizando esse BD é o comando “KEYS”. O comando KEYS retorna todas
as chaves armazenadas na base de dados. Como parâmetro podem ser passadas
expressões regulares para encontrar chaves que sigam certo padrão. A sintaxe do
comando é simples: para buscar todas as chaves da base você executa “KEYS *”.

Caso você necessite achar chaves específicas poderá passar uma expressão
regular como parâmetro, por exemplo, “KEYS *o” para buscar todas as chaves
que terminem com a letra “o”. Imagine que inserimos os dados de filmes e
diretores apresentados na modelagem da Figura 4. A Figura 10 apresenta os
resultados de consulta: (i) todos os registros cadastrados, e (ii) as chaves que
mapeiam informações de filmes. Apesar de muito útil, o uso do comando KEY é
desaconselhado em ambiente de produção, pois ele iterará sobre todas as chaves
armazenadas, o que pode mitigar o desempenho.

FIGURA 10 – CONSULTAS UTILIZANDO KEY

FONTE: O autor

O Redis possui muitas outras funções, tais como: manipular documentos


JSON, suporte a estruturas de lista e pilha, entre outras.

DICAS

Espero que essa rápida introdução tenha esclarecido algumas eventuais


dúvidas no funcionamento prático de um BD chave-valor e que sirva de ponto de partida
para que você continue explorando diferentes estruturas e consultas que o Redis permite
utilizar. Você pode encontrar informações detalhadas sobre os comandos do Redis e seu
funcionamento diretamente no link: https://bit.ly/3gsQRwa.

24
RESUMO DO TÓPICO 2
Neste tópico, você aprendeu que:

• Os BDs chave-valor possuem um modelo de dados simples, baseado em chaves


únicas que apresentam um valor associado. Esse valor pode ter qualquer
estrutura, sendo tratado pelo modelo como uma caixa-preta.

• Os BDs chave-valor possuem uma linguagem de consulta simples que,


geralmente, apenas permitem consultas nas chaves. Pesquisas nos valores
tornariam o sistema mais lento, sendo assim não são permitidas consultas com
base neles.

• O acesso aos dados armazenados em um BD chave-valor é bastante rápido,


pois os valores são armazenados de maneira otimizada baseada na chave.

• Esses BDs utilizam particionamento de dados para facilitar o suporte à


escalabilidade. Além disso, a fim de suportar alta disponibilidade, as partições
dos dados são replicadas entre os nós do cluster.

• Os BDs chave-valor são indicados para uso em que a busca de dados é sempre
feita por um identificador único.

25
AUTOATIVIDADE

1 Cite as principais características do modelo NoSQL chave-valor explicando


como o BD dá suporte a elas.

2 Descreva uma aplicação real para um BD chave-valor. Defina em qual


problema você usaria esse tipo de BD e argumente sobre o motivo de sua
decisão.

26
UNIDADE 1
TÓPICO 3

BANCOS ORIENTADOS A DOCUMENTOS

1 INTRODUÇÃO
Até agora conhecemos os BDs NoSQL de maneira geral. Sabemos que es-
ses BDs possuem diferentes modelos de dados e que cada um serve para um tipo
de aplicação. Além disso, já exploramos o modelo de dados mais simples, o cha-
ve-valor, conhecendo suas estruturas e quando devemos utilizá-lo.

Seguindo nossos estudos pelo paradigma de BDs NoSQL, iremos agora


conhecer o modelo de dados orientado a documentos. Esse modelo pode ser visto
como uma especialização do modelo de dados chave-valor. Como dito anterior-
mente, esse modelo de dados pertence à categoria dos BDs NoSQL baseados em
chave de acesso, já que, assim como o modelo de dados chave-valor, tem seu
acesso baseado na busca por chaves.

Essa informação deve ter feito você pensar o porquê da existência desse
modelo já que é semelhante ao chave-valor e também possui acesso via chave ou
identificador único. Como vimos anteriormente, o modelo chave-valor é muito
simples e apesar de ser rápido não permite que sejam realizadas pesquisas que
não estejam relacionadas à chave. Dessa forma, existia a necessidade de BDs que
tivessem uma linguagem de consulta mais robusta que não se limitasse apenas a
consultas pela chave.

BDs com modelo de dados orientado a documentos permitem o arma-


zenamento de estruturas mais complexas que o modelo chave-valor, assentindo
que o usuário possa realizar consultas nos valores armazenados dentro dessas
estruturas. Além disso, os BDs dessa categoria possuem linguagens de consulta
mais robustas, com funções de agregação, agrupamento, entre outras.

Neste tópico, veremos como um BD NoSQL orientado a documentos ar-


mazena e manipula seus dados. Exploraremos quais técnicas tais BDs utilizam
para prover suporte à alta escalabilidade e alta disponibilidade. Ademais, como
no tópico anterior, realizaremos uma atividade prática utilizando o MongoDB,
visando ao seu primeiro contato com um BD orientado a documentos.

27
UNIDADE 1 | BANCOS NOSQL

2 MODELO DE DADOS E ARQUITETURA


Como o nome já sugere, os BDs NoSQL orientados a documentos pos-
suem como estrutura central de armazenamento o documento. Sendo assim,
esses BDs armazenam e manipulam documentos que podem ser JSON, BSON
(Binary JSON), XML (Extensible Markup Language) ou qualquer outro (SADA-
LAGE; FOWLER, 2012). Tais documentos, geralmente, são autodescritivos com
estruturas hierárquicas em forma de árvore.

Podemos pensar neste BD como sendo um BD chave-valor, em que os da-


dos armazenados para o valor podem ser consultados e manipulados (CATTELL,
2015). Dessa forma, nestes BDs temos uma chave associada a um documento com
estrutura própria. Os documentos armazenados podem não possuir semelhança
estrutural, ou seja, o usuário é livre para definir como os dados serão organiza-
dos no documento. Desse modo, como se trata de documentos, a sintaxe de cada
modelo deve ser devidamente respeitada.

BDs orientados a documentos geralmente possuem uma estrutura de


armazenamento muito semelhante entre eles. A grande maioria possui uma es-
trutura baseada em um conceito geral que representa a base de dados. A base
é constituída por coleções de documentos definidas pelo usuário. Cada coleção
de documentos possui um nome único e pode ser vista como um diretório que
agrupa documentos semelhantes. As coleções de documentos são constituídas
por múltiplos documentos. Cada documento deve possuir um nome/chave que o
identifique unicamente dentro da coleção de documentos. Além disso, os docu-
mentos são basicamente constituídos de atributos com seus respectivos valores.
O valor de um atributo pode ser de diversos tipos, desde um valor inteiro atômi-
co a conjuntos de dados ou mesmo outros documentos. Esta estrutura pode ser
visualizada na Figura 11.

FIGURA 11 – EXEMPLO DE UM BD ORIENTADO A DOCUMENTOS

FONTE: O autor

28
TÓPICO 3 | BANCOS ORIENTADOS A DOCUMENTOS

Como você deve ter percebido, a estrutura de um BD orientado a


documento é comparável à estrutura de um BD relacional. Claro que os conceitos
se diferem pela natureza com que são tratados, porém é possível traçar um
paralelo entre os conceitos. O Quadro 2 apresenta uma forma de mapeamento
entre os conceitos do modelo relacional para o modelo orientado a documentos.
Perceba que uma coleção de documentos pode ser vista como uma tabela, já que,
em essência, ambas agrupam dados relacionados a um mesmo tipo de objeto/
entidade. Cada uma das linhas de uma tabela poderia ser mapeada para um
documento pertencente à coleção, tendo em vista que representa um registro de
certo objeto ou entidade. Considerando uma tupla com seus valores, o documento
mapearia cada uma das colunas como um atributo e seu respectivo valor. Por fim,
a chave primária ou identificador da tupla, pode ser vista como nome ou chave
de acesso de um documento.

QUADRO 2 – MAPEAMENTO BD ORIENTADO A DOCUMENTOS PARA RELACIONAL

Banco Relacional NoSQL documento


Base de dados Base de dados
Tabela (relação) Coleção de Documentos
Linha (tupla) Documento
Identificador da tupla Nome/Chave Documento
FONTE: O autor

Esse mapeamento não necessariamente é o correto, tudo depende da for-


ma com que os dados serão acessados. Na verdade, tal mapeamento deve ser
visto como um guia conceitual para traçar um paralelo entre os dois modelos e
não como guia definitivo de mapeamento entre modelos. Geralmente, não faz
muito sentido realizar esse tipo de mapeamento. Veja que se você sempre realizar
esse mapeamento, você estará atrelando a estrutura de sua aplicação ao modelo
relacional sem que seu BD seja relacional. Desse modo, isso pode condizer com
seu problema e suas consultas, mas também pode ocasionar sérios problemas de
desempenho nas consultas.

Vamos fazer um exemplo simples. Considere novamente o BD Cinema


apresentado no Tópico 2. Lembre-se que esse BD possui duas tabelas: Filmes e Di-
retor. A Tabela Filmes contém algumas informações básicas de filmes e uma chave
estrangeira para o diretor responsável pelas gravações. A Tabela Diretor apenas
possui um identificador único, o nome do diretor e quantos prêmios ele recebeu. A
Figura 12 apresenta o mapeamento do BD relacional Cinema para o modelo de do-
cumentos baseado nas regras de mapeamento propostas. Perceba que as tabelas fo-
ram mapeadas para coleções de documentos. A coleção de documentos Filmes, por
exemplo, possui três documentos, cada um mapeando uma tupla da tabela Filmes.
O documento possui como chave o valor da chave primária de cada tupla (coluna
id) e é constituído dos atributos que mapeiam as colunas das respectivas tuplas.

29
UNIDADE 1 | BANCOS NOSQL

FIGURA 12 – BD CINEMA MAPEADO PARA O MODELO DOCUMENTO

FONTE: O autor

Considerando isso, imaginamos que você ficou com uma dúvida: no BD


relacional a coluna diretor da tabela Filmes é uma chave estrangeria para a tabela
diretores, então, os BDs NoSQL possuem chaves estrangeiras?

Apesar do valor da coluna da Tabela Filmes ter sido mapeado para o atri-
buto ‘diretor’ dos documentos, não existe uma relação de chave estrangeira, ou
seja, não existe garantia nenhuma de integridade que o valor do atributo exista
na coleção de documentos Diretores. Este é um ponto importante dos modelos
NoSQL em geral: a fim de dar melhor desempenho ao acesso aos dados, restri-
ções de integridade referencial são deixadas de lado e esses BDs não suportam
esse tipo de função. Sendo assim, como sabemos que o valor armazenado no
atributo diretor no documento “1” da coleção Filmes de fato se refere a um valor
em outra coleção? A resposta é simples: você deve criar um método via aplicação
que verifique. No entanto, como você deve imaginar, isso se torna pesado, e não
é uma boa prática. Nesse sentido, indicamos que se você necessita muito desse
relacionamento não use esse tipo de mapeamento.

BDs NoSQL orientados a documentos geralmente não permitem chaves


estrangeiras. Existem algumas exceções: o MongoDB, por exemplo, permite que
você crie ligações entre documentos, é como se fosse um atalho para encontrar
um documento pertencente a outra coleção de documentos. Apesar de se asseme-
30
TÓPICO 3 | BANCOS ORIENTADOS A DOCUMENTOS

lhar com uma chave estrangeira, a referência a documentos implementada pelo


MongoDB não deve ser considerada para emular chaves estrangeiras.

Vamos imaginar então que em nosso BD não precisamos mais nos impor-
tar com a integridade referencial, ou seja, nosso sistema está bem construído e
para todo Filme cadastrado existe sempre um diretor correspondente. Dessa for-
ma, não precisamos nos importar com a restrição de uma chave estrangeira, e a
inclusão de registros, por consequência, é mais rápida já que não realiza esse tipo
de validação. Contudo, uma consulta recorrente em nossa base de dados é buscar
os filmes e o nome do diretor que o dirigiu. Através do modelo relacional essa
seria uma consulta simples de realizar, bastaria utilizar uma junção. O problema
é que BDs NoSQL, em sua grande maioria, não possuem suporte à operação de
junção.

Perceba que a operação de junção faz total sentido quando pensamos


no modelo relacional. Como o modelo é baseado na teoria de conjuntos, basi-
camente, estamos pegando dois conjuntos e executando uma intersecção (SIL-
BERSCHATS; KORTH; SUDARSHAN, 2012). Quando pensamos no modelo de
dados NoSQL de documentos, isso perde o sentido já que agora temos diretórios
(coleções) e documentos. Além disso, como vimos no Tópico 1, sistemas NoSQL
primam pelo desempenho, e operações de junção são pesadas. Então, já que não
podemos utilizar junções, como poderemos retornar os dados de cada filme com
seus respectivos diretores? Uma possível solução é implementarmos na aplicação
nosso próprio algoritmo de junção. Claramente essa não é uma boa opção, pois
demanda tempo e, considerando que algoritmos de junção são complexos, prova-
velmente acabaríamos perdendo desempenho ao executá-los.

Uma solução interessante para esse problema é a utilização do conceito


de agregados. BDs NoSQL geralmente utilizam o conceito de agregado para per-
mitir que o usuário possa interagir com estruturas de armazenamento mais com-
plexas. Perceba que quando estamos manipulando informações com o modelo
relacional, tudo se baseia na execução de operações em tuplas, sendo que tudo
é executado tupla a tupla. Muitas vezes, como quando utilizamos uma operação
de junção, precisamos combinar tuplas em um registro mais complexo. O concei-
to de agregação é, basicamente, armazenar esses dados em uma estrutura mais
complexa com mais subníveis.

Vamos pensar novamente em nosso exemplo, modelamos nosso BD


orientado a documentos considerando que cada tabela viraria uma coleção de
documentos, pois os conceitos têm semelhanças. Se utilizarmos o conceito de
agregados podemos considerar que na verdade algumas tabelas poderiam ser
mapeadas como um atributo complexo de um documento. Considerando isso,
poderíamos mudar nosso mapeamento inicial do BD Cinema para mapear as tu-
plas da tabela “Diretores” diretamente para valores complexos em seus pares
(chaves-estrangeiras) nos documentos da coleção Filmes. A Figura 13 apresenta
uma representação deste novo modelo de mapeamento.

31
UNIDADE 1 | BANCOS NOSQL

FIGURA 13 – MAPEAMENTO BD CINEMA BASEADO EM AGREGADOS

FONTE: O autor

Perceba que nessa nova versão de nosso modelo existe apenas uma
coleção de documentos: a coleção de Filmes. Os dados referentes ao diretor de
cada um dos filmes foram armazenados com o respectivo filme. Perceba que
dessa forma temos apenas um documento que contém todas as informações
referentes a um filme. Assim, não existe mais a necessidade de uma junção para
obter as informações. Assim, para se obter as informações dos filmes com seus
respectivos diretores, basta buscar todos os filmes e exibir apenas as informações
que precisamos.

Dessa forma, pode-se perceber que essa solução resolve de fato o problema,
mas cria alguns possíveis novos problemas. Um desses problemas é que na hora
de inserir um novo filme é possível escrever as informações do diretor erradas e
deixar a base de dados inconsistente. De fato, isso pode ocorrer, e se você optar
por uma solução desse tipo deve ter em mente os problemas que ela pode gerar.
Veja que a solução deste problema é mais simples que implementar um algoritmo
de junção.

Outro problema que você deve ter notado é que os diretores se repetem
para os filmes, sendo assim serão armazenadas informações redundantes, mas
isso não é necessariamente um problema. O modelo relacional foi criado em uma
época em que o armazenamento era muito caro, desse modo, para mitigar esses

32
TÓPICO 3 | BANCOS ORIENTADOS A DOCUMENTOS

custos, foram criadas as regras de normalização que evitam dados redundantes


e outras situações. Atualmente, o custo de armazenamento é muito mais barato,
computadores pessoais já são equipados com discos rígidos com armazenamento
na casa dos Terabytes.

Quando é realizado a modelagem de um banco de dados NoSQL, a partir


de qualquer modelo de dados, deve esquecer esse tipo de limitação. Não se deve
pensar em tabelas normalizadas, a estrutura de dados é diferente. Devemos focar
no desempenho das consultas que iremos executar. No caso de nosso exemplo,
eliminamos a necessidade de uma junção armazenando os dados juntos.

Para esse problema isso seria uma boa solução, pois o uso de agregados
é muito difundido e encorajado nos BDs orientados a documentos. No entanto,
deve ser utilizado com cuidado. Para nosso exemplo, essa é uma solução muito
elegante, pois o agregado de Diretores é pequeno. Devemos tomar cuidado com
o tamanho dos agregados utilizados. BDs orientados a documentos permitem a
inclusão de agregados dentro dos agregados, e isso pode gerar documentos muito
grandes. Quando você utiliza essa abordagem deve ter em mente que alguns BDs
limitam o tamanho dos documentos que são armazenados ou mesmo que são
retornados em uma consulta. Assim, se seu documento for muito grande, o BD
pode ter que adotar uma técnica que retorne o documento em partes menores, o
que influenciará diretamente no desempenho do seu sistema.

Sempre que você for planejar a utilização de um BD orientado a documento


temos que ter em mente as limitações que ele impõe. O modelo é muito flexível e
permite que o usuário defina a estrutura do documento livremente, mas isso deve
ser realizado com certo cuidado.

Como você já deve ter imaginado, os BDs orientados a documento são


livres de um esquema, ficando a critério do utilizador a estrutura que será
utilizada. Inclusive, não existe uma definição formal de esquema mesmo para
a coleção de documentos. Assim, é possível colocar documentos de diferentes
estruturas na mesma coleção. Se quisermos podemos adicionar um novo atributo
aos filmes que cadastrarmos a partir de agora, por exemplo. Para isso, basta
adicionar o atributo aos novos documentos e quando realizar uma consulta com
base nesse novo atributo os documentos que não o possuem não serão exibidos.

Alguns BDs específicos, como o MongoDB, permitem opcionalmente que


o usuário defina um esquema para documentos em uma mesma coleção. Assim,
é possível criar uma série de regras estruturais, utilizando DTD (Document Type
Definition), para que todos os documentos de uma certa coleção tenham essa
estrutura. Depois de definida a DTD, todos os documentos da coleção devem
seguir essa estrutura. Qualquer documento fora da especificação não será
adicionado. Agora você deve ter pensado: mas como assim um esquema para um
BD NoSQL? Ser livre de esquema não era uma característica interessante?

33
UNIDADE 1 | BANCOS NOSQL

DICAS

O DTD (Document Type Definition) é uma estratégia para estruturar


documentos. Para conhecer mais sobre ele, acesse a página do W3Schools que explica esse
conceito com exemplos. Disponível em: https://www.w3schools.com/xml/xml_dtd.asp.

Ser livre de esquema não significa necessariamente não suportar um


esquema. Os BDs NoSQL atacam diversas frentes de novas aplicações e,
eventualmente, um esquema pode ser necessário. Esse esquema possui um
custo, uma inclusão em uma coleção de documentos livre de esquema é mais
rápida do que em uma que o possua. Isso é meio óbvio, já que quando existe
um esquema deve ser feita uma verificação de validade do documento sobre o
conjunto de regras. Esse é o ônus do uso de um esquema: as inclusões ficam um
pouco mais lentas. O bônus é que as consultas ficam mais rápidas já que com uma
estrutura rígida o BD pode otimizar mais as consultas. Dessa forma, podemos nos
questionar: já que torna as consultas mais rápidas, devemos usar sempre?

A resposta é não! Sempre devemos considerar o problema que se está


tratando. Devemos ser capazes de medir se irá ou não valer a pena utilizar
o esquema de dados, ou seja, medir se o ganho em desempenho será tão
recompensador para valer a pena abrir mão da flexibilidade. Veja que, mesmo
usando o esquema, ainda assim temos uma inclusão, que tende a ser mais rápida
que uma realizada no modelo relacional. O modelo relacional deve garantir
todas as propriedades ACID, enquanto os BDs NoSQL relaxam ou ignoram essas
propriedades.

Agora que conhecemos o modelo de dados orientado a documentos


e sabemos como o armazenamento de dados funciona precisamos entender as
outras características desse modelo. Existem diversos sistemas NoSQL orientados
a documentos, vejamos alguns exemplos:

• MongoDB.
• CouchDB.
• RavenDB.
• LotusNotes.

Todos eles possuem suas estruturas de armazenamento e algoritmos de


manipulação. O MongoDB, por exemplo, utiliza documentos no formato BSON
para armazenar seus dados, já o CouchDB utiliza JSON. Apesar disso, todos
compartilham algumas características de funcionamento.

BDs orientados a documento, geralmente, possuem uma arquitetura


baseada em réplicas através de nós mestre e nós escravos/trabalhadores, ou

34
TÓPICO 3 | BANCOS ORIENTADOS A DOCUMENTOS

seja, um nó mestre é responsável por manter a versão mais atual dos dados e é
responsável por receber e executar as operações de escrita (inserção, atualização e
exclusão). Esse nó é ligado a nós configurados como trabalhadores que armazenam
réplicas dos dados. Essas réplicas são utilizadas apenas para leitura. Caso o nó
mestre pare de funcionar, um dos nós trabalhadores tomará seu lugar. O número
de réplicas é configurado pelo usuário.

BDs orientados a documentos suportam diferentes níveis de consistência.


Por padrão, a fim de maximizar o desempenho na escrita e leitura de registros,
o sistema suporta consistência eventual, assim como os BDs chave-valor. Deve-
se lembrar que os BDs NoSQL sacrificam as propriedades ACID para obter um
bom desempenho e serem capazes de lidar com grandes quantidades de dados.
Como tais sistemas são distribuídos, a consistência é uma propriedade cara, em
termos de desempenho, para se dar suporte. Quando um sistema garante forte
consistência, ele considera que todos os usuários sempre terão a visão da mesma
base de dados, dos mesmos registros em sua versão mais atual. Desse modo,
quando uma inserção ocorre, todas as réplicas devem receber os dados envolvidos
antes de retornar para o usuário uma resposta positiva para o armazenamento, o
que pode acarretar em locks em coleções de documentos.

Além da consistência eventual, alguns desses BDs permitem que o usuário


possua níveis maiores de consistência. Essa variação vai desde a consistência
eventual até uma consistência forte. Geralmente, para cada operação é permitido
que se defina uma consistência específica. Por exemplo, ao executar uma inserção
em um cluster que possui três nós (um mestre e dois trabalhadores), configura-se a
operação a ser executada por pelo menos um nó réplica. Dessa forma, tem-se uma
consistência um pouco maior que uma consistência eventual padrão, porém ainda
assim existe uma janela temporal de inconsistência no sistema. Eventualmente pode-
se forçar essa operação a ser fortemente consistente configurando-a para executar
em todos os nós trabalhadores. Desse modo, é evidente que neste último cenário a
operação terá um desempenho inferior a uma inserção realizada em apenas um nó,
já que precisa coordenar a inserção em três nós (o mestre e suas réplicas).

Assim como os BDs chave-valor, os orientados a documentos apenas


permitem transações atômicas sobre um único registro. Nesse sentido, tais BDs
suportam transações atômicas sobre operações em um único documento. Alguns
BDs suportam inclusões em grupo, porém, caso uma inserção retorne falha, as
inserções que já aviam sido inseridas não são desfeitas. Por exemplo, se eu criar
um grupo de inserção com dez elementos e no quinto elemento ocorrer uma falha,
as quatro inserções que já foram executas são persistentes e a partir da quinta não
são executadas.

Como você deve imaginar, os BDs orientados a documento são escalados


horizontalmente. Como a arquitetura desses BDs é uma estrutura master-slave
novos nós são adicionados no cluster como nós trabalhadores. Assim que um nó
é adicionado ao cluster, ele é conectado a outras réplicas e recebe uma réplica
dos dados. Assim que o processo de replicação é finalizado, ele começa a receber
operações de leitura.

35
UNIDADE 1 | BANCOS NOSQL

FIGURA 14 – REPLICAÇÃO MASTER-SLAVE

FONTE: <https://bit.ly/2AaOsFU>. Acesso em: 3 abr. 2020.

Como dito anteriormente, BDs orientados a documento são conhecidos


por possuírem linguagens de consulta mais robustas que o modelo chave-valor.
Cada representante dessa categoria de BDs possui suporte a diferentes estruturas
de pesquisa, porém todos possuem métodos de busca por documentos baseados
em seu valor (CATTELL, 2015). Alguns BDs possuem suporte de consultas com
agregação de valores, como contagens, somas e médias, assim como as funções
disponibilizadas pelos BDs relacionais.

De maneira geral, esses BDs não possuem funções de junção, porém


suportam operações que combinam documentos através de filtros específicos.
Alguns BDs suportam também estruturas complexas que se assemelham aos
conceitos de visões (views) do modelo relacional. O CouchDB, por exemplo,
permite que o usuário crie estruturas que pré-calculam os resultados de uma
consulta. Esses resultados podem ser calculados em tempo de execução ou
armazenados diretamente no disco (visão materializada).

Considerando as características que foram discutidas até agora, é possível


inferir algumas aplicações em que o uso de um BD orientado a documentos é
muito indicado. Aplicações que armazenam logs de eventos se comportam muito
bem nesse modelo de BD. Devido a sua natureza flexível, esse modelo de dados
pode armazenar diferentes estruturas de logs, além de, com nível eventual de
consistência, possuir baixa latência para operações de inserção, não importando
o tamanho da base já armazenada.

Além disso, devido a sua natureza de armazenamento, esse modelo de


dados se comporta muito bem para armazenar conteúdos de blogs e outras
páginas web. Em consequência de sua arquitetura robusta e suporte a consultas,
esses BDs também podem ser aplicados para análise de dados em tempo real
(dados de sensores).

Também baseados nas características desse modelo, podemos afirmar que


esses BDs não são bons para lidar com dados que possuem muitos relacionamentos.

36
TÓPICO 3 | BANCOS ORIENTADOS A DOCUMENTOS

Conforme vimos, alguns relacionamentos podem ser modelados com o modelo


de agregados, porém tal modelo pode criar documentos grandes e complexos se
os dados possuírem muitos relacionamentos. Além disso, como esses BDs não
suportam ACID, não podem ser utilizados em aplicações que necessitem utilizar
transações.

Agora que foram vistas as características desses BDs é hora de colocar a


mão na massa. Na próxima seção, realizaremos uma atividade prática utilizando o
MongoDB. A atividade não visa a apresentar todas as capacidades do MongoDB,
mas pode servir como guia para os primeiros contatos com esse BD.

3 ATIVIDADE PRÁTICA MONGODB


Existem diversos BDs orientados a documento, porém o mais utilizado é
o MongoDB. Segundo o ranking do site DB-Engine (2020), o MongoDB é o quinto
BD mais utilizado no mundo e o representante dos BDs NoSQL mais utilizado. O
MongoDB é disponibilizado em regime de código aberto pela licença GNU AGPL.

O MongoDB possui um modelo de documento baseado em documentos


no formato JSON, possuindo uma linguagem de consulta que se assemelha mui-
to à linguagem de programação JavaScript. Fisicamente, o MongoDB armazena
seus dados em documentos BSON, que são um formato binário para os documen-
tos JSON.

Esse BD é constituído de coleções de documentos, e para cada coleção te-


mos conjuntos de documentos. Assim como em todo BD orientado a documentos,
cada documento no MongoDB possui um identificador único. Esse identificador
é armazenado internamente em todos os documentos em um atributo chamado
“_id”. O atributo deve ser único para a coleção de documentos, porém o usuário
geralmente não necessita se preocupar com o seu valor, pois o Mongo gera auto-
maticamente um OBJECT ID para o campo.

O MongoDB possui suporte a diversas linguagens de programação e é de


fácil instalação. Além disso, o BD é multiplataforma, funcionando em máquinas
Windows, Linux, Solaris e Mac. Vamos demostrar a instalação do Mongo para
sistemas operacionais Linux Ubuntu e Windows. Lembrando que estas informa-
ções que serão disponibilizadas podem ser encontradas no tutorial oficial de ins-
talação do MongoDB.

Para este exemplo não necessitamos da versão mais atual. Assim, para o
usuário do Ubuntu basta rodar o comando “sudo apt install mongodb” e todos
os pacotes serão baixados e instalados. Após a instalação basta rodar o comando
“mongo” e você será direcionado para o “MongoShell”. Se você quiser dispor da
versão mais atual do Mongo no Ubuntu deve seguir as instruções de instalação
disponíveis em: https://docs.mongodb.com/manual/tutorial/install-mongodb-
-on-ubuntu/.

37
UNIDADE 1 | BANCOS NOSQL

A instalação no Windows também é muito simples, basta acessar o link:


https://www.mongodb.com/download-center/community?jmp=docs, selecionar
a opção “Windows x86 x64” na opção de “OS”, e para o campo “Package” a opção
ZIP. Após o fim do download, descompacte o arquivo. Dentro da pasta descom-
pactada acesse a pasta “bin”. Nessa pasta você encontrará alguns arquivos exe-
cutáveis. Inicialmente deve-se executar o módulo servidor do Mongo “mongod.
exe” que ficará rodando durante o exemplo inteiro. Depois de executar o servidor
só precisamos entrar no MongoShell rodando o executável “mongo.exe”.

Neste ponto, a instalação foi concluída e você deve ter aberto o Mon-
goShell. Sendo assim, você deve estar com uma tela semelhante à apresentada
na Figura 15. Nesta interface, executaremos as consultas que envolvam as opera-
ções de CRUD (Create, Read, Update and Delete – Criar, Ler, Atualizar e Excluir).
Conforme dito anteriormente, este ambiente se assemelha muito a um shell de
JavaScript, assim iremos executar alguns métodos.

FIGURA 15 – MONGO SHELL

FONTE: O autor

Inicialmente, torna-se necessário criar uma coleção de documentos para


armazenar os dados. O comando para criar uma coleção de documentos é “db.
createCollection(“nome_coleção”)”. A primeira linha da Figura 16 apresenta a
criação de uma coleção de documentos chamada “filmes”. Como estamos em um
ambiente de “programação”, para acessar qualquer informação de uma coleção
de documentos basta usar a “db.nome_colecao” e acessar os métodos que a
coleção dispõe. Para listar os documentos em nossa coleção de documentos basta
utilizar o comando “db.filmes.find()”.

FIGURA 16 – CREATE COLLECTION

FONTE: O autor

38
TÓPICO 3 | BANCOS ORIENTADOS A DOCUMENTOS

Como você já sabe, esse comando não retornaria nada já que ainda não
adicionamos nenhum documento a essa coleção. Sendo assim, vamos utilizar o
comando “insert” para adicionar um documento a nossa coleção. Para inserir
basta utilizar o comando “db.colecao.insert({atributo1: ‘valor’, atributo2: 2})”,
em que o parâmetro passado para o procedimento insert é um documento. Veja
pela Figura 17 (primeira linha) como ficará a inserção de um dos filmes. Perceba
que o diretor está como um agregado no documento principal do filme. Perceba
que o insert possui como retorno o número de linhas afetadas pela operação. Na
segunda linha vemos a busca pelos documentos da coleção de filmes.

FIGURA 17 – INSERT MONGO

FONTE: O autor

Já foi visto como realizar uma busca simples nesse modelo de dados,
porém, como dito anteriormente, a linguagem de consulta dos BDs orientados
a documentos é mais robusta e permite buscas mais refinadas no interior dos
documentos.

Para realizar essas buscas será utilizado o já conhecido comando “find”.


O comando find pode receber dois parâmetros: (1) um documento de busca e (2)
um documento de projeção. Assim, serão feitas consultas do tipo “db.colecao.
find({atributo1 : valor},{atributo1: 1, atributo2:0})”, em que o primeiro documento
representa o que está sendo buscado, nesse caso um busca por igualdade
para o valor. O segundo documento passado como parâmetro “{atributo1: 1,
atributo2:0}” representa a projeção da consulta: atributos que não são declarados
com 1 aparecem na projeção e atributos com 0 não. Quando existe uma projeção,
todos os atributos são setados por padrão como 0, apenas o _id sempre aparece.

Caso não queira que o atributo apareça, é possível removê-lo atribuindo a


ele o valor 0. A Figura 18 apresenta inicialmente uma pesquisa para buscar o nome
de todos os filmes. Perceba que o documento usado para comparações aparece
vazio. Veja que na resposta da primeira consulta também foi retornado o ‘_id’.
Para que ele não seja exibido na resposta ele deve ser explicitamente removido,
como o segundo no segundo comando.

39
UNIDADE 1 | BANCOS NOSQL

FIGURA 18 – MONGO CONSULTA POR BUSCA

FONTE: O autor

A última consulta apresentada pela Figura 18 demonstra a busca pelo


nome dos filmes que foram produzidos em 1970. Perceba que, diferentemente das
consultas anteriores, agora utilizamos também o documento de busca (primeira
parte do find). Nesse documento, é possível realizar consultas complexas sobre
os dados.

Já foi visto como utilizar o operador de igualdade, porém os outros


operadores matemáticos também são importantes. A Figura 19 apresenta uma
consulta que utiliza o operador de comparação ‘>’ (maior que) que para o
MongoDB é mapeado para ‘$gt’. O operador de menor ‘$lt’, menor e igual “$lte”,
diferente “$ne”, e maior igual “$gte”. A primeira consulta da Figura 19 apresenta
o nome dos filmes feitos após 1969.

FIGURA 19 – CONSULTA COM OPERADORES DE MAIOR

FONTE: O autor

Agora que já foi realizado algumas consultas, é possível que haja a necessi-
dade de remover alguns documentos armazenados na base de dados. O procedi-
mento utilizado para remover informações é o “remove”. O remove recebe como
parâmetro um documento que filtra os dados que serão removidos. A sintaxe para
o comando é “db.colection.remove({ atributo: valor})”. O documento passado como
parâmetro tem a mesma sintaxe que o documento passado para o método find.

40
TÓPICO 3 | BANCOS ORIENTADOS A DOCUMENTOS

A Figura 19 apresenta um exemplo de comando para remoção de docu-


mento. O comando está removendo os filmes produzidos após o ano de 1969.
Perceba que assim como o método de insert, o método remove retorna o número
de tuplas afetadas pela sua execução.

MongoDB possui uma linguagem de consulta bem robusta e que possui


suporte a agregações e agrupamentos. Infelizmente, por limitações de espaço,
não podemos explorar toda a riqueza dessa linguagem de consulta. Mais infor-
mações sobre a linguagem de consulta do MongoDB podem ser encontradas em
sua documentação, disponível no link: https://docs.mongodb.com/manual/intro-
duction/.

41
RESUMO DO TÓPICO 3
Neste tópico, você aprendeu que:

• Os BDs orientados a documentos armazenam seus dados em documentos com


estruturas hierárquicas em forma de árvores.

• Os BDs orientados a documentos são constituídos de coleções de documentos,


cada coleção possui diversos documentos. Um documento precisa de um nome
único (para a coleção) e armazena uma série de atributos.

• Atributos podem possuir valores simples (inteiros, caracteres, datas, entre


outros) ou valores complexos (vetores, matrizes, outros documentos, estrutura
chave-valor, entre outros).

• Geralmente, os BDs possuem linguagens de consultas mais robustas que


permitem consultas complexas sobre os dados.

• Os BDs orientados a documentos possuem suporte a diferentes níveis de


consistência.

• A escalabilidade e alta disponibilidade são alcançadas por meio de uma


arquitetura baseada em replicação.

42
AUTOATIVIDADE

1 Elenque os pontos positivos e negativos da utilização dos BDs Orientados


a Documentos, explicando sua visão do motivo pelo qual esse é um ponto
positivo ou negativo do modelo de dados.

2 Compare três características do modelo orientado a documento com


características do modelo chave-valor.

3 Imagine que estamos montando uma aplicação que envolve dados oriundos de
diferentes tipos de sensores. Alguns sensores retornam informações referentes
à temperatura, outros à umidade do ar, outros à intensidade do vento, mas
todos consideram local, data e hora da coleta das informações. Justifique se
você considera ou não essa uma aplicação em que deve ser utilizado o modelo
orientado a documentos para persistência dos dados.

43
44
UNIDADE 1
TÓPICO 4

BANCOS ORIENTADOS A COLUNAS

1 INTRODUÇÃO
Já foram vistos dois dos quatros modelos de dados dos BDs NoSQL.
Conhecemos os modelos de dados e como funcionam suas linguagens de
consulta. Além disso, discutimos como cada um deles trabalha internamente e
quais os possíveis casos de uso.

Devemos continuar lembrando que os BDs NoSQL não surgiram para


dominar todo o mercado e suprimir o modelo relacional. Surgiram para atender
a alguns nichos que o relacional não conseguia tratar. Nesse sentido, surgiram
de a necessidade de algumas aplicações não necessitarem mais toda a robustez
e a rigidez oferecida pelo modelo relacional de dados. Considerando isso, é
importante ressaltar que não existe um modelo de dados NoSQL melhor que
outro. Cada modelo de dados serve para um tipo específico de problema, e este
curso tem como objetivo nos proporcionar um entendimento acerca de cada um
desses modelos. Assim, seremos capazes de selecionar o BD correto para cada
tipo de demanda de nossas aplicações.

Com isso em mente, passamos para o próximo modelo de dados. O modelo


orientado a colunas, assim como o orientado a documentos, é uma espécie de
especialização do modelo chave-valor. Sendo assim, ele faz parte dos chamados
modelos de dados baseados em chave de acesso.

Da mesma forma que o modelo de dados anterior, o modelo orientado


a colunas possui suporte a uma linguagem de consulta mais complexa que
os modelos chave-valor. Esses BDs permitem uma estrutura mais robusta de
armazenamento que é otimizada para consultas baseadas em identificadores para
as linhas. Sua estrutura favorece consultas que são frequentemente executadas
nos modelos, como as consultas empregadas na geração de relatórios.

Assim, neste tópico, exploraremos a estrutura dos BDs orientados a


colunas. Como nos tópicos anteriores, estudaremos a organização do seu modelo
de dados conhecendo suas estruturas conceituais. Posteriormente, vamos conhecer
as características de sua linguagem de consulta e como esses bancos trabalham
consistência, escalabilidade e outras características. Por fim, executaremos um
exemplo prático utilizando o Cassandra DB.

45
UNIDADE 1 | BANCOS NOSQL

2 MODELO DE DADOS E ARQUITETURA


Diferente dos modelos apresentados até agora, o modelo de colunas
possui como conceito geral de armazenamento uma estrutura colunar. Podemos
dizer que muitos desses BDs são vistos como uma grande tabela (CATTELL,
2015). Nesta tabela, como em uma tabela normal, temos linhas e colunas. Cada
uma das linhas é identificada unicamente e possui um conjunto de colunas.
Nesse sentido, vemos uma semelhança com o modelo relacional de dados que
também armazena os seus dados em tabelas. No modelo relacional, os dados são
geralmente armazenados em linhas (salvo em BDs particionados verticalmente),
o que faz com que diversas otimizações sejam executadas sobre as linhas de uma
tabela; no modelo orientado a colunas, os dados são armazenados de maneira
estruturada pelas colunas.

Assim como nos tópicos anteriores, vale ressaltar que cada BD NoSQL
orientado a colunas tem sua forma peculiar de organização. Vamos ver neste
tópico a estrutura básica de um BD orientado a colunas, no entanto, os conceitos
podem variar de nome entres os produtos.

Em geral, os BDs orientados a colunas possuem uma keyspace (espaço para


chaves) em que todos os dados são armazenados. Essa keyspace é dividida em
famílias de colunas. Famílias de colunas agrupam linhas e colunas que possuem
alguma semelhança. Uma família de colunas é composta por diversas linhas
e cada uma com um conjunto de colunas. Esse conjunto de colunas pode ser
diferente para cada linha mesmo pertencendo a uma mesma família de colunas
(SALADALAGE; FOWLER, 2012). A Figura 20 apresenta uma visão dos conceitos
de um BD orientado a colunas e sua hierarquia.

FIGURA 20 – ESTRUTURA BD ORIENTADO A COLUNAS

FONTE: O autor

46
TÓPICO 4 | BANCOS ORIENTADOS A COLUNAS

Considerando que você conhece bem o modelo de dados relacional, vamos


novamente traçar um paralelo entre os modelos. Assim, o Quadro 3 apresenta
uma visão do mapeamento entre os dois modelos de dados. Perceba que uma
base de dados é comparável a uma keyspace, a keyspace é o espaço responsável
por armazenar todos os dados de uma aplicação. Em uma instalação de um BD
orientado a colunas, é comum existir mais de uma keyspace. Tabelas podem
ser mapeadas para famílias de colunas, uma família de colunas é utilizada para
armazenar, de maneira mais próxima, conjuntos de colunas. Uma tupla do modelo
relacional pode ser mapeada para um conjunto de colunas do modelo orientado a
colunas. As chaves primárias podem ser mapeadas para o identificador de linhas.

QUADRO 3 – MAPEAMENTO RELACIONAL PARA DB ORIENTADO A COLUNAS

Banco Relacional NoSQL documento


Base de dados Keyspace
Tabela (relação) Família de Colunas
Linha (tupla) Linha/Conjunto de Colunas
Identificador da tupla Identificador da linha/Chave
FONTE: O autor

Vale ressaltar que essa é uma proposta de mapeamento que pode ou não
ser a melhor. Sempre quando modelamos uma abordagem devemos considerar
como esses dados serão acessados.

Quando criamos uma base de dados em um BD orientado a colunas,


devemos ter em mente que, apesar de semelhante, esse modelo de dados tem
conceitos distintos de um BD relacional. Assim, devemos criar as famílias de
colunas cuidadosamente, levando em consideração quais as consultas que iremos
posteriormente executar. Geralmente, a abordagem mais simples a ser seguida é
não deixar os dados normalizados da mesma forma que o modelo anterior.

A Figura 21 apresenta o mapeamento dos dados do já conhecido BD


relacional Cinema para o modelo de dados orientado a colunas. Perceba que o
mapeamento que foi adotado é o mesmo apresentado pelo Quadro 3. Cada uma
das tabelas foi mapeada para uma Família de colunas distinta. Como você deve
imaginar, poderíamos ter armazenado as informações de diretores diretamente
na família de colunas Filmes. Essa seria uma ação necessária para conseguirmos
executar consultas que combinam o filme com seu respectivo diretor. Cada coluna
da tupla relacional é mapeada para uma coluna simples no modelo orientado a
colunas. Perceba também que a chave para acesso de cada linha é o valor da chave
primária da tupla.

47
UNIDADE 1 | BANCOS NOSQL

FIGURA 21 – MAPEAMENTO BD CINEMA PARA O MODELO DE DADOS ORIENTADO A COLUNAS

FONTE: O autor

Esse mapeamento, apesar de trivial, pode ser utilizado para um grande


número de casos. A forma de realizar o mapeamento ou mesmo de armazenar
os dados deve ser considerada para cada tipo de uso de BD. Esse modelo terá
problemas para responder consultas que combinem as famílias de colunas Filmes
com seus respectivos diretores. Se essa for uma consulta muito frequente, as duas
coleções de documentos deveriam ser fusionadas.

O modelo de dados orientado a colunas é otimizado para buscas


relacionadas à chave de suas linhas. De fato, alguns BDs nem suportam buscas dos
dados que não envolvam diretamente os valores das chaves. Desse modo, ele se
torna um ponto muito crítico no desenvolvimento de abordagens que utilizem o
modelo orientado a colunas. No caso do exemplo, vamos imaginar que a consulta
mais frequente, na nossa base de dados, é a busca por filmes relacionados a um
ano específico.

Por exemplo, o usuário realiza a busca dos filmes que foram lançados em
1970. Para que essa consulta tenha um ótimo desempenho é necessário adicionar
o ano ao identificador de cada uma das linhas. De maneira geral, é como se fosse
criada uma chave primária composta pelo id do filme e seu ano. Isso fará com que
a base de dados armazene filmes que possuam o mesmo ano de lançamento em
locais próximos. Assim, quando a busca pelos filmes de um determinado ano for
executada, a consulta terá ótimo desempenho.

48
TÓPICO 4 | BANCOS ORIENTADOS A COLUNAS

Imaginamos que você deve ter pensado que isso se assemelha muito a
um índice em um banco relacional. De fato, o armazenamento de chaves em um
BD orientado a colunas é semelhante a um valor indexado. A diferença é que
no BD orientado a colunas os dados são fisicamente armazenados considerando
os valores de chave, o que torna a busca de dados muito rápida. Sabemos que
a busca de uma chave no modelo chave-valor é O (1), a busca de uma chave no
modelo orientado a colunas não é tão rápida, mas atinge um patamar semelhante,
com a vantagem que para esse modelo as chaves são construídas por colunas, o
que facilita a busca dos dados e permite consultas mais complexas.

É importante ressaltar que, apesar das famílias de colunas se assemelharem


conceitualmente a uma tabela, elas, por definição, não possuem um esquema.
Nesse sentido, os conjuntos de colunas armazenados para uma determinada
família de colunas não precisam seguir uma mesma estrutura. Alguns BDs
orientados a documentos possuem uma estrutura mais rígida e necessitam de
um esquema. O Cassandra, por exemplo, torna obrigatório o uso de um esquema.
Como dito anteriormente, um esquema traz consigo o bônus de otimizações na
execução de consultas. Mesmo que alguns dos BDs dessa categoria possuam
um esquema como obrigatório, a maneira com que os dados são tratados no
armazenamento é diferente do modelo relacional. Nos BDs orientados a colunas,
como o armazenamento é feito baseado na coluna, colunas nulas não são
armazenadas. Mesmo que no esquema a coluna exista, se ela for opcional e não
estiver presente na linha, ela não é armazenada.

Além desses conceitos, alguns BDs possuem o conceito de supercolunas.


Uma supercoluna pode ser vista como uma coluna que contém outras colunas, ou
seja, em geral, é uma coluna que contém pares chave-valor. A supercoluna pode
ser vista como uma utilização do conceito de agregados, mas, como já afirmamos,
nem todos os BDs suportam.

Embora BDs do modelo orientado a colunas não suportem chaves


estrangeiras, algumas implementações de algoritmos de junções já estão
disponíveis. De maneira geral, esses BDs apenas aceitam realizar junções de
famílias de colunas distintas e as colunas envolvidas na condição de junção
devem obrigatoriamente fazer parte da chave de acesso das linhas. Operações
de junção são operações caras e demandam uma queda de desempenho, dessa
forma, mesmo as abordagens que permitem seu uso o desencorajam.

Apesar de suportarem junções, as linguagens de consulta desenvolvidas


para BDs colunares, geralmente, são limitadas se comparadas às linguagens dos
BDs orientados a documentos. Um ponto interessante é que grande parte desses
BDs possuem uma linguagem de consulta com sintaxe semelhante à linguagem
SQL. O Cassandra, por exemplo, utiliza como padrão a linguagem de consulta
CQL que possui uma sintaxe muito semelhante à linguagem SQL (para não dizer
igual). Aprendemos um pouco mais sobre o CQL na próxima Seção.

Geralmente, esses BDs possuem uma arquitetura de master e slave


diferenciada, implementada através de um anel lógico. As escritas são executadas

49
UNIDADE 1 | BANCOS NOSQL

em um nó mestre e replicadas para os demais nós, sendo que a replicação pode


ser feita de maneira síncrona ou assíncrona. No entanto, o diferencial dessa
arquitetura é que todos os nós possuem o mesmo papel e prioridade, ou seja,
todos são iguais e qualquer um pode vir a ser mestre ou trabalhador.

Quando um nó recebe uma operação de escrita ele se torna um mestre,


executa a escrita e depois envia os dados para as réplicas (nós trabalhadores).
Depois que o processo de replicação é encerado, esse nó torna-se novamente
um nó regular e o cluster fica sem mestre até a próxima instrução de escrita. É
importante ressaltar que as requisições são distribuídas pelo anel a fim de manter
todo o sistema balanceado (em nível de cargas).

BDs orientados a colunas também suportam níveis diferentes de


consistência. Geralmente, esses sistemas empregam consistência eventual. Dessa
forma, escritas são realizadas em um mestre e depois replicadas assincronamente
para as réplicas, permitindo uma baixa latência para operações de escrita. Da
mesma forma que os sistemas orientados a documentos, é possível configurar
maiores níveis de consistência aumentando o número de réplicas que devem
responder a uma instrução de escrita. Por exemplo, imagine que possuímos um
cluster de três nós. Se executarmos uma instrução de escrita e configurarmos
o sistema para que a instrução seja fortemente consistente, a inclusão só será
finalizada quando o dado for inserido nas três máquinas.

Já sabemos que a escrita pode ser executada de maneira consistente, porém


como funcionam as leituras neste ambiente? Se o BD for configurado para assegurar
forte consistência, todas as suas operações devem ser executadas em todos os
nós. Quando uma leitura é executada nesse ambiente todos os nós retornam uma
resposta para o nó que recebeu a requisição inicial (o nó mestre). Esse nó mestre
compara as respostas recebidas, e, caso todas coincidam, ele as retorna. Caso as
respostas divirjam, é utilizado um algoritmo de “quórum” que verificará entre
as respostas retornadas qual se repete mais, e esta será retornada. Em sistemas
orientados a colunas, também é possível estabelecer um número mínimo de nós
para o algoritmo de “quórum”, ou seja, qual o número mínimo de nós que devem
retornar à mesma resposta para que essa seja considerada correta. Caso esse número
não seja alcançado, o sistema retorna um erro ou, em alguns casos, retorna todas as
respostas possíveis para que o usuário selecione a mais adequada.

Adicionalmente, alguns sistemas orientados a colunas, como o Cassandra,


guardam com os dados a data e a hora (timestamp) de quando esses dados foram
gerados. Quando se trata de consistência, o algoritmo de quórum deve considerar
também os dados com o timestamp mais novo, ou seja, o dado mais atual deve ser
retornado. Dessa forma, o quórum deve ser atingido para uma leitura, e o dado a ser
retornado deve possuir o maior timestamp. Caso o timestamp mais atual não possua
o quórum necessário, um erro é retornado, pois o banco terá perdido a consistência.

Perceba que a consistência é levada muito a sério neste modelo de dados.


Esses BDs são conhecidos por proporcionarem bons níveis de consistência

50
TÓPICO 4 | BANCOS ORIENTADOS A COLUNAS

(CATTELL, 2011). No entanto, como dito anteriormente, esses BDs, por padrão,
trabalham com consistência eventual primando pelo suporte à alta disponibilidade.

Já que tocamos no assunto da alta disponibilidade, é importante notar que


essa característica é provida pelos BDs orientados a coluna de maneira diferente
dos demais. Devido a sua arquitetura em que qualquer nó pode vir a ser um
mestre, escritas são executadas mais rapidamente. Perceba que qualquer nó pode
realizar uma escrita e, caso a consistência eventual seja mantida, essa escrita é
realizada em um mestre e replicada assincronamente pelo cluster, tornando o
processo ainda mais rápido.

Assim como os demais modelos de dados anteriores, os BDs orientados a


colunas somente possuem suporte a transações atômicas sobre um único registro.
Assim, uma transação no modelo orientado a colunas somente pode ser realizada
para a inclusão/manipulação de uma única linha. Transações com múltiplas
linhas, aos moldes do modelo relacional, não são suportadas.

Geralmente esses BDs possuem a escalabilidade horizontal como


requisito. Dada a natureza de sua arquitetura, a dição de novos nós ao cluster é
simples. Além disso, se considerarmos que qualquer nó do cluster pode executar
tanto leituras quanto escritas, aumentar o número de nós pertencentes ao cluster
aumenta a capacidade de processamento.

Agora que conhecemos as estruturas desse modelo de dados, sua


capacidade de consulta e a maneira geral que sua arquitetura trabalha somos
capazes de entender quais os problemas que melhor se adequam a sua estrutura.

Assim como o modelo de dados orientado a documentos, esse modelo


pode ser utilizado para atividades de log do sistema. Claro que, utilizando um
modelo orientado a colunas, não iremos dispor da flexibilidade da estrutura
proporcionada pelo modelo de documentos, porém a arquitetura desses BDs
permite escalar com mais facilidade o número de escritas. Lembre-se de que o
modelo orientado a documentos, geralmente, centraliza suas escritas em um nó
mestre, enquanto no modelo orientado a colunas qualquer nó do cluster está apto
a executar operações de escrita.

Esses BDs também podem ser utilizados em aplicações que fornecem


demonstrações de uso ou mesmo anúncios que são exibidos por um determinado
tempo. Alguns BDs desse tipo possuem funcionalidades de TTL (Time to Live) para
colunas. Essa funcionalidade permite que colunas desapareçam automaticamente
depois de um tempo predeterminado.

BDs orientados a colunas não devem ser utilizados em aplicações que


necessitam das propriedades ACID. Como vimos, esses BDs não são capazes
de executar transações sobre múltiplas linhas. Além disso, tais BDs não devem
ser utilizados em aplicações que mudam constantemente suas consultas sobre
os dados. Sabemos que esse modelo de dados é otimizado para consultas que

51
UNIDADE 1 | BANCOS NOSQL

buscam os valores pertencentes à chave de identificação da linha. Caso as


consultas sofram constantes mudanças, seriam necessárias mudanças nas chaves
de acesso e, consequentemente, a reorganização dos dados.

Nesta seção exploramos as características gerais do modelo orientado a


colunas, discutimos as estruturas do modelo de dados, a capacidade de consultas
e como a arquitetura se comporta. Explicitamente conhecemos apenas a estrutura
geral desses BDs e sabe-se que cada um dos representantes dessa categoria possui
suas peculiaridades. Existem vários BDs orientados a colunas e seria interessante
usar alguns deles, porém poderemos realizar atividades práticas com apenas um
representante desta categoria. Na próxima seção realizaremos um estudo prático
utilizando o Cassandra.

3 ATIVIDADE PRÁTICA CASSANDRA


O Cassandra é um BD orientado a colunas desenvolvido inicialmente pelo
Facebook. Desde 2009, o sistema é open source e mantido pela Apache Foundation.
Diferentemente dos demais BDs que estudamos até aqui, o Cassandra é
essencialmente um BD distribuído. Ele possui uma arquitetura descentralizada
em forma de anel em que qualquer nó pode assumir o papel de mestre.

O Cassandra é compatível com sistemas Linux e Mac. Sua instalação é


simples e nesta seção abordaremos rapidamente como procedê-la. Incialmente,
acesse o terminal do Linux e digite o seguinte comando:

FIGURA 22 – COMANDO PARA ADICIONAR O REPOSITÓRIO DO CASSANDRA

echo "deb http://www.apache.org/dist/cassandra/debian 311x main" |


sudo tee -a /etc/apt/sources.list.d/cassandra.sources.list

FONTE: O autor

Após sua execução, é necessária a inclusão das chaves do repositório


oficial da Apache:

FIGURA 23 – COMANDO PARA ADICIONAR AS CHAVES DO REPOSITÓRIO

curl https://www.apache.org/dist/cassandra/KEYS | sudo apt-key add -

FONTE: O autor

Então, atualize as informações do repositório de sua máquina e instale o


Cassandra:

52
TÓPICO 4 | BANCOS ORIENTADOS A COLUNAS

FIGURA 24 – COMANDOS PARA ATUALIZAR OS PACOTES E INSTALAR O CASSANDRA

sudo apt-get update


sudo apt-get install cassandra

FONTE: O autor

Para que possamos executar alguns comandos de exemplo, utilizaremos o


“CQLSQ” que é um terminal produzido pela Apache que permite a execução de
comandos CQL. Para acessar o sistema basta digitar “cqlsh” no terminal. Se tudo
estiver correto, você deve estar visualizando uma tela semelhante à Figura 25.

FIGURA 25 – CASSANDRA SHELL

FONTE: O autor

Como já dito anteriormente, o Cassandra possui uma linguagem de


consulta chamada CQL (Cassandra Query Language) que se assemelha muito à
SQL. O Cassandra é constituído de uma keyspace composta por famílias de colunas
(também pode ser utilizado tabela). Cada família de colunas possui uma série de
linhas e cada uma delas é identificada por uma chave (rowid). Essa chave é obtida
pela combinação dos valores de chaves primárias declaradas para a família de
colunas. Vamos começar criando uma keyspace para nosso exemplo.

Uma keyspace pode ser vista com uma base de dados. O comando para
criar uma keyspace é o “CREATE KEYSPACE”. Como você pode ver na Figura
26, este comando precisa de alguns parâmetros específicos. Um dos parâmetros
é o nome, no caso do exemplo, foi criada a keyspace “Cinema”. Repare que junto
aos parâmetros estão sendo passados a estratégia de replicação e qual o fator de
replicação utilizado. Isso é utilizado para configurar os níveis de consistência do
keyspace, quanto maior o fator de replicação, maior o nível de consistência (limitado
ao número de nós participantes do cluster). Após a criação, basta utilizar o comando
“USE nome_keyspace” para selecionar a keyspace em que os dados serão inseridos.

FIGURA 26 – KEYSPACE

FONTE: O autor

53
UNIDADE 1 | BANCOS NOSQL

Como o Cassandra organiza todos os dados de suas famílias de colunas


baseado nas chaves de acesso, o esquema é obrigatório. Assim, criaremos o esquema
para nossas duas famílias de colunas: Filmes e Diretores. Conforme a Figura
27, perceba que a sintaxe é muito semelhante à SQL, inclusive, opcionalmente,
poderia ser utilizada a palavra “TABLE” no lugar de “COLUMNFAMILIE”.

FIGURA 27 – CRIANDO FAMÍLIAS DE COLUNAS

FONTE: O autor

Após criado o esquema de todas as famílias de colunas, podemos iniciar


a inserção dos dados. A Figura 28 mostra a inserção dos dados. Você deve estar
pensando que se trata de uma SQL, de fato, a linguagem é muito semelhante.

FIGURA 28 – INSERÇÃO DOS DADOS

FONTE: O autor

Após a inclusão dos dados, podemos iniciar a consulta. A consulta


dos dados não se difere muito da SQL, existem algumas pequenas diferenças
relacionadas à forma do Cassandra trabalhar. A Figura 29 mostra duas consultas,
a primeira simplesmente busca os dados da família de colunas, e a segunda busca
o nome do diretor com id = 2. Perceba que ambas as consultas são idênticas ao que
seria executado em SQL.

54
TÓPICO 4 | BANCOS ORIENTADOS A COLUNAS

FIGURA 29 – CONSULTA CQL

FONTE: O autor

Uma diferença importante entre as consultas SQL e as realizadas em CQL é


que no Cassandra apenas são permitidas consultas que acessem a chave primária da
família de colunas. Lembre-se que discutimos isso na seção anterior: os dados são
armazenados fisicamente no Cassandra baseados na chave de acesso (primary key).
Consultas que executam filtros sobre valores de colunas que não fazem parte da
chave de acesso possuem um desempenho ruim. Para permitir que essas consultas
sejam executadas, deve ser adicionado ao fim da consulta os tokens “ALLOW
FILTERING” que dizem ao Cassandra para ignorar os problemas de desempenho
da consulta. A Figura 30 apresenta uma consulta em atributo não chave, com o seu
respectivo erro. Depois, a mesma consulta com o Token, forçando a execução.

FIGURA 30 – CONSULTAS COM ALLOW FILTERING

FONTE: O autor

A exclusão de valores e atualização é executada da mesma forma que no


modelo relacional. Assim, não é necessário que executemos os comandos.

Com isso, encerramos mais essa atividade prática. Esperamos que a


experiência tenha sido interessante e que tenha despertado seu interesse pelo
CQL. Outros BDs orientados a colunas como o HBase possuem linguagens de
consultas mais robustas. No entanto, o desempenho e a facilidade de uso do
Cassandra o mantém no topo dos BDs orientados a colunas há muitos anos.

55
RESUMO DO TÓPICO 4
Neste tópico, você aprendeu que:

• Os BDs orientados a colunas armazenam seus dados baseado em conjunto de


colunas identificadas por uma chave de acesso.

• De maneira geral, esse BD é constituído de uma keyspace que armazena diversas


famílias de colunas. Cada família de colunas possui um conjunto de linhas/
conjunto de colunas. Linhas são identificadas por uma chave única obtida
através da combinação de valores das colunas de chave.

• A chave de acesso das colunas deve ser criada com base nas colunas que são
mais frequentemente acessadas pelas consultas.

• Os dados são organizados fisicamente no disco baseados nas chaves de acesso,


dessa forma, a consulta sobre a chave possui um desempenho elevado.

• Esses BDs possuem uma arquitetura baseada em um anel em que qualquer nó


pode executar operações de leitura e escrita.

• Suportam diferentes níveis de consistência, sendo que o padrão é a consistência


eventual por permitir um melhor desempenho.

• Esses BDs não são bons para aplicações que possuem mudanças constantes nas
colunas consultadas, pois os dados são armazenados baseados nos valores das
colunas que compõem a chave de acesso.

56
AUTOATIVIDADE

1 Com base nos conhecimentos discutidos neste tópico apresente as principais


características do modelo orientado a colunas.

2 Já que conhecemos afundo o modelo de dados orientado a documentos e o


modelo orientado a colunas. Descreva as principais diferenças entre esses dois
modelos e quais as implicações técnicas no uso de cada um deles.

57
58
UNIDADE 1
TÓPICO 5

BANCOS ORIENTADOS A GRAFOS

1 INTRODUÇÃO
Estamos nos encaminhando para o fim do conteúdo relacionado aos BDs
NoSQL. Até agora aprendemos que BDs NoSQL, de maneira geral, são BDs não
relacionas que possuem como premissas a alta disponibilidade e a escalabilidade
horizontal. Além disso, esses BDs não seguem o modelo relacional de dados e
possuem suas próprias linguagens de consulta.

Segundo Sadalage (2012), os modelos de dados dos BDs NoSQL podem


ser classificados em quatro: chave-valor, orientado a documentos, orientado a
colunas e orientado a grafos. Até agora já exploramos três modelos de dados
distintos. O chave-valor que, apesar de usa simplicidade e de apenas permitir
consultas diretamente nas chaves de acesso, é o mais rápido na busca pelos
valores armazenados em uma determinada chave. Estudamos também o modelo
de dados orientado a documentos, que possui uma estrutura mais flexível de
armazenamento e uma linguagem de consulta robusta. Conhecemos a pouco os
BDs orientados a colunas que possuem diferentes níveis de consistência e uma
arquitetura otimizada para a inserção de dados.

Sendo assim, só nos falta conhecer os BDs orientados a grafos. Esses


BDs possuem um modelo de dados bem distinto dos demais. Até agora apenas
conhecemos BDs baseados em chave de acesso, e o modelo orientado a grafos
não pode ser classificado dessa maneira. Sua estrutura de grafo é otimizada para
o armazenamento de dados que possuem conexões/relacionamentos e não mais
para a busca de valores por determinada chave.

Deve-se lembrar sempre a importância de conhecer a fundo cada um dos


modelos de dados, sendo capaz de entender qual o modelo mais adequado para
cada tipo de problema. Note que não nos referimos apenas aos modelos de dados
NoSQL, mas também ao modelo relacional. É de suma importância que você,
através deste material, consiga entender o funcionamento dessas estruturas de
dados e seja capaz de selecionar a tecnologia correta para cada tipo de problema.

Neste tópico, conheceremos o modelo orientado a grafos. Como nos tópicos


anteriores, inicialmente, exploraremos a estrutura de dados e conheceremos
sua capacidade de representação. Então, estudaremos a capacidade de consulta

59
UNIDADE 1 | BANCOS NOSQL

desse modelo e como é sua arquitetura. Por fim, realizaremos uma atividade
prática visando a um primeiro contato com essa tecnologia. Para a atividade será
utilizado o BD NoSQL Neo4J.

2 MODELO DE DADOS E ARQUITETURA


O conceito de relacionamento entre dados pode ser considerado uma das
bases para a abstração do modelo de dados relacional. Perceba que o modelo
relacional, de maneira geral, armazena registros e suas respectivas relações. Se
considerarmos os modelos de dados dos BDs NoSQL que estudamos até agora,
não temos nenhum representante que modele de fato o relacionamento entre os
dados. Claro que de certa maneira o uso de agregados pode ser visto como uma
solução para armazenar a relação entre os dados. No entanto, como vimos, é uma
solução interessante apenas quando se trata de um relacionamento simples.

O modelo orientado a grafos foi desenvolvido com o intuito de suprir esse


tipo de demanda. Desse modo, esse modelo surgiu da necessidade de representar
relações e ligações entre os dados. Você deve ter imaginado que isso poderia
ser tratado facilmente pelo modelo relacional, mas, neste caso, isso trata-se de
um engano. Podemos criar estruturas de comportamento no modelo relacional,
porém algumas consultas que envolvam buscas de caminhos (não geográficos,
mas caminhos entre as conexões dos dados) se tornam excessivamente complexas
no modelo relacional.

Por exemplo, imagine que estamos armazenando dados de certa rede


social. Redes sociais geralmente permitem que pessoas possuam um perfil
e se conectem entre elas através de uma relação de amizade. Modelando esse
problema para o modelo relacional, teríamos basicamente duas tabelas, uma para
armazenar os perfis de usuários e outra para as conexões. Se eu quisesse buscar
os amigos de um determinado perfil seria muito simples já que bastaria uma
consulta em perfil e uma operação de junção com a tabela de conexões. Agora
imagine que eu preciso retornar os amigos dos meus amigos. Essa consulta em
SQL teria uma alta complexidade e um desempenho ruim. Acreditamos que você
concorde que essa é uma situação recorrente em uma rede social e, se abstrairmos
o exemplo, essa estrutura de consulta pode ser mapeada para outros problemas
(por exemplo, classificação de perfil para inferência de marketing, sistemas de
recomendação, entre outros).

Esse tipo de necessidade motivou o surgimento de um modelo de dados


que possuísse como característica principal o emprego de estruturas otimizadas
para acesso de relacionamentos ou conexões entre os dados. BDs NoSQL
orientados a grafos possuem como conceito central, como o nome sugere, o
modelo de grafos.

Lembre-se que um grafo é basicamente uma estrutura que possui nós e


arestas (CORMEN et al., 2012). Os nós podem ser vistos como objetos, e arestas

60
TÓPICO 5 | BANCOS ORIENTADOS A GRAFOS

representam relações entre dois nós distintos. Segundo Sadalage (2012), o modelo
orientado a grafos, assim como um grafo tradicional, possui uma estrutura baseada
em nós e arestas. Cada nó possui um identificador e conjunto de atributos. As
arestas conectam dois nós e também possuem um nome (não necessariamente
único) e um conjunto de atributos e valores. Além disso, geralmente, em BDs
orientados a grafo, as arestas possuem uma direção, ou seja, cada aresta possui
uma origem e um destino definidos. A Figura 31 apresenta uma visão da
organização dos dados armazenados em um BD orientado a grafos.

FIGURA 31 – EXEMPLO DE UM MODELO ORIETADO A GRAFOS

FONTE: Sadalage e Fowler (2019, p. 104)

Como você deve ter notado, os dados apresentados pelo BD da Figura 31


representam o exemplo de uma espécie de rede social. A figura apresenta diversos
nós e relacionamentos. Cada nó possui um tipo específico, esse tipo pode ser
modelado como um atributo. Veja que temos um nó chamado “BigCo” e todas as
conexões (arestas) que chegam a ele são do tipo “employee” (empregado). Sendo
assim, podemos inferir pelo modelo que os nós “Anna”, “Barbara” e “Carol”
são pessoas, são amigas (possuem arestas do tipo “friend”) e trabalham para
a empresa “BigCo”. Veja como a representação de grafos torna-se rica para o
armazenamento de conexões entre os dados.

61
UNIDADE 1 | BANCOS NOSQL

Como vimos nos tópicos anteriores, todos os modelos de dados que es-
tudamos possuem uma forma de organizar seus dados fisicamente baseados em
uma chave de acesso. Então, seria natural pensarmos que o modelo orientado
a grafos também realiza alguma otimização nesse formato. Essa afirmação está
parcialmente correta. Lembre-se, primeiramente, que o modelo orientado a gra-
fos não possui o conceito de chave de acesso como os demais representantes dos
BDs NoSQL. No entanto, esses BDs otimizam seu armazenamento baseado nos
relacionamentos entre os nós.

BDs orientados a colunas não possuem aspiração de serem muito rápidos


na busca de nós por seu nome ou um atributo específico, apesar de usarem índi-
ces e está busca ser relativamente rápida. Por outro lado, o foco do modelo de da-
dos orientado a grafos são as consultas realizadas sobre os relacionamentos entre
os nós. Assim, o fundamento do desempenho desses BDs está em buscas que rea-
lizam operações nos caminhos (arestas) do grafo. Perceba que os relacionamentos
entre os dados não são gerados em tempo de execução, e sim são persistidos no
modelo de dados, o que torna todo o processamento muito mais eficiente.

Agora que sabemos que os dados são armazenados preconizando os re-


lacionamentos entre os nós, é de interesse ressaltar a importância de um bom
planejamento quanto aos relacionamentos utilizados. A inclusão de novos rela-
cionamentos entre nós é uma operação simples e, geralmente, BDs orientados a
grafo não possuem um limite de relacionamentos para um determinado nó. No
entanto, como os dados são organizados baseados no relacionamento, mudanças
nos relacionamentos, atualizações e exclusões são operações de alto custo já que
podem acarretar na reorganização dos dados. Assim, devemos ter cuidado ao
projetar os tipos de relacionamentos utilizados para evitar operações que reor-
ganizem grandes quantidades de dados. Claro que essa é uma situação que nem
sempre pode ser evitada. O BD possui suporte a essa reorganização, porém como
podemos lidar com grafos de dimensões gigantescas (na casa de bilhões de nós)
é importante conhecer os custos envolvidos.

BDs orientados a grafos são conhecidos por possuírem suporte em con-


sistência forte. Diferente dos demais BDs NoSQL, a maioria dos BDs dessa cate-
goria suportam as propriedades ACID. De maneira geral, esses BDs trabalham
sobre grafos conectados, sendo assim grande parte das soluções não suportam o
particionamento de seu grafo. O particionamento do grafo implicaria em diver-
sas transações distribuídas, ou seja, para executar uma determinada operação se-
quencial (andar pelo grafo), o sistema dependeria de mais de uma máquina para
executar a operação (considerando que parte do grafo está em outra máquina),
o que tornaria o processo lento. Dessa maneira, a arquitetura distribuída desses
BDs normalmente é só utilizada para replicação das informações para atingir alta
disponibilidade.

Esses BDs geralmente possuem uma arquitetura distribuída baseada em


um mestre com diversos trabalhadores. Trabalhadores armazenam réplicas dos
dados usadas para leitura, e apenas o mestre centraliza todas as escritas. Como
esses sistemas, geralmente, possuem suporte às propriedades ACID, a sincroni-
zação entre o mestre e suas réplicas é realizada de maneira síncrona. Como já

62
TÓPICO 5 | BANCOS ORIENTADOS A GRAFOS

estudamos anteriormente, replicação síncrona acarreta em maiores tempos de


resposta para o usuário, já que todas as réplicas devem ter armazenados os dados
para que a operação tenha sido completada com sucesso. Assim, alguns desses
sistemas desencorajam o uso de arquiteturas distribuídas. Poucos BDs dessa ca-
tegoria permitem o particionamento do grafo, Infinite Graph é um dos únicos. O
Neo4J permite o uso do sistema distribuído considerando o grafo particionado,
porém, caso configurado desta forma, não suporta as propriedades ACID.

Você já deve estar imaginando que como estes BDs possuem suporte às
propriedades ACID também devem possuir suporte a transações. E isso é exata-
mente o que ocorre. BDs orientados a grafos geralmente suportam transações que
operam sobre diversos nós. Durante uma transação podem ser realizadas quais-
quer operações sobre o grafo. De maneira geral, toda operação que envolve algu-
ma operação de escrita deve ser declarada explicitamente como uma transação.
Assim como as transações do modelo relacional, caso estejamos executando uma
transação com dez operações, e a última delas falhar, o BD realizará o rollback e
voltará para o estado anterior à execução da transação.

Como dito anteriormente, a disponibilidade nesses BDs é realizada atra-


vés de réplicas em uma arquitetura mestre-trabalhador. Em geral, escritas so-
mente são permitidas no mestre, porém alguns BDs dessa categoria permitem
que escritas sejam realizadas pelos trabalhadores (réplicas) desde que os dados
sejam armazenados primeiramente no nó mestre. Nesse sentido, um trabalhador
recebe uma requisição de escrita e repassa a requisição internamente para o mes-
tre, o mestre executa a operação, retorna para o trabalhador que também executa
a operação, e só então devolve o resultado para o usuário.

Segundo Sadalage (2012), a escalabilidade de um BD orientado a grafos é


complexa já que seu particionamento causa operações distribuídas que não são
desejadas. Cada BD possui um algoritmo próprio para atingir a escalabilidade,
alguns utilizam diferentes técnicas para escalar baseados em suas configurações.
Uma das formas empregadas para escalar o processamento desses BDs é aplicar
a escalabilidade vertical, ou seja, adicionar memória suficiente para que todos os
dados caibam na memória principal. No entanto, essa é uma técnica que, como
vimos, torna-se cara. Outra técnica utilizada é a adição de trabalhadores (répli-
cas) ao cluster, o que aumenta a capacidade para tratar operações de leitura. No
entanto, como esses BDs somente permitem escritas em um nó mestre, esse se tor-
na um potencial gargalo. A última técnica empregada é o particionamento basea-
do em domínio. Nesta técnica, o usuário deve conhecer o domínio da aplicação e
como os dados interagem pelas consultas, assim, esse usuário é capaz de propor,
via regras, um particionamento manual dos dados que diminuirá o número de
transações distribuídas. Essa é uma abordagem, como já dito, complexa, pois de-
pende de um domínio com consultas estáveis e de um usuário apto a propor as
partições baseado no acesso dos dados.

Outra característica que deve ser explorada para estes BDs é a capaci-
dade de consulta. Ao contrário das demais categorias de BDs NoSQL, os BDs
orientados a grafos possuem linguagens de consulta muito semelhantes entre
si. Geralmente, os BDs orientados a grafos utilizam uma linguagem baseada em

63
UNIDADE 1 | BANCOS NOSQL

Gremlin. A Gremlin é uma linguagem de domínio específica para consultas em


grafos. A maior parte dos BDs orientados a grafos apenas permitem buscas sobre
os relacionamentos dos grafos. Desse modo, apenas são suportadas operações
que percorrem o grafo e examinam os nós conforme um predicado. Alguns BDs,
por exemplo, o Neo4J, permitem que o usuário também realize consultas pelos
atributos dos nós, aceitando consultas transversais no grafo. As consultas trans-
versais envolvem atributos para os quais foram criadas estruturas de indexação.

Conhecendo adequadamente as estruturas de cada modelo de dados po-


demos inferir com mais precisão qual o modelo de dados mais adequado para um
determinado problema. No entanto, enquanto diferenciar quando é melhor utilizar
um modelo de documento ou modelo orientado a colunas pode ser uma tarefa
complexa, selecionar aplicações para aplicar o modelo orientado a grafos é muito
simples. Devida a sua característica de armazenar relacionamentos, esse modelo de
dados trata problemas muito específicos. Como você deve imaginar, esses proble-
mas devem possuir como restrição a necessidade do uso de relacionamentos.

Esse modelo de dados deve ser empregado sempre que possuímos uma
aplicação que lide com dados conectados de alguma forma. Por exemplo, você
pode utilizar grafos para representar empregados, seus conhecimentos, quais os
projetos em que trabalharam e com quais outros empregados trabalharam. Dessa
forma, posso realizar consultas para selecionar equipes efetivas e com conheci-
mento específico para realização de novos projetos.

Outra aplicação em que o modelo de grafos pode trazer benefícios é a área


de logística. Você pode representar endereços em que pacotes devem ser entre-
gues como nós do grafo, e a distância entre os endereços podem ser mapeadas
como propriedades de arestas. Assim, você pode facilmente aplicar algoritmos de
caminho ótimo para diferentes entregadores.

Perceba que, apesar de específico, o uso de BDs baseados em grafo pode


ser difundido para diversas áreas, desde que os dados possam ser modelados
através de relacionamentos entre objetos. No entanto, claramente esses BDs pos-
suem uma desvantagem quando é necessário fazer buscas por atributos, pois os
nós devem ser examinados um a um. Mesmo utilizando índices, outros modelos
de dados serão mais rápidos neste tipo de tarefa.

Desse modo, finalizamos essa seção. Agora, você conhece o modelo de


grafos e sabe de que forma esse modelo deve ser empregado. Assim, nos resta
realizar uma atividade para que você veja na prática como esse BD trabalha. No
próximo subtópico, realizaremos uma atividade utilizando o BD Neo4J.

3 ATIVIDADE PRÁTICA NEO4J


O Neo4J é o mais famoso entres os BDs orientados a grafo. Como
vimos no decorrer desse tópico, esses BDs possuem como maior característica
o armazenamento dos dados baseados em conceito de grafos. Como dito

64
TÓPICO 5 | BANCOS ORIENTADOS A GRAFOS

anteriormente, os modelos orientados a grafo, diferente dos demais, possuem


uma espécie de linguagem padrão para acesso aos dados.

A linguagem utilizada para o Neo4j é chamada de Cypher. Ela é uma


linguagem declarativa para a consulta sobre grafos. Essa linguagem permite
buscas complexas baseadas em relacionamentos (arestas) no grafo, assim como
permite a busca e a indexação de informações armazenadas nos atributos dos nós
e arestas.

Para realizar essa atividade prática não será necessária a instalação do


Neo4J na sua máquina. Basta acessar o link: https://console.neo4j.org/. Caso você
tenha interesse de instalá-lo em sua máquina para posteriores testes, o Neo4J é
multiplataforma e compatível com Linux, Windows e MAC. Mais informações
podem ser encontradas na seguinte página de instalação do produto: https://
neo4j.com/docs/operations-manual/current/installation/.

Após acessar o link do console, você verá que já existe um exemplo rodando
nesta aba. Usaremos este mesmo exemplo, porém vamos executá-los passo a
passo para que você consiga entender o funcionamento deste BD. Assim, quando
acessar link do console, será observado uma tela semelhante à Figura 32. Na parte
superior da tela (número 1), são apresentados os dados que estão armazenados
para o exemplo. Na parte superior direita (número 2), é apresentado um menu
com algumas facilidades de acesso. Inferiormente, à direita na imagem, número
3, é apresentada uma visão do grafo armazenado na base de dados. Perceba que
são exibidos os nomes de cada nó e aresta. Por fim, a última parte na imagem,
número 4, é o console em que podemos realizar nossas consultas.

FIGURA 32 – TELA NEO4J ONLINE CONSOLE

FONTE: Adaptado de: <https://console.neo4j.org/>. Acesso em: 4 abr. 2020.

65
UNIDADE 1 | BANCOS NOSQL

Inicialmente, vamos limpar a base de dados para que possamos executar


o exemplo. Então, no canto superior direito da Figura 32 (número 2), clique em
“Clear DB”. Pronto, agora que estamos com a base limpa podemos iniciar a
inclusão dos dados.

Para criar um nó no BD basta utilizar o comando “create”. Para criar


um novo nó utilizaremos a seguinte sintaxe “create (nome_nó: tipo_nó
{atributos:valores})”. Note que o nome_nó é uma espécie de variável que pode ser
utilizada em transações, as quais serão executadas em breve. Para criar o nó ‘Neo’
usamos o seguinte comando “CREATE (Neo:Crew {name:'Neo'})”. Para executar a
consulta, basta digitar os comandos no console e então apertar na seta da direita
(Figura 32, número 4). Perceba que na direita um nó será criado.

Um grafo de apenas um nó não é muito divertido, então vamos adicionar


mais nós ao nosso exemplo. Adicione o nó para o Morpheus. Da mesma forma
que o nó anterior, basta usar o comando “CREATE (Morpheus:Crew {name:
'Morpheus'})”. Perceba que se tudo correu bem você terá dois nós armazenados,
porém sem nenhuma ligação entre eles, como mostra a Figura 33.

FIGURA 33 – NÓS EXEMPLO

FONTE: O autor

Agora precisamos criar um relacionamento entre os dois. Para isso,


teremos que buscar os dados nos nós e então criar uma relação entre eles. A busca
no Cypher é realizada através do “MATCH”. Assim, usaremos a seguinte sintaxe:
“MATCH (nó1: tipo), (nó2: tipo) WHERE condição”, em que nó1 e nó2 podem
ser vistos como variáveis que armazenarão os nós retornados pela condição
apresentada pelo WHERE. A condição que passaremos por parâmetro é executada
sobre os atributos de cada nó. Dessa forma, para criar o relacionamento, devemos
buscar os nós que já criamos e a partir deles criar o relacionamento. A Figura 34
apresenta a consulta gerada e o relacionamento criado entre os dois nós. Perceba
que as primeiras duas linhas estão selecionando os nós e apenas na última linha
é criado o relacionamento.

66
TÓPICO 5 | BANCOS ORIENTADOS A GRAFOS

FIGURA 34 – CRIANDO RELACIONAMENTO

FONTE: O autor

Já vimos como criar um nó e depois como adicionar novos relacionamentos


em nosso grafo, porém nosso grafo ainda está muito pequeno para podermos
realizar consultas. Vamos então criar os demais relacionamentos sugeridos pelo
exemplo. Perceba que não podemos mais simplesmente copiar o código que está
na primeira página, pois parte dos dados já foi incluído. Dessa forma, devemos
novamente selecionar os nós “Neo” e “Morpheus” para depois prosseguir com a
população do grafo. A Figura 35 mostra o comando utilizado para criar o restante
dos nós e relacionamentos do exemplo. Após o create temos múltiplas operações
sendo executadas: quatro novos nós sendo criados e 5 relacionamentos. Essas
operações serão executadas como uma transação única.

FIGURA 35 – CRIANDO O RESTANTE DOS RELACIONAMENTOS

FONTE: O autor

Agora que temos o grafo completo podemos realizar consultas baseadas


no grafo. A Figura 36 apresenta uma visão completa do grafo criado através da
execução dos comandos apresentados até aqui.

67
UNIDADE 1 | BANCOS NOSQL

FIGURA 36 – GRAFO COM TODOS OS RELACIONAMENTOS

FONTE: O autor

Uma consulta interessante seria ver a quem o Neo ama (Loves). Essa é
uma consulta simples: basta buscar um nó do “Crew”, chamado Neo, e verificar
quem possui um relacionamento do tipo “Love” com ele. A resposta para essa
consulta é representada pela primeira linha da Figura 37. Perceba que nesta
consulta é utilizado o relacionamento dos dois nós. A consulta retorna o nome
do nó “m” que se liga ao nó “n” por um relacionamento do tipo “LOVES”. A
segunda consulta apresenta os nomes dos nós, que são conhecidos dos conhecidos
do nó “Neo”. Veja que a consulta está considerando os nós que possuem
relacionamento do tipo “KNOWS” ([:KNOWS]-(m)), com quaisquer nós (“-()-
”) que possuam o relacionamento do tipo KNOWS com um nó do tipo Crew
(“(n:Crew)-[:KNOWS]”).

FIGURA 37 – CONSULTAS DE RELACIONAMENTOS

FONTE: O autor

Agora, só nos faltar saber excluir nós de nossa base de dados. É importante
ressaltar que nós que possuem algum tipo de relacionamento não podem ser
excluídos. Nós que não possuem relacionamentos só devem ser buscados pela
consulta MATCH e deletados através do comando DELETE. Por exemplo, caso

68
TÓPICO 5 | BANCOS ORIENTADOS A GRAFOS

“Neo” não possuísse relacionamentos com outros nós, ele poderia ser excluído
pela consulta “match (n:Crew) where n.name='Neo' DELETE n”. No entanto, se for
necessário excluir um nó que possui relacionamento, como procedemos? Temos
que criar uma consulta que primeiro apague o relacionamento para então apagar
o nó propriamente dito. A consulta apresentada pela Figura 38 apaga o nó “The
Architect” e seus respectivos relacionamentos.

FIGURA 38 – DELETE

FONTE: O autor

Desse modo, terminamos nosso exemplo para o modelo de grafos. O


interessante desse modelo são as consultas que envolvem os relacionamentos.
Entendemos que você deve ter ficado um pouco assustado com a sintaxe das
operações no início, porém esperamos que no decorrer da execução e das
explicações você tenha compreendido como essa linguagem trabalha.

69
UNIDADE 1 | BANCOS NOSQL

LEITURA COMPLEMENTAR

NOSQL NA WEB 2.0: UM ESTUDO COMPARATIVO DE BANCOS NÃO


RELACIONAIS PARA ARMAZENAMENTO DE DADOS NA WEB 2.0

Mauricio de Diana
Marco Aurélio Gerosa

1 INDRODUÇÃO

O mundo nunca lidou com volumes de dados tão grandes, em parte graças
à Web 2.0. No artigo em que define Web 2.0, Tim O’Reilly fala sobre a necessidade
de se aproveitar a Inteligência Coletiva e sobre dados como diferencial competitivo
(O’REILLY, 2005). Não por acaso, muitas inovações na área de gerenciamento de
dados vieram de algumas empresas pioneiras da Web 2.0, que encontrando limites
nas técnicas e ferramentas disponíveis naquele momento, criaram suas próprias
soluções, em sua maioria não relacionais. Boa parte da motivação por trás dessas
soluções estava ligada a novos requisitos de escalabilidade e disponibilidade, que
fizeram com que outros requisitos tidos como indiscutíveis fossem revistos, como
a consistência dos dados, por exemplo (VOGELS, 2009) (PRITCHETT, 2008).

Seguindo essa onda de inovações no gerenciamento de dados na web,


vieram organizações menores e a comunidade de software livre e de código
aberto em geral, inspiradas naquelas primeiras ideias, criaram diversas soluções
de bancos de dados não relacionais, seguindo diferentes paradigmas. Apesar
de bancos de dados não relacionais não serem novidade, inclusive existindo
antes dos bancos de dados relacionais, a esse conjunto específico de soluções
surgidas nessa segunda onda na Web 2.0 deu-se o nome NOSQL. Mesmo ainda
estando cercadas de polêmicas e discussões (STONEBRAKER, 2009) (LEAVITT,
2010) (STONEBRAKER 2010), tanto academia quanto mercado reconhecem a
importância e a necessidade de estudá-las (AGRAWAL et al., 2009).

Como essas tecnologias são muito recentes, existem poucas recomendações


indicando em que contexto usar determinado paradigma. Em especial, apesar de
haver casos em que bancos de dados NOSQL ajudaram organizações a escalar
seus sistemas, existem poucos estudos comparativos que indiquem os cenários
em que se aplicam e quais são seus limites de performance e escalabilidade.
[...]

2 BANCOS DE DADOS NOSQL

Os bancos de dados NOSQL surgiram como uma solução para a questão


da escalabilidade no armazenamento e processamento de grandes volumes
de dados na Web 2.0. No início, grandes empresas enfrentando esse tipo de
problema criaram suas próprias soluções e publicaram alguns artigos científicos
descrevendo diversas soluções ligadas ao gerenciamento de dados distribuído em

70
TÓPICO 5 | BANCOS ORIENTADOS A GRAFOS

larga escala, mas sem usar ainda o nome NOSQL. O nome só surgiu alguns anos
depois, em 2009, quando algumas novas empresas da Web 2.0 e a comunidade de
software livre e código aberto começaram a desenvolver novas opções de bancos
de dados, inspiradas nas ideias que apareceram naqueles artigos.

Assim como o termo não relacional, o termo NOSQL não ajuda a definir o
que esses bancos são de fato. Além do problema da falta de precisão, esse termo
também tem contribuído para uma grande confusão em torno dessa categoria de
bancos de dados, já que a princípio a linguagem SQL não é sinônimo de bancos
de dados relacionais, nem representa as limitações desses bancos de dados.
Devido a isso, o termo NOSQL tem sido usado com o significado de “não apenas
SQL” numa tentativa da comunidade de reconhecer a utilidade dos modelos
tradicionais e não divergir as discussões. No fim, NOSQL não define precisamente
esses bancos de dados, mas no geral cada um deles apresenta a maioria das
seguintes características: não relacional, distribuído, de código aberto e escalável
horizontalmente, ausência de esquema ou esquema flexível, suporte à replicação
nativo e acesso via APIs simples (NOSQL, 2010). Entre os principais fatores que
favoreceram seu surgimento estão a natureza dos dados da Web, a importância
de se atingir altos graus de paralelismo no processamento dos grandes volumes
de dados e a distribuição de sistemas em escala global.

Natureza dos dados da web. A Web é composta por uma grande quantidade
de dados semiestruturados e crus, como as páginas Web (cuja estrutura descrita
no documento HTML expressa muito pouco sobre o significado do conteúdo do
documento) e conteúdo multimídia (imagens, sons e vídeos). Ao reconhecer a
natureza particular dos dados, é possível criar soluções otimizadas para eles, ao
invés de se tentar estruturá-los, como proposto por alguns autores (ATZENI et
al., 1997). A constatação de que os dados na Web não são estruturados é um dos
fatores que favoreceram o surgimento de tecnologias de gerenciamento de dados
diferentes das tradicionais.

Importância do paralelismo para o processamento de grandes volumes


de dados. O uso de hardware comum e barato para operação dos sistemas é outro
fator que levou ao surgimento de soluções alternativas para o gerenciamento
de dados. Para se atingir à performance razoável no processamento de grandes
volumes de dados, é necessário pensar nos sistemas de forma a se atingir
alto grau de paralelismo. Quando esse paralelismo é factível, o uso de muitos
processadores baratos não só oferece melhor performance, mas também é uma
solução economicamente mais interessante que o uso de menos processadores
mais poderosos e mais caros (BARROSO et al., 2003). Dessa forma, é possível
escalar o sistema horizontalmente apenas adicionando mais hardware. Além
da questão do paralelismo, escalabilidade horizontal é importante para que o
crescimento de uma organização não fique limitado à capacidade de fornecedores
criarem hardware mais poderoso (PRITCHETT, 2008) (ABBOTT; FISCHER, 2009).

Distribuição dos sistemas em escala global. Para atender seus usuários


de forma eficiente, algumas organizações utilizam diversos data centers, muitas

71
UNIDADE 1 | BANCOS NOSQL

vezes localizados em países diferentes. Isso introduz uma série de preocupações


sobre disponibilidade e performance (VOGELS, 2009), que devem ser levados em
consideração na construção dos sistemas.

A distribuição dos sistemas globalmente e o uso de hardware comum e


barato impõem um novo requisito sobre o software sendo implementado: ele
deve ser robusto o suficiente para tolerar constantes e imprevisíveis falhas de
hardware e de infraestrutura (como redes de terceiros, por exemplo). Isso levou
à construção de muita infraestrutura por parte de grandes empresas para dar
suporte aos pesados requisitos de suas aplicações, como o GFS, por exemplo
(GHEMAWAT et al., 2003).

3 CONSISTÊNCIA EM MOMENTO INDETERMINADO

Uma propriedade que muitos bancos de dados NOSQL têm em comum é a


consistência em momento indeterminado (eventual consistency). Essa propriedade
é fundamental para que algumas das soluções consigam atingir níveis maiores de
escalabilidade.

As propriedades de transações ACID (Atômica, Consistente, Isolada e


Durável) tornam o trabalho do desenvolvedor de aplicações muito mais simples.
No entanto, apesar de muito desejáveis, essas propriedades criam dificuldades
ao se distribuir o banco de dados. Quando um banco de dados relacional cresce,
além da capacidade de um único nó, é preciso se optar por escalabilidade vertical
ou horizontal. Escalabilidade vertical não é uma opção para sistemas que lidam
com grandes volumes de dados. Assim, a opção é escalar horizontalmente, e
nesse caso há duas formas de se particionar os dados (PRITCHETT, 2008).

A primeira é o particionamento funcional, que consiste em distribuir as


tabelas pelos nós de acordo com as funcionalidades do sistema que elas
atendem, por exemplo, um nó pode conter as tabelas relacionadas a usuários
e outro as relacionadas à cobrança. O segundo tipo, chamado sharding, ocorre
quando uma tabela está dividida em mais de um nó. Quando essa técnica é
utilizada, os dados são espalhados por nós de acordo com um critério arbitrário
qualquer, como a inicial do nome do usuário em uma tabela de usuários, por
exemplo. Ao se aplicar sharding em um banco de dados, mesmo com a falha
de um nó, o sistema continua funcionando para todas as operações que não
dependam dos dados contidos naquele nó. A desvantagem dessa estratégia é
que o banco de dados perde parte da sua capacidade de lidar com restrições dos
dados, além de não serem mais capazes de realizar JOINs transparentemente.
Com isso, os bancos de dados relacionais deixam de oferecer algumas de suas
principais funcionalidades para o desenvolvedor de aplicações, que passa a ter
que fazer esses tratamentos no nível da aplicação. Ambas as técnicas foram e
ainda são muito utilizadas por sistemas da Web 2.0.

O teorema CAP fala sobre esse tipo de situação. As três letras de CAP se
referem à consistência, disponibilidade e tolerância à partição. Consistência nesse

72
TÓPICO 5 | BANCOS ORIENTADOS A GRAFOS

contexto não tem exatamente o mesmo significado da consistência de transações


de bancos de dados, mas sim diz respeito à ordem de execução de requisições, e
significa que uma leitura de um item após uma escrita desse item deve retornar
ao novo valor. Disponibilidade é a propriedade de um sistema responder a
todas as requisições que chegam a um nó funcionando. Tolerância à partição é a
propriedade de um sistema continuar funcionando mesmo quando um problema
ocorre na rede, dividindo o sistema em duas ou mais partições, o que faz com
que nós de uma partição não consigam se comunicar com as outras. Em sistemas
tolerantes à partição, clientes acessando uma partição conseguem ser atendidos
normalmente. O teorema CAP diz que, em um sistema distribuído, só é possível
garantir duas dessas três propriedades em um dado instante.

Partições de rede são raras, mas ocorrem de tempos em tempos em


sistemas largamente distribuídos (sistemas distribuídos por vários datacenters,
por exemplo) (VOGELS, 2009). A partir dessa constatação, para essa categoria
de sistemas, é necessário escolher entre disponibilidade e consistência. Dada a
natureza das aplicações Web 2.0, elas costumam optar por disponibilidade quando
for possível tolerar alguma inconsistência temporária. Para descrever essas
situações, Pritchett (2008) fala sobre BASE, em oposição à ACID. BASE significa
basicamente disponível, estado leve e consistente em momento indeterminado,
mas o termo não descreve propriedades de fato como as definidas por ACID.
O termo apenas indica que se deve planejar um sistema de forma a tolerar
inconsistências temporárias quando se quer priorizar disponibilidade.
[...]

CHAMADA

Ficou alguma dúvida? Construímos uma trilha de aprendizagem


pensando em facilitar sua compreensão. Acesse o QR Code, que levará ao
AVA, e veja as novidades que preparamos para seu estudo.

73
RESUMO DO TÓPICO 5
Neste tópico, você aprendeu que:

• Os BDs orientados a grafos possuem estruturas baseadas no acesso a grafo


e, diferentemente dos demais modelos de dados, possuem o armazenamento
baseado nos relacionamentos dos dados.

• Esses BDs possuem uma estrutura composta por nós e arestas. Os nós
representam objetos e possuem atributos. As arestas representam relações entre
objetos, sendo que elas possuem direção (origem e destino) e opcionalmente
possuem uma série de atributos.

• O modelo relacional de dados não pode ser mapeado diretamente para o


modelo de grafos devida a sua estrutura de armazenamento baseadas nas
relações que os grafos empregam.

• Diferentemente dos demais BDs NoSQL, os BDs orientados a grafos possuem


uma linguagem de consulta considerada padrão baseada no Gremlin.

• Esses BDs geralmente possuem suporte em forte consistência, suportando as


propriedades ACID.

• Os BDs orientados a grafos suportam transações sobre conjuntos de dados com


múltiplas operações em um ambiente fortemente consistente (ACID).

• Esses BDs são muito indicados para uso em aplicações que possuem dados
conectados de alguma forma, porém é desencorajado seu uso em aplicações que
necessitem realizar consultas que busque nós baseado em suas propriedades
(consultas transversais).

74
AUTOATIVIDADE

1 Considerando todos os modelos de dados que conhecemos no decorrer da


unidade, qual a principal diferença no armazenamento do modelo orientado
a grafos para os demais? Justifique.

2 Modelos de dados orientados a grafos são otimizados para lidar com


dados conectados. Como sistemas de recomendação podem se beneficiar da
estrutura desses BDs?

75
76
UNIDADE 2

PARTICIONAMENTO DE BANCO
DE DADOS
OBJETIVOS DE APRENDIZAGEM
A partir do estudo desta unidade, você deverá ser capaz de:

• compreender o conceito de particionamento de dados e suas aplicações


em big data;

• conhecer os principais frameworks voltados para o particionamento de


dados;

• aprender sobre o conceito de streaming de dados e quais os principais


frameworks;

• compreender o funcionamento de uma arquitetura de big data com da-


dos particionados e distribuídos.

PLANO DE ESTUDOS
Esta unidade está dividida em quatro tópicos. No decorrer da unidade
você encontrará autoatividades com o objetivo de reforçar o conteúdo
apresentado.

TÓPICO 1 – PARTICIONAMENTO DE DADOS

TÓPICO 2 – APLICAÇÕES SIMPLES UTILIZANDO FRAMEWORKS DE


BIG DATA

TÓPICO 3 – OVERVIEW DE FRAMEWORKS DE STREAM DE BIG DATA

TÓPICO 4 – FRAMEWORKS DE ARMAZENAMENTO NÃO


ESTRUTURADOS

CHAMADA

Preparado para ampliar seus conhecimentos? Respire e vamos


em frente! Procure um ambiente que facilite a concentração, assim absorverá
melhor as informações.

77
78
UNIDADE 2
TÓPICO 1

PARTICIONAMENTO DE DADOS

1 INTRODUÇÃO
Big data pode ser considerada como a eletricidade do século XXI, com
um alto poder de transformar muitos aspectos em relação aos negócios e quanto
à vida pública e privada. No entanto, não são os dados brutos que permitem a
mudança e levam a melhores resultados, mas os insights derivados deles. Atual-
mente, as empresas buscam organizar seus dados pensando na modelagem de
negócios e em como isso pode ajudar a administrar os processos. Ou seja, big data
é a descoberta de informação baseada nos dados de instituições e empresas, o que
pode revelar outros novos fatores. Portanto, o uso de dados pode ajudar a mudar
definitivamente o cenário de empreendimentos, sejam privados ou públicos.

As empresas precisam de soluções analíticas para reduzir os custos de


formar e testar hipóteses sobre o grande volume de novos dados que surgem,
padronizando e controlando os processos que realizam. Assim, utilizar os dados
íntegros em ambiente único ou realizar o particionamento em ambientes distri-
buídos são poderosas formas de processar e analisar dados na busca de informa-
ções e novos conhecimentos. Neste tópico, será apresentado um paralelo entre as
vantagens e limitações do particionamento de dados em big data.

2 DESAFIOS DO BIG DATA


Lidar com o grande volume de dados que representa o termo big data
não é nada fácil. Os dados estão em todo lugar e processar esse grande volume
de dados não estava nos planos durante os primórdios da computação. Isso pode
ser percebido ao se constatar que os sistemas computacionais, em hardware e
software, estão em constante evolução, pois quando foram criados não existiam
todos esses dados. O termo big data, na atualidade, ganha visibilidade a partir
de 2001, quando empresas e instituições passaram a compreender e desenvolver
tecnologias para trabalhar com o novo fenômeno da era da informação. Dessa
revolução, surgiram soluções como o Apache Hadoop, criado pela Apache Foun-
dation, uma fundação responsável por várias tecnologias que lidam com formas
de uso e tratamento de dados. A grande vantagem da existência de instituições
como a Fundação Apache é que a pesquisa na área de dados tem se expandido a
tal ponto que o mercado recente permite que tanto grandes empresas da área de
tecnologia, como Microsoft, Amazon e Oracle, quanto pequenas startups emer-
79
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

gentes participem desse processo de desenvolvimento de tecnologias capazes de


processar o imenso universo de dados gerados diariamente.

As ferramentas analíticas de hoje podem ser usadas para revelar infor-


mações de dados históricos e de fluxos de informações em tempo real. Essas
ferramentas ajudam a analisar eventos passados, entender as atividades atuais
e prever resultados futuros. Com essa riqueza de informações, surge uma rara
oportunidade para que empresas superem seus concorrentes, indo além de ex-
pectativas e dos planejamentos das partes envolvidas. Com big data, as organiza-
ções podem conhecer melhor seus clientes, introduzir novos produtos e serviços
e gerenciar melhor os riscos na tomada de decisão.

Os dados estão em todo lugar, pois são trocadas informações a todo ins-
tante, como e-mails, consultas em ferramentas de busca, trocas de mensagens por
aplicativos, acesso a sistemas de gestão nos locais de trabalho e assim por diante.
Isso ocorre até mesmo no controle de tráfego aéreo durante a comunicação entre
as aeronaves e a torre de comando, no trânsito com radares eletrônicos e nas mi-
lhares de câmeras captando imagens pelas cidades. Assim, são gerados dados de
vários tipos, que, em algum momento, são armazenados para análise em tempo
real ou posterior.

Big data são grandes conjuntos de dados coletados, que precisam de fer-
ramentas e tecnologias próprias para lidar com seu grande volume. Independen-
temente de os dados serem de tipos diferentes, hoje, há sistemas que permitem
que os dados sejam compilados e agrupados a fim de que se transformem em
informação, uma vez que dado e informação não são a mesma coisa. Dados são
parte da informação que, em conjunto, formam o conhecimento sobre determi-
nado assunto. Logo, um dado sozinho pode não fazer muito sentido, enquanto
o conjunto de dados pode gerar uma informação. Com informações, se alcança o
conhecimento, seja dentro de um único contexto em uma área específica, seja em
uma área mais vasta, que está inserida em vários contextos diferentes.

Um número como 2001 é considerado um dado, isoladamente. Porém,


ao inserirmos mais dados, cria-se um contexto, como na frase “2001 foi o ano do
atentado às torres gêmeas nos Estados Unidos”. A partir disso, surge uma infor-
mação gerada de dados obtidos, que, no caso, formam uma frase. Assim, a frase
criada um conhecimento adquirido de informações obtidas por meio de dados,
o que dá origem à tríade “dado, informação e conhecimento”, que são elementos
complementares entre si.

Segundo o IDG (2013), em 2005, os seres humanos criaram 150 exaby-


tes de dados. Em 2010, esse número cresceu oito vezes, ou seja, foi para 1.200
exabytes. Os pesquisadores estimam que os dados corporativos aumentam em
torno de 60% ao ano — 90% dos quais não são estruturados — e a quantidade
média de dados armazenados por empresa é de 200 terabytes. Com o volume de
dados dobrando a cada dois anos, aproximadamente, muitas organizações preci-
sam gerenciar e analisar petabytes de dados estruturados e não estruturados. Ao

80
TÓPICO 1 | PARTICIONAMENTO DE DADOS

contrário dos dados corporativos tradicionais que podem ser modelados e arma-
zenados em tabelas relacionais, os dados atuais vêm de muitas fontes diferentes e
aparecem de várias formas, como em páginas da internet, redes sociais, e-mails,
ferramentas de pesquisas, sensores de equipamentos e todos os tipos de arquivos
multimídia e hipermídia, incluindo áudio, vídeo e figuras.

NOTA

Existem diferentes tipos de dados divididos em pelo menos três categorias,


segundo os principais autores: estruturados, não estruturados e semiestruturados. Estru-
turados são dados já armazenados. Portanto, realizar uma operação ou análise com eles
é mais fácil, pois já estão prontos para uso. Semiestruturados são dados que apresentam
certa estrutura e organização, mas ainda precisam passar por refinamentos antes de serem
utilizados ou analisados. Os dados não estruturados representam dados vindos em forma-
tos diversos que precisam passar por uma normalização ou preparação antes de serem
úteis e analisados.

O conceito de big data é baseado em seus Vs. Existem diferentes opiniões


sobre a quantidade desses Vs, mas os três básicos são:

• volume;
• velocidade;
• variedade.

Alguns outros complementares são:

• veracidade;
• variabilidade;
• valor.

Volume é a quantidade de dados envolvidos no conjunto de dados


analisado. Velocidade se trata de ter os dados em tempo hábil para uma análise,
pois um sistema que demora a obter dados cai em desuso de maneira muito
rápida. A variedade é a quantidade de fontes distintas que um dado tem e que
podem ser redes sociais, sensores, sistemas, aplicativos etc.

3 LIMITAÇÕES DO PARTICIONAMENTO DE DADOS


Quase todas as organizações possuem o poder de usar análises para re-
velar padrões ocultos, obter insights estratégicos e gerar valor com o enorme vo-
lume de dados que geram. Em muitos casos, os dados já estão sendo capturados,
mas não são totalmente aproveitados. Para originar análises poderosas, é preci-

81
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

so obter informações significativas que possam transformar determinado proje-


to, instituição ou empresa. Os dados se tornam um fluxo contínuo que flui para
todas as áreas da economia mundial. Cada projeto que abrange dados precisa
ser bem elaborado a fim de aproveitar o que as empresas produzem de volume
crescente de dados transacionais capturados, que podem ser trilhões de bytes de
informações sobre seus clientes, fornecedores e operações.

O modo de armazenamento dos dados fará toda a diferença na hora de


analisar as informações contidas neles. Como ressaltam Sharda, Delen e Turban
(2019, p. 75), “no mundo real, os dados costumam não estar prontos para serem
usados em tarefas de análise de dados. Eles costumam se apresentar sujos, mal
alinhados, excessivamente complexos e imprecisos”. Dessa forma, é possível per-
ceber que o modo de armazenamento dos dados pode ser, primariamente, com
dados não estruturados ou semiestruturados, para, posteriormente, serem pré-
-processados e passados a um ambiente de dados estruturados.

O particionamento de dados é a forma de fragmentar ou particionar os


dados em diferentes meios físicos. A forma de armazenamento de dados utilizan-
do sistemas distribuídos é um formato comumente aceito quando se trata de big
data. O particionamento permite que tabelas e índices de um banco de dados se-
jam subdivididos em partes menores individuais. Cada parte do objeto de banco
de dados é chamada de partição. Uma partição tem seu próprio nome e, opcional-
mente, pode ter suas próprias características de armazenamento. Da perspectiva
de um administrador de banco de dados, um objeto particionado possui várias
partes que podem ser gerenciadas coletivamente ou individualmente (BAER,
2007). Isso fornece ao administrador uma flexibilidade considerável ao gerenciar
um objeto particionado. No entanto, da perspectiva do aplicativo, uma tabela
particionada é idêntica a uma tabela não particionada, ou seja, nenhuma modi-
ficação é necessária ao acessar uma tabela particionada usando comandos SQL,
por exemplo. Por mais que haja uma divisão física de onde estão os dados, logi-
camente, ainda é apenas uma tabela e qualquer aplicativo pode acessá-la, assim
como ocorre em uma tabela não particionada.

Mannino (2008) exemplifica o uso do processamento em bancos de dados


paralelos com a necessidade da junção de grandes tabelas em bancos de dados re-
lacionais. O autor ainda apresenta dois importantes fatores que fazem o processa-
mento em servidores de bancos de dados de maneira paralela: scaleup e speedup.
Segundo o autor, scaleup tem a ver com a quantidade de trabalhos (jobs) que são
realizados com o objetivo de aumentar a capacidade computacional. Ela é uma
forma de medir o tamanho de um trabalho. O scaleup é uma capacidade de esca-
labilidade linear, com aplicação para que um aumento da capacidade de compu-
tadores em um número X permita o aumento também em X vezes a quantidade
de trabalho realizado no mesmo tempo de execução de uma aplicação. Porém,
nem sempre será possível o uso de scaleup de maneira linear. Portanto, scaleup
se refere à escalabilidade e capacidade de medir a expansão da capacidade de um
computador em processar e armazenar dados.

82
TÓPICO 1 | PARTICIONAMENTO DE DADOS

Já speedup diz respeito à velocidade em que uma resposta, consulta ou


transação será executada em um servidor de banco de dados. Como afirma Man-
nino (2008), o speedup é uma forma de avaliar ou fazer um comparativo entre o
tempo que se gastava em uma transação com configurações em situações normais
em comparação com o tempo gasto com a capacidade adicional vinda do parti-
cionamento de dados. Com isso, o autor quer dizer que, em um processamento
paralelo de dados particionados, uma vez que as configurações estejam adequa-
das à realidade do servidor, o tempo de resposta e conclusão de um trabalho será
expandido, o que é uma qualidade positiva do particionamento de dados.

4 BENEFÍCIOS DO PARTICIONAMENTO DE DADOS


O particionamento pode reduzir muito o custo total de propriedade de
dados, por exemplo, usando uma abordagem de arquivamento em camadas para
manter as informações relevantes mais antigas ainda on-line, no formato com-
pactado ideal e em dispositivos de armazenamento de baixo custo, enquanto os
dados mais importantes são armazenados na coluna de memória do servidor de
dados. Quando usado em conjunto com ferramentas de otimização automática
de dados, o particionamento fornece uma maneira simples e automatizada de
implementar uma estratégia de gerenciamento do ciclo de vida da informação.

Na abordagem de bancos de dados, objetos como tabelas e índices são par-


ticionados usando uma chave de particionamento, que é um conjunto de colunas
que determinam em qual partição uma determinada linha ficará. As partições de
uma tabela armazenam fisicamente os dados, enquanto a própria tabela é apenas
metadado. Por exemplo, uma tabela de vendas pode particionar seus dados por
intervalo da data de venda ou de pedido usando uma estratégia de particiona-
mento mensal. Assim, a tabela aparece para qualquer aplicativo como uma única
tabela normal. No entanto, o administrador do banco de dados pode gerenciar e
armazenar cada partição mensal individualmente, otimizando o armazenamento
de dados de acordo com a importância dos dados e a frequência de uso.

Datacenter é um servidor central que armazena dados de uma organiza-


ção. Quando é realizado o particionamento de dados, um mesmo banco de dados
pode estar fisicamente dividido, com parte dele em uma máquina servidor e ou-
tra parte em outra máquina servidor. Assim, o usuário acessa os dados indistin-
tamente, sem saber que a mesma tabela que contém seus dados pode estar fisica-
mente em diferentes máquinas. Afinal, os bancos de dados distribuídos possuem
essa capacidade de integração, em que, mesmo os dados estando em diferentes
partes, sua leitura é permitida como se estivessem todos em um só local.

Desse modo, partições que armazenam intervalos de dados mais anti-


gos podem ser armazenadas em camadas de armazenamento distintas, usando
a compactação de tabelas ou mesmo armazenadas em espaços de tabela lidos ou
marcados como partições somente de leitura, enquanto as partições mais recentes
são marcadas para serem armazenadas no armazenamento de colunas em memó-
ria do banco de dados (BAER, 2007).
83
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

Ao limitar a quantidade de dados a serem examinados ou operados, o


particionamento fornece vários benefícios de desempenho. A remoção de parti-
cionamento, também conhecida como eliminação de partição, é o mais simples e
também o meio mais eficaz para melhorar o desempenho. Geralmente, ele pode
melhorar muito o desempenho da consulta, aproveitando os metadados de par-
ticionamento para usar apenas os dados relevantes para uma operação SQL. Isso
pode ocorrer, por exemplo, em um aplicativo que contenha uma tabela chamada
“pedidos”, ou seja, um registro histórico de pedidos, que tenha sido particiona-
da por dia na data do pedido. Uma consulta solicitando pedidos por uma única
semana acessaria apenas sete partições dessa tabela. Se a tabela tivesse dois anos
de dados históricos, essa consulta acessaria sete partições em vez de 730. Essa
consulta pode ser executada 100 vezes mais rapidamente simplesmente devido à
remoção da partição. A remoção de partição funciona com a maioria dos bancos
de dados modernos que possuem a capacidade do modelo distribuído de dados.

O particionamento de dados pode apresentar diversos benefícios, como:

● melhorar a escalabilidade;
● melhorar o desempenho do acesso aos dados;
● melhorar a segurança dos dados;
● fornecer flexibilidade operacional;
● fazer correspondência de diferentes repositórios de dados a um padrão;
● melhorar a disponibilidade dos dados em uma organização.

5 GERENCIAMENTO DE PARTICIONAMENTO
Ao particionar tabelas e índices em unidades menores e mais gerenciá-
veis, os administradores de bancos de dados podem usar uma abordagem de
dividir para conquistar no gerenciamento de dados. Bancos de dados distribuí-
dos fornecem um conjunto abrangente de comandos SQL para gerenciar tabelas
de particionamento. Isso inclui comandos para adicionar novas partições, soltar,
dividir, mover, mesclar, truncar e trocar partições. Com o particionamento, as
operações de manutenção podem se concentrar em partes específicas das tabelas.

As partições podem acontecer de maneira horizontal, vertical ou funcio-


nal. Cada um dos tipos de particionamento apresenta características que vão va-
riar em benefícios de acordo com a estratégia a ser adotada por uma instituição.
Especialistas indicam que a estratégia deve ser escolhida com cautela, uma vez
que os benefícios devem ser maiores que os efeitos contrários que possam ser oca-
sionados, incluindo maior investimento de tempo e dinheiro na implementação
de mudanças. Os tipos de particionamento são os apresentados a seguir.

• Particionamento horizontal: chamado de fragmentação ou sharding. Nesse


modelo, os dados são fragmentados em partes menores, chamadas de shard
ou fragmento, com todos os dados do mesmo tipo juntos. Um exemplo seria
uma enorme tabela de clientes cadastrados sendo dividida com um número X
de registros de clientes em cada fragmento, formando um conjunto de shards.
84
TÓPICO 1 | PARTICIONAMENTO DE DADOS

• Particionamento vertical: esse tipo de particionamento, diferentemente do


horizontal, divide os dados de modo a deixar apenas campos ou colunas mais
acessados em uma partição, deixando os demais em outra partição.
• Particionamento funcional: é uma forma diferente de particionar os dados, que
seria como criar subtabelas derivadas de uma tabela central. É um uso comum
na separação de dados que sejam apenas para leitura ou consulta de outros que
servem para escrita e leitura.

Na prática, um administrador de banco de dados pode compactar uma única


partição contendo, por exemplo, os dados para um ano específico de uma tabela,
em vez de compactar a tabela inteira. Como parte da operação de compactação,
essa partição também pode ser reduzida para um nível de armazenamento de
custo mais baixo, reduzindo ainda mais o custo total de propriedade dos dados
armazenados. A operação de manutenção de partição pode ser feita de maneira
totalmente on-line, permitindo que consultas e operações DML ocorram enquanto
a operação de manutenção de dados está em processo (BAER, 2007).

Como exemplo, é possível mesclar três partições, como “janeiro de 2020”,


“fevereiro de 2020” e “março de 2020”, em uma única partição “T1 2020” (T de
trimestre), com uma única operação de partição de mesclagem. Outro caso de
uso do gerenciamento de particionamento é oferecer suporte a um processo de
carregamento de janela sem interrupção em um data warehouse. Suponha-se que
um DBA carregue novos dados em uma tabela diariamente. Essa tabela pode ser
particionada por intervalo para que cada partição contenha um dia de dados.
O processo de carregamento é simplesmente a adição de uma nova partição.
Adicionar uma única partição é muito mais eficiente do que modificar a tabela
inteira, pois o DBA não precisa modificar nenhuma outra partição.

A remoção de dados de uma maneira muito eficiente e prática é outra


vantagem importante do particionamento. Por exemplo, para limpar os dados
de uma tabela particionada, pode-se simplesmente eliminar ou truncar uma
ou várias partições, o que é uma operação rápida, em vez de emitir o comando
delete, usando muitos recursos e mexendo em todas as linhas a serem excluídas.
Esse tipo de operação não requer manutenção imediata do índice para manter
todos os índices válidos, tornando-se mais rápida apenas para metadados.

NOTA

O Hadoop é um ecossistema criado para lidar com grandes volumes de dados


— o big data. Os arquivos armazenados no Hadoop são divididos em blocos, em que o
tamanho padrão é 124 MB. Esses blocos são pequenas partições do arquivo original, que
também são replicados numa escala configurável, na qual o padrão de réplicas é três.

No Hadoop, o particionamento dos dados permite o armazenamento de arquivos maiores


que o tamanho de um disco. Por exemplo, em um cluster em que há uma quantidade de

85
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

discos (HDs) de 1 TB cada um, sem o particionamento, o maior arquivo que poderá ser
armazenado terá o tamanho máximo de 1 TB. Usando o particionamento, o arquivo será
dividido em várias partes e distribuído pelos discos do cluster. Assim, quando for preciso
recuperá-lo, não haverá perda de informação.

6 DESAFIOS DO PARTICIONAMENTO DE DADOS


Algumas operações em dados particionados podem ser mais complicadas
que outras. A criação de partições e até a união de partições podem ser um pouco
mais tranquilas. Mas, enquanto as operações de manutenção de partição permitem
a rápida remoção de dados, a granularidade de uma operação é vinculada aos
limites das partições que estão sendo eliminadas ou truncadas. Porém, com
frequência, existe exceção à regra: por exemplo, como parte de uma operação
de rollback, deseja-se remover todos os dados com mais de três anos, mas não se
deve remover nenhum pedido que não tenha sido oficialmente fechado. Embora
essa seja uma situação muito rara de acontecer, esse requisito de negócio exclui o
uso de uma partição truncada ou descartada.

Para prevenir problemas, o ideal é lidar com essa situação


programaticamente, preservando os valores extremos. As operações de
manutenção de partição são aprimoradas em bancos de dados modernos para
permitir a filtragem de dados como parte de qualquer operação de manutenção
da partição. No exemplo citado, mover a partição e preservar todos os registros
antigos que não estão oficialmente fechados obtém a remoção dos dados. As
operações de manutenção de partição filtrada levam a manutenção de dados às
operações de manutenção de partição.

O particionamento pode ser feito para atingir diferentes objetivos. O


particionamento traz um elemento novo quando se trata do desenho de um
sistema ou aplicativo. Logo, lidar com dados particionados também requer que a
tecnologia e linguagem de programação utilizadas no desenvolvimento tenham
habilidade para isso. É indicado que o particionamento de dados esteja no projeto
original dos dados, já pensando em seu crescimento e na escalabilidade posterior.
Afinal, é consideravelmente mais simples implementar um design de aplicação
desde o princípio com pensamento de partição dos dados que alterar a arquitetura
depois do aplicativo pronto.

De acordo com a documentação oferecida pela Microsoft Azure (2018), a


lógica da forma como se acessa os dados acaba por ser diferenciada, precisando
ser modificada caso a aplicação já tenha sido criada. Com a necessidade de
distribuir os dados em partições, será necessário migrar grandes quantidades de
dados já existentes, o que pode demandar tempo, impactando no tempo que os
usuários teriam que esperar para ter acesso aos dados durante essa migração.

86
TÓPICO 1 | PARTICIONAMENTO DE DADOS

Outros desafios a serem levados em consideração são:

• replicação de partições como forma de prevenir falhas eventuais;


• avaliar os limites físicos de servidores de bancos de dados;
• realizar o rebalanceamento dos fragmentos particionados como forma de
garantir um crescimento saudável do armazenamento dos dados;
• criação de mapas com metadados sobre as partições como forma de diminuir a
busca por dados, evitando a necessidade de percorrer todas as partições atrás
de um dado solicitado.

7 ESTRATÉGIA DE PARTIÇÃO
Por mais vantajosa que seja a partição de dados, isso requer certos cuidados.
Um banco de dados distribuído deve fornecer o conjunto mais abrangente de
estratégias de particionamento, permitindo que os usuários do banco alinhem
da melhor maneira a subdivisão de dados com os requisitos de negócios reais.
É preciso, então, ter uma estratégia para lidar com o particionamento e o
planejamento de como as consultas e transações com os dados deverão acontecer.

Todas as estratégias de particionamento disponíveis dependem de


métodos fundamentais de distribuição de dados que podem ser usados para
tabelas particionadas únicas (um nível) ou compostas (dois níveis). Além
disso, é necessário observar se o banco de dados adotado possui extensões de
particionamento que permitam alguma flexibilidade para a seleção de chaves
de particionamento, fornecendo criação automatizada de partições, conforme
necessário, além de compartilhamento de estratégias de particionamento entre
grupos de tabelas conectadas logicamente por meio de relacionamentos pai-filho,
assim como estratégias de particionamento para objetos não particionados.

Além dos métodos fundamentais, deve ser observado se o banco de dados


fornece a estrutura total para particionar uma tabela ou se apenas armazena
metadados para determinar o posicionamento dos dados. Por meio de um
sistema gerenciador de banco de dados (SGBD), como um aplicativo, deve ser
possível gerenciar o posicionamento dos dados, tanto para inserção como para
acesso, sendo possível, com a aplicação SGBD, realizar a remoção da partição
(MICROSOFT, 2017).

O particionamento do sistema deve ser projetado como uma estrutura


de desenvolvimento com necessidades especiais de posicionamento ou acesso a
dados, como índices de domínio, além de suportar tabelas com particionamento
único ou composto.

87
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

ATENCAO

Nem todos os bancos de dados suportam o particionamento de dados. Alguns


deles possuem ferramentas mais completas para isso, como Oracle e SQL Server. Em outros
bancos relacionais, como PostgreSQL e MySQL, existe essa opção, mas com recursos não
tão profundos, de acordo com a própria documentação deles. Em bancos não relacionais,
isso já é algo mais natural, visto que eles lidam com big data e sistemas distribuídos por
natureza. Destacam-se o MongoDB e o Cassandra.

Como forma de resumir a implementação do particionamento de dados


na prática, o Quadro 1 apresenta as características do uso dessa técnica, como as
estratégias, tipos de distribuição de dados e casos de uso.

QUADRO 1 – MÉTODOS DE PARTICIPAÇÃO

FONTE: Adaptado de Baer (2007)

Assim, existem diferentes formas de particionamento e para cada


uma delas existe uma aplicação. É preciso ressaltar que hash é uma técnica de
agrupamento por tabela, que associa chaves de pesquisa a valores. Nesse contexto,
ela se encaixa como um agrupamento de metadados, associando os dados por
intervalos e realizando uma virtualização das tabelas no banco de dados, como
uma aplicação que busca por essa tabela hash como se estivesse lendo os dados
em seu local de armazenamento original.

Com isso, é possível concluir que o particionamento pode melhorar


muito a capacidade de gerenciamento, desempenho e disponibilidade de quase
todos os sistemas de banco de dados. Percebe-se que, como o particionamento é
transparente para a aplicação que acessa os dados e, consequentemente, para o
usuário do aplicativo, ele pode ser facilmente implementado para qualquer tipo
de aplicativo, pois não são necessárias alterações caras e demoradas. Seu uso,
dependendo do planejamento e da cautela, pode agregar muitas vantagens ou se
tornar um problema, caso seja mal planejado ou haja erros na sua implementação.
88
RESUMO DO TÓPICO 1
Neste tópico, você aprendeu que:

• Dentre os desafios de Big Data, o grande volume de dados leva ao


particionamento e distribuição de dado.

• O scaleup se refere à escalabilidade e capacidade de medir a expansão da


capacidade de um computador em processar e armazenar dados.

• O particionamento pode reduzir muito o custo total de propriedade de dados,


por exemplo, usando uma abordagem de arquivamento em camadas para
manter as informações relevantes mais antigas ainda on-line.

• Quando é realizado o particionamento de dados, um mesmo banco de dados


pode estar fisicamente dividido, com parte dele em uma máquina servidor e
outra parte em outra máquina servidor.

• As partições podem acontecer de maneira horizontal, vertical ou funcional.

89
AUTOATIVIDADE

1 Big data é uma expressão relativamente nova. Com o avanço da Tecnologia


da Informação e Comunicação (TIC), lidar com quantidades enormes de
dados tem se tornado algo comum em empresas e instituições públicas. Sobre
o conceito de big data, qual é a alternativa correta?

a) ( ) É uma forma de lidar com dados em formato binário.


b) ( ) Trata-se da descoberta de informação baseada em dados da instituição
ou da empresa.
c) ( ) É uma metodologia na qual a quantidade de dados é o mais importante.
d) ( ) É uma expressão que descreve grande volume de dados estruturados.
e) ( ) O big data pode ser analisado para obter dados baseados em
informações estratégicas de uma empresa.

2 Existem diferentes tipos de dados: estruturados, não estruturados e


semiestruturados. Sobre os tipos de dados, analise as afirmações a seguir:

I- Dados tratados e prontos para uso


II- Dados de arquivo de texto
III- Arquivos de imagem, vídeo e áudio
IV- Arquivo de tipo heterogêneo
V- Dados de um formulário de cadastro​​​​​​​

Quais afirmativas contêm dados do tipo estruturado?


a) ( ) I e II.
b) ( ) II e II
c) ( ) I, II e III
d) ( ) II e IV.
e) ( ) I e V.

3 O particionamento de dados é a forma de fragmentar ou particionar os dados


em diferentes meios físicos. A forma de armazenamento de dados utilizando
um formato comumente aceito em se tratanto de big data é o que se encontra
em qual alternativa?

a) ( ) Sistemas distribuídos.
b) ( ) Sistema particionado.
c) ( ) Sistema gerenciador de banco de dados.
d) ( ) Sistemas computacionais.
e) ( ) Sistema de gestão de servidores.

4 Mannino (2014) exemplifica o uso do processamento em bancos de dados


paralelos com a necessidade da junção de grandes tabelas em bancos de dados
relacionais. O autor ainda apresenta dois importantes fatores que fazem com

90
que o processamento em servidores de bancos de dados de maneira paralela:
scaleup e speedup. Sobre essas duas palavras, analise as afirmações a seguir:

I- Envolve a quantidade de trabalhos que podem ser realizados


II- Trata do aumento da capacidade computacional
III- Tem a ver com tempo de resposta de uma transação com dados
IV- Tem a ver com a escalabilidade

Das afirmações acima, quais afirmativas estão corretas no que se refere ao


scaleup?
a) ( ) I e II.
b) ( ) II e III.
c) ( ) I e IV.
d) ( ) I, II e III.
e) ( ) I, II e IV.

91
92
UNIDADE 2 TÓPICO 2

APLICAÇÕES SIMPLES UTILIZANDO


FRAMEWORKS DE BIG DATA

1 INTRODUÇÃO
O termo big data é cada vez mais utilizado tanto por profissionais de TI
quanto por empresários, alguns buscando especialização em áreas mais avan-
çadas em tecnologia e outros buscando obter vantagens competitivas para suas
empresas com a ajuda de profissionais de TI, por poderem oferecer possibilidade
de diminuição de custos, mais informação e conhecimento adequado para uma
melhor tomada de decisão, aumento na lucratividade e possibilidade de cresci-
mento do negócio ou, em alguns casos, por serem os profissionais que podem
garantir a sobrevivência da empresa.

Nesse contexto, o termo é utilizado para representar uma quantidade de


dados tão grande a ponto de tornar o seu processamento inviável em métodos
tradicionais de processamento de dados, o que gerou interesse da comunidade
em contribuir com a manutenção e a evolução dos frameworks de big data, sendo
os principais deles de código livre e com apoio de grandes empresas, que acabam
por utilizá-los no dia a dia dos seus negócios.

Neste tópico, você vai conhecer aplicações simples, utilizando frameworks


de big data, por meio de conceitos do MapReduce e de um exemplo de aplica-
ção de contagem de palavras que utiliza o MapReduce tanto no Apache Hadoop
quanto no Apache Spark.

2 FUNCIONAMENTO DO MAPREDUCE
Conforme apresentado no artigo da Google, por Dean e Ghemawat (2004),
o MapReduce é um modelo de programação e implementação associada a esse
modelo, que permite o processamento e a geração de grandes conjuntos de da-
dos. Nele, os usuários especificam uma função de mapeamento para processar
um par chave-valor, o que gera um conjunto de pares chave-valor intermediários,
e uma função de redução para mesclar os valores intermediários associados à
mesma chave intermediária. Além disso, muitas das tarefas do mundo real são
expressáveis nesse modelo.

Segundo a Apache Software Foundation (2019), o MapReduce é um fra-


mework de software para a fácil escrita de aplicações que processam uma vasta
93
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

quantidade de dados em paralelo, com conjuntos que podem chegar a vários te-
rabytes, em clusters que podem chegar a milhares de nós, compostos por máqui-
nas comuns, de maneira confiável e com tolerância a falhas.

Conforme pode ser observado na Figura 1, no processamento paralelo


e distribuído tradicional, antes da existência do MapReduce, o conjunto de da-
dos era dividido em partes menores ou blocos para que fossem armazenados em
máquinas diferentes. Em seguida, era realizada a busca de alguma característica
em cada parte armazenada por meio do comando grep, que permite realizar a
busca de palavras em vários arquivos diferentes, de forma que cada uma retorna
seus próprios resultados nas máquinas correspondentes, para que todos sejam
concatenados por meio do comando cat, que pode ser utilizado para a criação de
arquivo, concatenação e apresentação de conteúdo na tela, e assim gerar como
resultado final o conjunto dos resultados.

FIGURA 1 – PROCESSAMENTO PARALELO E DISTRIBUÍDO ANTERIOR À EXISTENCIA DO


MAPREDUCE

FONTE: Adaptado de Kiran (2020)

Os principais desafios associados a essa abordagem, que precisam ser cui-


dados individualmente, têm relação com problemas em caminhos críticos quan-
do uma das máquinas atrasa a tarefa e gera atraso em todo o processamento,
problemas de confiabilidade causados pelo desafio de gerenciamento de uma
máquina que falha durante a execução de uma tarefa, problemas de divisão de
tarefas que possam gerar sobrecarga ou subutilização das máquinas, problemas
de falha de um nó que podem impossibilitar a geração do resultado final, bem
como desafios de agregação, para que os dados possam ser concatenados para
gerar o resultado final.

Com o MapReduce, esses desafios são superados, tendo em vista que ele
permite computação paralela e distribuída sem a necessidade de cuidar de pro-
blemas como confiabilidade, tolerância a falhas e demais problemas citados ante-
riormente, o que gera flexibilidade aos desenvolvedores para criarem as aplicações
de big data focando apenas na abstração do problema que a aplicação se propõe a
resolver, sem a preocupação com o paralelismo ou a distribuição dos dados.

94
TÓPICO 2 | APLICAÇÕES SIMPLES UTILIZANDO FRAMEWORKS DE BIG DATA

De acordo com a Apache Software Foundation (2019), no MapReduce,


um Job divide o conjunto de dados em partes menores independentes, que são
processadas por tarefas de mapeamento e executadas paralelamente. Nessa fase,
são produzidos pares com chave-valor. Em seguida, acontece a classificação das
saídas das tarefas de mapeamento apresentadas como funções Map(), que são
inseridas nas tarefas de redução, descritas como funções Reduce(), que agregam
os pares em um conjunto menor de chave-valor para gerar o resultado final. Esse
processo pode ser observado na Figura 2.

FIGURA 2 – PROCESSAMENTO PARALELO E DISTRIBUÍDO COM MAPREDUCE

FONTE: Sharda, Delen e Turban (2019, p. 453)

No Hadoop, geralmente os dados de entrada e as saídas são armazenados


em um sistema de arquivos, mesmo que venham a ser reprocessados
posteriormente. Todavia, no Spark, os dados podem ser mantidos em memória
para os casos de processamento iterativo. Em ambos os casos, o framework fica
responsável pelo agendamento e monitoramento das tarefas, bem como pelas
novas tentativas de execução das tarefas que falharem.

3 INTERFACES PARA UTILIZAÇÃO DO HADOOP MAPREDUCE


Como observado na Figura 2, as duas das principais interfaces tipicamen-
te implementadas para utilizar o MapReduce são as interfaces Mapper e Reducer,
que disponibilizam os métodos map() e reduce(). Outras interfaces que fazem
parte do conjunto das principais interfaces são Counter, Job, Partitioner, Inpu-
tFormat e OutputFormat.

95
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

Segundo Coulouris et al. (2013), a função map() é responsável por receber


um conjunto de pares chave-valor como entrada e produzir um conjunto de pares
chave-valor intermediários como saída. No caso de contagem de palavras em um
texto, com diversas linhas e várias palavras em cada linha, é essa função que irá
separar cada palavra do texto e irá atribuir um valor para uma delas, gerando os
pares chave-valor intermediários.

Em se tratando da classe Reducer, os valores intermediários de saída da


função map() são classificados utilizando o valor da chave de forma que todos
os resultados intermediários fiquem ordenados pela chave intermediária e que
sejam decompostos em grupos, para que sejam passados como entrada para ins-
tâncias da classe Reducer. Dessa forma, a função reduce() tem como responsabi-
lidade realizar o processamento dessa entrada para produzir uma lista de valores
para cada um dos grupos, de forma que fiquem prontos para serem combinados
em um índice completo.

No caso da classe Partitioner, esta controla a divisão das chaves da saída


do mapeamento intermediário, chaves, ou seu subconjunto, que são utilizadas
para derivar a partição, bem como definir para qual tarefa de redução a chave
intermediária é enviada para redução. O número total de partições é o mesmo de
tarefas de redução.

No entanto, no caso da classe Job, esta representa o trabalho do MapRe-


duce. Por meio da sua interface, o usuário descreve o trabalho do MapReduce,
que deve ser executado no Hadoop, e é com essa classe que normalmente são
especificadas as implementações das classes Mapper, Reducer, Partitioner, Inpu-
tFormat e OutputFormat.

Como o MapReduce opera exclusivamente com pares chave-valor, as


classes chave e valor precisam ser serializáveis e, por consequência, implementar
a interface Writable. Além disso, as classes chave precisam implementar a inter-
face WritableComparable para facilitar a sua classificação.

4 CONCEITO DO CONTADOR DE PALAVRAS COM


MAPREDUCE
Antes da apresentação de implementação com o MapReduce no Hadoop
e no Spark, é importante entender o domínio do problema que será abordado.
Neste caso, será um contador que separa cada uma das palavras de um arquivo
texto e informa o número de ocorrências para cada uma delas ao longo do
arquivo. Com isso, será possível visualizar o funcionamento do MapReduce por
meio de um exemplo, que será implementado nos próximos tópicos, a partir de
um arquivo de entrada que contém as seguintes palavras: ciência computação
dados computação dados nuvem ciência dados dados.

96
TÓPICO 2 | APLICAÇÕES SIMPLES UTILIZANDO FRAMEWORKS DE BIG DATA

Como é possível observar na Figura 3, no primeiro passo, o arquivo é


divido em três partes, sendo a primeira: ciência computação dados; a segunda:
computação dados nuvem; e a terceira: ciência dados dados. Nesta fase, são
formadas as primeiras saídas intermediárias de chave-valor, ou C1, V1. No
segundo momento, é realizado o mapeamento das palavras, no qual acontece a
separação delas, e é atribuído o valor 1 para cada uma, formando a segunda saída
intermediária de chave-valor, ou C2, V2. Em seguida, acontece a combinação das
palavras adicionando o valor 1 na lista de valores para cada chave. Na sequência,
acontece a redução, que soma o valor 1 da lista para gerar a saída final e, por
consequência, o último par chave-valor, ou C3, V3.

FIGURA 3 – PROCESSAMENTO DO EXEMPLO DO CONTADOR DE PALAVRAS COM O


MAPREDUCE

FONTE: Adaptado de Kiran (2020)

Com isso, os tipos de entradas e saídas de cada etapa de uma tarefa no


MapReduce podem ser observados no seguinte esquema:

C1, V1 → mapeamento → C2, V2 → combinação → C2, V2 → redução → C3, V3

Veja, a seguir, a implementação do exemplo do contador de palavras


utilizando o Hadoop MapReduce em Java.

5 APLICAÇÃO COM O HADOOP MAPREDUCE


De acordo com a Apache Software Foundation (2019), na documentação
do framework Hadoop, para que seja possível rodar as aplicações com o
Hadoop MapReduce, é necessário que o Hadoop esteja instalado, configurado e
rodando, seja por meio da configuração em um único nó, normalmente utilizado
para questões de aprendizado, ou por meio da configuração para clusters, que
possibilita trabalhar com clusters grandes e distribuídos.

Para programar a aplicação do contador de palavras no Hadoop, é


necessário criar três classes: a de mapeamento MeuMap, a de redução MeuReduce
e a principal ContadorPalavras, que contém as duas primeiras, além do método
main, que configura o Job informando as classes MeuMap e Meu-Reduce e chama
a função de execução da aplicação.

97
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

Para que seja possível utilizar as classes e realizar as chamadas dos


métodos de cada uma delas, é necessário escrever as devidas importações, como
no trecho de código a seguir:

package com.sagah.exemplohaddop; //nome do pacote do arquivo no seu projeto


import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.fs.Path;

A primeira é a classe MeuMap, que realiza o mapeamento e herda da


classe Mapper, conforme é possível observar no código da classe a seguir:

public static class MeuMap extends Mapper<LongWritable,Text,


Text,IntWritable> {
public void map(LongWritable chave, Text valor, Context contexto)
throws IOException,InterruptedException {
String linha = valor.toString();
StringTokenizer tokenizer = new StringTokenizer(linha);
while (tokenizer.hasMoreTokens()) { valor.set(tokenizer.
nextToken()); contexto.write(valor, new IntWritable(1));}}}

Neste código, a variável linha recebe o valor do parâmetro valor do método


map, convertido para String, para, então, ser dividido pelo StringTokenizer em
palavras que serão armazenadas na variável tokenizer. Dessa forma, é possível
executar um loop, que verifica se a variável tokenizer contém mais palavras, e,
caso contenha, realizar a atribuição da palavra para a variável valor e escrever no
contexto o valor dela e o número 1.

No trecho de código a seguir, pode ser observada a segunda classe, que


realiza a redução e herda da classe Reducer:

98
TÓPICO 2 | APLICAÇÕES SIMPLES UTILIZANDO FRAMEWORKS DE BIG DATA

public static class MeuReduce extends Reducer<Text,IntWritab


le,Text,IntWritable> {
public void reduce(Text chave, Iterable<IntWritable> valores, Context
contexto) throws IOException,InterruptedEx ception {
int soma=0;
for(IntWritable valor: valores) {
soma+=valor.get();
}
contexto.write(chave, new IntWritable(soma));
}
}

Esta classe inicia a variável soma com o valor 0, para, então, executar o
loop, que soma cada valor do vetor valores na variável soma. Quando o loop
termina, escrito no contexto o valor da variável chave e a soma dos valores da
chave. A terceira classe, que engloba as duas anteriores e contém o método main
para executar o código delas, pode ser observada a seguir:

public class ContadorPalavras{


public static class MeuMap extends Mapper<LongWritable,T
ext,Text,IntWritable> {…}
public static class MeuReduce extends Reducer<Text,IntWr
itable,Text,IntWritable> {…}
public static void main(String[] args) throws Exception {
Configuration configuracao= new Configuration();
Job job = new Job(configuracao,"Meu Contador dePalavras");
job.setJarByClass(ContadorPalavras.class);
job.setMapperClass(MeuMap.class);
job.setReducerClass(MeuReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
Path caminhoSaida = new Path(args[1]); FileInputFormat.
addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1])); outputPath.
getFileSystem(configuracao).
delete(caminhoSaida);
System.exit(job.waitForCompletion(true) ? 0 : 1);}}

Nesse trecho, os códigos das classes MeuMap e MeuReduce são omitidos


por já terem sido apresentados separadamente. Por conter o método main, é
a classe ContadorPalavras que será chamada para executar a aplicação. Nesse
método, são criadas as variáveis de configuração do Job e, em seguida, ele é
99
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

executado. No Job, são informadas as classes para gerar o arquivo executável, ou


jar, bem como a classe de mapeamento, de redução, de saída da chave e do valor,
e do formato de saída e de entrada.

Como no comando de execução da aplicação são passados os parâmetros


que informam qual é o arquivo de entrada e de saída, respectivamente, a variável
caminhoSaida recebe o caminho do segundo parâmetro. Em seguida, são
adicionados os caminhos de entrada e saída na variável job, por meio das funções
addInputPath e setOutputPath, respectivamente, e, em seguida, é realizada a
configuração para que a saída seja removida do HDFS automaticamente, para
que não seja necessário removê-la explicitamente. Em seguida, o Job é executado
pela função waitForCompletion, que representa a conclusão quando retorna 1,
fechando o sistema.

Para executar essa aplicação no Hadoop, é necessário rodar o comando


informando o nome do arquivo executável criado com a extensão .jar no
momento da compilação do código, o nome da classe que foi criada e que contém
o método main, bem como o caminho dos arquivos de entrada e saída, neste caso,
localizados na pasta amostra, conforme pode ser observado a seguir:

hadoop jar exemplo-hadoop-mapreduce.jar ContadorPalavras / amostra/


input /amostra/output

6 APLICAÇÃO COM O MAPREDUCE NO SPARK


Neste exemplo, o projeto utiliza o Maven para adicionar as dependências,
portanto, não é necessário instalar e configurar o Apache Spark. Entretanto,
necessário localizar e abrir o arquivo pom.xml do projeto e adicionar a dependência
do Spark com o seguinte trecho de código:

<dependency>
<groupId>org.apache.spark</groupId> <artifactId>spark-core_2.11</
artifactId> <version>1.4.0</version>
</dependency>

Além da dependência, é necessário adicionar a classe ContadorPalavras


juntamente com o seu caminho no projeto dentro das tags <mainClass></
mainClass> do mesmo arquivo, conforme apresentado a seguir:

<mainClass>com.sagah.exemplospark.ContadorPalavras</mainClass>

100
TÓPICO 2 | APLICAÇÕES SIMPLES UTILIZANDO FRAMEWORKS DE BIG DATA

No caso da criação da aplicação que utiliza o mapeamento e a redução


com o Spark, é necessário criar apenas a classe principal ContadorPalavras, que
contém o método contaPalavras e o método main para chamar a execução do
primeiro método, conforme pode ser observado no código a seguir:

package com.sagah.exemplospark
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD; import org.apache.
spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext; import scala.
Tuple2;
import java.util.Arrays;
public class ContadorPalavras {
private static void contaPalavras(String nomeArquivo) { SparkConf
configuracao = new SparkConf().setMaster("local").
setAppName("Meu Contador de Palavras");
JavaSparkContext contexto = new JavaSparkContext(configuracao);
JavaRDD<String> arquivoEntrada = contexto.
textFile(nomeArquivo);
JavaRDD<String> palavrasArquivo = arquivoEntrada. flatMap(conteudo ->
Arrays.asList(conteudo.split(" ")));
JavaPairRDD dadosContados = palavrasArquivo.mapToPair(t -> new
Tuple2(t, 1)).reduceByKey((x, y) -> (int) x + (int) y);
dadosContados.saveAsTextFile("DadosContados");}
public static void main(String[] args) { contaPalavras(args[0]);}}

Nesse código, é possível observar a configuração do Spark, no qual o nó


mestre é definido como “local” e o nome da aplicação como “Meu Contador de
Palavras”. Em seguida, é declarada a variável contexto do tipo JavaSparkContex
e instanciada a partir da configuração anterior. A variável arquivoEntrada
declarada com o tipo JavaRDD é instanciada a partir do comando textFile do
contexto e a variável palavrasArquivo recebe as palavras contidas no arquivo
de entrada a partir da função flatMap, que recebe o conteúdo com as palavras
separadas por espaço em branco.

Em seguida, são realizadas as operações de transformação do Spark, em


que são realizados o mapeamento das palavras por meio do método mapToPair
e a redução do resultado do mapeamento por meio da função reduceByKey,
armazenando o resultado final na variável dadosContados do tipo JavaPairRDD.
A variável dadosContados é utilizada, então, para salvar o arquivo de texto do
diretório informado a partir do método saveAsTextFile, que é uma das operações
de ação do framework.

Para executar a aplicação no Spark, é necessário rodar o comando que


tem como parâmetros a classe ContadorPalavras com seu caminho no projeto e o
arquivo de entrada, como pode ser observado a seguir:

101
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

mvn exec:java -Dexec.mainClass=com.sagah.exemplospark.Conta-


dorPalavras -Dexec.args="input.txt"

No Spark, as linguagens de programação mais utilizadas são Python, Sca-


la e Java. Veja no trecho de código a seguir, retirado do GitHub oficial do Spark,
um exemplo em Python, por meio do pyspark, para o caso de uso de contagem
de palavras (GITHUB, 2018, s.p.):

from __future__ import print_function


import sys
from operator import add
from pyspark.sql import SparkSession
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: wordcount <file>", file=sys.stderr)
sys.exit(-1)
spark = SparkSession\.builder\.appName("PythonWordCount")\.
getOrCreate()
lines = spark.read.text(sys.argv[1]).rdd.map(lambdar: r[0])
counts = lines.flatMap(lambda x: x.split(' ')) \.map(lambda x: (x,
1)) \.reduceByKey(add)
output = counts.collect()
for (word, count) in output:
print("%s: %i" % (word, count))
spark.stop()

Dessa forma, a partir do entendimento do funcionamento do MapReduce


e das funções de mapeamento e redução, que fazem parte do conjunto mínimo
de funções de uma aplicação que utiliza o MapReduce, bem como do exemplo de
uma aplicação MapReduce para a contagem de palavras de um conjunto de dados,
tanto no Hadoop quanto no Spark, é possível dar início ao desenvolvimento de
outras aplicações que utilizam o framework, de forma a praticar os conceitos e
aprofundar os conhecimentos que são cada dia mais valorizados pelo mercado.

102
RESUMO DO TÓPICO 2
Neste tópico, você aprendeu que:

• O MapReduce é um modelo de programação para dados distribuídos.

• Utilizando o MapReduce é possível simplificar escrita de aplicações que


processam uma vasta quantidade de dados em paralelo.

• O Apache Hadoop é um framework para big data que utiliza do modelo


MapReduce.

• A implementação do MapReduce não está limitada ao framework ou linguagem


de programação.

103
AUTOATIVIDADE

1 Quando se deseja criar aplicações utilizando o Hadoop MapReduce​​​​​​ é


necessário usar interfaces específicas. Assinale a alternativa que representa
apenas interfaces de aplicações Hadoop MapReduce:

a) ( ) Job, Counter, JavaRDD e JavaPairRDD.


b) ( ) Mapper, JavaRDD, Reduce e Counter.
c) ( ) Job, Counter, Partitioner e JavaRDD.
d) ( ) Mapper, Reducer, Partitioner e Counter.
e) ( ) Partitioner, JavaPairRDD, Job e Reducer.

2 Uma aplicação que utilize o Apache Spark para solucionar um desafio de


Big Data tem operações de transformação e de ação. Assinale a alternativa que
representa apenas funções de transformação:

a) ( ) Map, count e saveAsTextFile.


b) ( ) Map, groupByKey e filter.
c) ( ) Count, groupByKey e union.
d) ( ) Filter, saveAsTextFile e join.
e) ( ) Join, collect e intersection.

3 Com o MapReduce é possível processar um conjunto de dados muito


grande em paralelo e de forma distribuída. Assinale a alternativa que
representa a afirmação verdadeira sobre as características e o funcionamento
do MapReduce.

a) ( ) O MapReduce pode processar conjuntos de dados que chegam a até


alguns gigabytes de dados.
b) ( ) Para utilizar o MapReduce é necessário utilizar servidores poderosos,
pouco acessíveis aos usuários comuns.
c) ( ) Com o MapReduce é possível distribuir os dados em clusters que
podem chegar a milhares de nós.
d) ( ) Mesmo com o MapReduce é necessário cuidar de problemas como
tolerância a falhas e confiabilidade.
e) ( ) No MapReduce o agendamento e o monitoramento de tarefas são de
total responsabilidade do programador.

104
UNIDADE 2
TÓPICO 3

OVERVIEW DE FRAMEWORKS DE
STREAM DE BIG DATA

1 INTRODUÇÃO
Existem cenários com características específicas de streaming de big
data, como no caso de uma instituição financeira que rastreia em tempo real as
mudanças de mercado para ajustar as operações das carteiras de investimento
com base em limites máximos e mínimos, ou no caso de soluções de Internet
das Coisas que crescem a cada dia, e sensores de monitoramento que fazem o
envio constante das suas leituras para uma ou mais estações. Para lidar com esses
cenários, é necessário utilizar tecnologias que possam tratar séries temporais e
realizar o processamento à medida que os dados chegam, ao invés de esperar
o final da mensagem para realizar o processamento, pois, nesses casos, as
mensagens não contêm um sinal de fim de arquivo por serem um fluxo constante
de dados, que em teoria não tem fim.

Neste tópico, você vai conhecer uma visão geral de frameworks de stream
de big data, saber mais sobre o Spark Streaming, por meio da descrição de suas
características e da comparação com outras tecnologias utilizadas para stream de
big data, bem como pela ingestão de um stream de dados simples.

2 CONHECENDO O SPARK STREAMING


De acordo com a documentação do Apache Spark Streaming, o framework
torna simples o desenvolvimento de aplicações em stream de dados de alta taxa de
transferência, de forma que as aplicações sejam escaláveis e tolerantes a falhas sem
que haja a necessidade de escrita de código extra para esses fins. A simplicidade
se dá por conta dos operadores de alto nível contidos em sua API integrada para
o processamento dos fluxos de dados, o que permite que o desenvolvedor crie
serviços de stream de dados da mesma forma que cria serviços para lotes de
dados. No entanto, a tolerância a falhas se dá pela sua recuperação de trabalho
perdido e das janelas deslizantes.

De acordo com Dayananda (2019), Spark Streaming tem como principais


recursos a escalabilidade, pois pode ser facilmente escalonado para centenas de
nós; a velocidade, por atingir baixa latência ou processar em tempo real em certos
casos; a tolerância a falhas; a sua integração entre processamento de fluxos de

105
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

dados e de lotes; e a sua disponibilidade para a realização de análise de negócios,


pois pode ser utilizado para rastrear comportamentos que podem ser utilizados
estrategicamente para a tomada de decisão das empresas.

Como o Spark Streaming roda em cima da API principal do Spark,


ele permite a combinação de operações em fluxos ativos de dados com dados
em lotes e buscas interativas, bem como o reuso de código de streaming para
processamento em lote, unindo os fluxos com dados históricos, o que possibilita
a criação de aplicações interativas, além das aplicações de análise.

Os dados das aplicações que tratam esses fluxos podem ser ingeridos por
diversas fontes distintas, como plataformas de código aberto, e proprietário, como
o Apache Kafka, o Apache Flume e o Amazon Kinesis, ou de sockets TCP. Esses
dados podem ser processados com algoritmos complexos por meio das funções
de alto nível, como map, reduce, join e window.

Os dados resultantes desse processamento podem ser armazenados em


bancos de dados e sistemas de arquivos, como o HDFS, ou o Hadoop Distributed
File System, bem como podem ser enviados para dashboards, conhecidos como
painéis de controle. Também é possível executar algoritmos de aprendizagem de
máquina e de processamento gráfico nos fluxos de dados.

Internamente, o Spark Streaming recebe um fluxo de dados de entrada


em tempo real e divide esses dados em lotes em intervalos de tempo predefinido.
Esses lotes são chamados de microlotes e são processados pelo motor do Spark,
o que resulta em um fluxo final também composto por um conjunto de lotes,
conforme apresentado na Figura 4.

FIGURA 4 – FUNCIONAMENTO INTERNO DO APACHE SPARK STREAMING

FONTE: Adaptado de Apache Spark (2020)

De acordo com Penchikala (2016), após a divisão dos dados em microlotes,


eles são tratados como RDDs, acrônimo para Resilient Distributed Datasets, que são
coleções de elementos. O autor também afirma que a decisão do intervalo de tempo
a ser utilizado é de extrema importância para o projeto e deve ser baseado no caso
de uso que se quer analisar, bem como nos requisitos de processamento de dados.

Caso o tempo seja muito baixo, os microlotes não irão conter dados
suficientes para que os resultados da análise sejam significativos, e caso seja
muito alto, podem faltar recursos para o processamento dos microlotes.
106
TÓPICO 3 | OVERVIEW DE FRAMEWORKS DE STREAM DE BIG DATA

3 FLUXOS DISCRETIZADOS (DSTREAMS)


O Spark Streaming fornece uma abstração de alto nível que representa um
fluxo contínuo de dados chamado DStream, acrônimo para fluxo discretizado,
do inglês discretized stream. Internamente, um DStream é representado por
uma série contínua ou sequência de RDDs, que é a abstração do Spark para um
conjunto de dados distribuído e imutável, e contém os dados de um intervalo de
tempo, conforme pode ser observado na Figura 5.

FIGURA 5 – RDDs NO DSTREAM COM DADOS DE DETERMIONADO INTERVALO DE TEMPO

FONTE: Adaptado de Apache Sparks (2020)

Além disso, cada operação que acontece em um DStream é convertida


em operações nos RDDs que seguem, como no caso de um fluxo de entrada que
chega na forma de linhas e é convertido para palavras, no qual a operação flatMap
é executada em cada um dos RDDs nas linhas do stream discretizado para gerar
os RDDs das palavras de saída DStream. A Figura 6 apresenta um exemplo que
mostra o fluxo de uma aplicação usando Spark que conta o número de palavras
dos textos recebidos de um servidor de dados que escuta de um socket TCP.

FIGURA 6 – REAPLICAÇÃO DA OPERAÇÃO FLATMAP NOS RDDs SUBJACENTES DO DSTREAM

FONTE: Adaptado de Apache Sparks (2020)

Neste caso, as operações do DStream ocultam grande parte desses detalhes


de replicação das operações para outros RDDs e disponibilizam uma API de alto

107
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

nível para os desenvolvedores, tendo em vista que as transformações subjacentes


nos RDDs são executadas pelo motor do Apache Spark. Esse fluxo contínuo de
dados representado pelo Spark Streaming como DStream pode ser o fluxo de
dados de entrada que é recebido da fonte ou o fluxo de dados processados de
saída que é gerado pela transformação do fluxo de entrada.

Quando se trata de um fluxo de entrada, o DStream diz respeito aos dados


de entrada recebidos por meio das fontes de stream, que podem ser criadas a partir
de operações de alto nível em outros DStreams, além das outras fontes citadas
anteriormente, como das plataformas como Kafka, Flume e Kineses. Além disso,
todo DStream de entrada é associado a um objeto do tipo Receiver, que recebe
os dados da fonte e os armazena na memória do Spark para o processamento,
conforme pode ser observado na Figura 7.

FIGURA 7 – DSTREAM DE ENTRADA COM O OBJETO DO TIPO RECEIVER PARA RECEBER OS


DADOS

FONTE: Adaptado de Dayananda (2019)

O DStream suporta diversas das transformações normalmente permitidas


nos RDDs do Spark, como map, flatMap, filter, reduce, join, transform e
updateStateByKey, e, assim como no caso dos RDDs, as transformações permitem
que os dados do DStream de entrada sejam modificados.

Em se tratando do DStream de saída, que representa o fluxo de dados


processados, são as operações de saída que permitem que os dados sejam
enviados para sistemas externos, como bancos de dados e sistemas de arquivos,
e, assim como no caso dos RDDs, são essas operações que acionam a execução
de todas as transformações no DStream que não são executadas imediatamente
quando chamadas.

108
TÓPICO 3 | OVERVIEW DE FRAMEWORKS DE STREAM DE BIG DATA

4 SPARK STREAMING E OUTROS FRAMEWORKS


Além do Spark Streaming, existem outros frameworks que permitem
tratar fluxos contínuos de dados, como o Structured Streaming do Spark, o Kinesis
Streams da Amazon, o Flink, o Storm, o Kafka e o Samza, todos da Apache. Neste
tópico, o framework Apache Spark Streaming será comparado com o Spark
Structured Streaming, o Apache Flink e o Apache Storm.

4.1. SPARK STREAMING E SPARK STRUCTURED STREAMING


O Spark é uma ferramenta muito popular por conta do seu processamento
rápido e distribuído, sem sobrecarga de entrada e saída, com tolerância a
falhas, entre outras qualidades. Voltado para soluções de big data, ele permite
o processamento de vastas quantidades de dados, bem como trabalhar com
processamento de fluxos contínuos de dados em tempo real. Para lidar com esses
fluxos de dados, o Spark disponibiliza duas ferramentas, uma é o Spark Streaming,
apresentado anteriormente neste tópico, e a outra é o Structured Streaming.

De acordo com Saxena (2019), o Spark Structured Streaming surgiu com a


Versão 2 do Spark como mais uma forma de lidar com fluxos contínuos de dados
e foi construído na biblioteca Spark SQL. Baseado nas APIs Dataframe e Dataset,
ele torna fácil a execução de consultas SQL com a API Dataframe e operações com
a API Dataset nos fluxos de dados.

Uma das diferenças entre eles é a forma como tratam os fluxos de dados
em tempo real. Enquanto o Spark Streaming utiliza o conceito de divisão em
microlotes e cada lote pertence a um lote do DStream, representado por diferentes
RDDs, o Structured Streaming processa cada linha do fluxo de dados e o resultado
é a atualização de uma tabela de resultados. Além disso, com o Structured
Streaming é possível que a tabela resultante seja composta por uma atualização
dos dados, apenas novos resultados ou todos os resultados, dependendo do
modo das operações utilizadas.

A segunda diferença tem relação com as diferentes APIs de cada um dos


modelos. Enquanto o Spark Streaming utiliza a API DStream, que internamente
funciona com RDDS, o Structured Streaming utiliza APIs Dataframe e Dataset.
Dessa forma, conforme apresentado por diversos autores, os Dataframes são mais
otimizados quando se trata de processamento, além de oferecerem mais opções
de agregação e outras operações com funções suportadas no Spark.

Outra diferença diz respeito à forma de processamento de dados com base


no horário exato do acontecimento do evento. No Spark Streaming, o controle do
tempo só tem relação com o momento em que o dado é ingerido pelo Spark,
quando os dados são colocados em um lote atual, mesmo que o evento tenha
acontecido mais cedo e pertença ao lote anterior, o que pode ser considerado
como perda de dados e gerar informações menos precisas.
109
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

Todavia, no caso do Structured Streaming, um dos principais recursos


introduzidos é o tratamento de dados atrasados com base no horário do
acontecimento do evento, de forma que o registro de data e hora do acontecimento
do evento no mundo real é inserido na tabela de resultados, fornecendo uma
maneira diferente de processar os dados, se comparado ao Spark Streaming.

Em se tratando de tolerância a falhas, em ambos os frameworks é utilizado


o conceito de ponto de controle para guardar o progresso de um trabalho, pois
para que uma aplicação seja tolerante a falhas ela precisa ter capacidade de
reiniciar a partir do ponto de falha, de forma a evitar perda de dados, no caso de
retomar em um ponto posterior, ou a duplicação de dados, no caso de retomar
em um ponto anterior.

A diferença entre eles é que o Structured Streaming utiliza duas condições


para se recuperar de qualquer erro, além do ponto de controle, tendo em vista
que essa abordagem ainda permite perda de dados. A primeira é que a fonte de
dados deve ser repetível e a segunda é que as áreas de destino das operações
nos fluxos de dados devem suportar operações idempotentes para que os dados
possam ser reprocessados em caso de falhas.

4.2. SPARK STREAMING, APACHE FLINK E APACHE STORM


Assim como o Spark Streaming, o Apache Flink e o Apache Storm são
projetados para tratar os dados em memória e processá-los em tempo real, sem,
necessariamente, persistirem os dados em outros tipos de armazenamento,
apesar de ser possível gravá-los em bancos de dados e sistemas de arquivos, pois
o propósito dos frameworks de streaming é processar os dados em tempo real à
medida que eles chegam. A grande diferença entre eles é que o Flink e o Storm são
baseados em uma arquitetura diferente do Spark Streaming, pois foram criados
do zero com o propósito de trabalhar com um motor nativo para streaming,
enquanto o Spark contém um motor baseado no conceito de tratamento de stream
de dados com microlotes.

Os modelos nativos de tratamento de streaming foram projetados


especificamente para resolver os desafios de aplicações que exigem processamento
em tempo real baseado em recebimento de eventos, no qual o fluxo de dados é
obtido das fontes ao longo do tempo e é processado individualmente à medida
que é recebido, o que ajuda a manter um menor tempo de espera antes que o
dado entre no sistema. Como resultado, esse tipo de arquitetura tem uma menor
latência se comparada ao modelo orientado a microlotes do Spark Streaming.

Em relação à tolerância a falhas, como visto anteriormente, o Spark


Streaming utiliza o conceito de gerenciamento de estado por ponto de verificação
para replicar continuamente o estado para outros nós, para que, quando a falha
aconteça, o dado possa ser extraído do outro nó e o processamento seja reiniciado,
o que é um processo mais custoso em motores de stream nativos no sentido de
recursos, pois é aplicado a cada nível de registro.
110
TÓPICO 3 | OVERVIEW DE FRAMEWORKS DE STREAM DE BIG DATA

De acordo com Gorasiya (2019), apesar de esse controle ser mais custoso,
o Flink também utiliza pontos de verificação para a sua recuperação de falhas. No
entanto, o Storm não fornece gerenciamento de estados, o que força o reinício do
processo inteiro em diferentes nós, gerando, assim, a garantia de processamento
“ao menos uma vez”, diferentemente dos dois anteriores, que têm a garantia de
processamento de “exatamente uma vez”.

A diferença entre a gestão de estados do Spark Streaming e do Flink é


que no Spark ela está associada com os RDDs e envolve a atualização de cada
lote, mesmo que o estado não seja alterado, tornando-o extremamente ineficiente
se comparado ao Flink. No caso do Flink, tem suporte eficiente para integrar o
gerenciamento de estado com a ajuda de um sistema de arquivos distribuídos, de
forma a manter o controle do estado por meio de um retrato fiel da situação em
determinado momento.

Para Gorasiya (2019), outra diferença é em relação à escalabilidade, pois,


no Spark, as soluções escalam automaticamente, enquanto no Flink e no Storm,
esse processo é manual. Além disso, o Spark tem uma ampla comunidade que
trabalha, dá suporte e discute sobre a tecnologia, enquanto no Flink, a comunidade
ainda está em crescimento e no Storm, a comunidade de colaboradores é pequena
se comparada aos dois anteriores.

Segundo Prakash (2018), o Storm é o projeto de código aberto mais antigo


para trabalhar com streaming e um dos mais maduros e confiáveis. Excelente
para trabalhar com casos de uso que não sejam complexos, ele tem latência muito
baixa e alta taxa de transferência. Entretanto, tem desvantagens, como o fato de
não controlar estados, controle de garantia de processamento de “ao menos uma
vez” e não tem funcionalidades avançadas, como o processamento de evento
baseado no horário do acontecimento, agregação, separação em janelas, sessões,
entre outros.

O autor afirma que as principais vantagens do Spark Streaming são que


ele suporta arquitetura Lambda, que é disponibilizada gratuitamente com o
Spark, tem alta taxa de transferência, tolerância a falhas por padrão por conta da
sua natureza de microlotes, além de ter simplicidade no uso de APIs de alto nível,
uma comunidade grande e melhorias agressivas no framework. Suas principais
desvantagens dizem respeito a não ser nativamente criado para streaming e não
é adequado para alguns casos de requisitos de baixa latência se comparado a
outros frameworks.

Em se tratando do Flink, é o líder em inovação quando se trata de


framework de streaming de código aberto. Foi o primeiro projeto nativo para
streaming com funcionalidades avançadas, como processamento de evento com
horário do acontecimento, separação em janelas, entre outros. Ele tem baixa
latência com alta taxa de entrega, que pode ser configurada de acordo com os
111
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

requisitos da aplicação. Entretanto, suas desvantagens dizem respeito à sua


popularidade se dar apenas em aplicações de streaming e à sua falta de adoção
inicial, o que o colocou mais tarde na competição contra outros frameworks,
tendo uma comunidade menor do que o Spark.

5 INGESTÃO DE DADOS COM O SPARK STREAMING EM JAVA


Para que seja possível entender como funciona a ingestão de dados em
uma aplicação com o Spark Streaming, será apresentado um caso de uso em
Java de uma aplicação simples para contagem de palavras nos dados de texto
recebidos de um servidor, por meio da escuta de um socket TCP, que, neste caso,
vai ser exemplificado pelo endereço “localhost” e porta 9999.

Assim como no caso do Spark, o Spark Streaming está disponível no


repositório central do Maven. Para tanto, é necessário criar um projeto Maven
e adicionar o trecho de código a seguir como dependência no arquivo pom.xml,
sem esquecer de verificar as versões disponíveis no repositório do Maven no
momento que estiver trabalhando com o projeto:

<dependency>
<groupId>org.apache.spark</groupId> <artifactId>spark-
streaming_2.12</artifactId> <version>2.4.5</version>
</dependency>

Para a ingestão de dados de fontes que não estão presentes na API


principal do Spark Streaming, como o Kafka, o Flume e o Kineses, também é
possível adicionar suas respectivas dependências no arquivo pom.xml, por meio
dos artefatos spark-streaming-kafka-0-10_2.12, spark-streaming-flume_2.12 ou
spark-streaming-kinesis-asl_2.12, e suas versões correspondentes, que têm o
número final correspondente à versão do exemplo, mas que irão evoluir e devem
ser buscadas para que a versão utilizada seja atualizada no momento da criação
do projeto para que não se utilize uma versão defasada e com menos recursos.

6 ETAPAS PARA CRIAR UM PROGRAMA COM SPARK


STREAMING
Uma vez que o Spark Streaming foi instalado na máquina, ou adicionado
ao projeto Maven, é necessário seguir alguns passos para criar uma aplicação
queutilize stream de dados, sendo o primeiro deles a definição das importações,
conforme no trecho a seguir:

112
TÓPICO 3 | OVERVIEW DE FRAMEWORKS DE STREAM DE BIG DATA

import org.apache.spark.*;
import org.apache.spark.api.java.function.*;
import org.apache.spark.streaming.*;
import org.apache.spark.streaming.api.java.*;
import scala.Tuple2;

Com as devidas importações que serão apresentadas no código de


exemplo, inicialmente, é necessário criar o objeto do tipo SparkConf especificando
o local de execução e o número de threads que irão executar o processamento,
bem como o nome da aplicação, como no trecho de código a seguir, que utilizada
o ambiente local:

SparkConf configuracao = new SparkConf().setMaster("local[2]").


setAppName("ContaPalavras");

Em seguida, é criado o objeto do tipo JavaStreamingContext para receber


a configuração do objeto SparkConf como parâmetro e o intervalo de tempo
de cada lote. Esse objeto é o ponto de entrada para todas as funcionalidades de
streaming e no caso de uso do exemplo foi configurado em 1 segundo, conforme
pode ser observado no seguinte trecho de código:

JavaStreamingContext jssc = new JavaStreamingContext(configuracao,


Durations.seconds(1));

A partir deste objeto de contexto, é possível criar o DStream de entrada


a partir do objeto do tipo JavaReceiverInputDStream. Como neste exemplo a
conexão é feita com um socket TCP, o método chamado é o socketTextStream, que
recebe como parâmetro o endereço IP do servidor e a porta, como apresentado no
trecho de código a seguir:

JavaReceiverInputDStream<String> linhas = jssc.


socketTextStream("localhost", 9999);

A variável linhas do tipo DStream representa o fluxo de dados que será


recebido do servidor, onde cada entrada vinda do servidor representa uma linha
do texto como um todo.

113
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

Para que essa linha seja processada e seja realizada a sua separação em
palavras, com o espaço em branco sendo o separador entre elas, é necessário
utilizar a operação flatMap, que recebe uma lista como parâmetro, que deve ser
separada na variável x, por meio dos métodos split e iterator, para que, então,
cada uma das palavras possa ser atribuída à variável palavras do tipo DStream,
conforme é possível observar no seguinte trecho de código:

JavaDStream<String> palavras = linhas.flatMap(x -> Arrays.asList(x.


split(" ")).iterator());

Para a realização da contagem de palavras, é utilizada a operação


mapToPair no DStream palavras e, no seu resultado, que também é uma variável
do tipo DStream de nome pares, é realizada a operação reduceByKey. Após
isso, o resultado é armazenado no DStream palavrasContadas, que recebe a
operação print para que seus valores sejam escritos no terminal à medida que são
processados. O trecho do código pode ser visto a seguir:

JavaPairDStream<String, Integer> pares = palavras.mapToPair(s ->


new Tuple2<>(s, 1));
JavaPairDStream<String, Integer> palavrasContadas = pares.
reduceByKey((i1, i2) -> i1 + i2); palavrasContadas.print();

Com o código escrito até agora, foi realizada a configuração do que


deverá ser executado pelo Spark Streaming, sem que aconteça algum tipo de
processamento até que a operação de chamada de início aconteça explicitamente,
por meio da função start do objeto de contexto do Spark Streaming. Além disso, é
necessário esperar a execução terminar por meio da operação awaitTermination,
como pode ser visto no trecho de código que segue:

jssc.start();
jssc.awaitTermination();

Neste caso, a classe que contém o código foi chamada de ContadorPala-


vrasStreaming e o código completo ficaria como o apresentado a seguir:

import org.apache.spark.*;
import org.apache.spark.api.java.function.*; import org.apache.
spark.streaming.*;
import org.apache.spark.streaming.api.java.*; import scala.Tuple2;

114
TÓPICO 3 | OVERVIEW DE FRAMEWORKS DE STREAM DE BIG DATA

public final class ContadorPalavrasStreaming {


public static void main(String[] args) throws Exception { SparkConf
configuracao =
new SparkConf().setMaster("local[2]").
setAppName("ContaPalavras");
JavaStreamingContext jssc =
new JavaStreamingContext(configuracao, Durations.seconds(1));
JavaReceiverInputDStream<String> linhas = jssc.
socketTextStream("localhost", 9999);
JavaDStream<String> palavras =linhas.flatMap(x -> Arrays.asList(x.
split(" ")).iterator());
JavaPairDStream<String, Integer> pares =palavras.mapToPair(s -> new
Tuple2<>(s, 1));
JavaPairDStream<String, Integer> palavrasContadas =pares.
reduceByKey((i1, i2) -> i1 + i2);
palavrasContadas.print();
jssc.start();
jssc.awaitTermination();
}
}

Para que seja possível rodar um servidor de dados de texto localmente,


é possível utilizar o serviço Netcat, que está presente na maioria dos sistemas
operacionais baseados em unix, como Linux e MacOS, por meio do comando nc
–lk 9999 no terminal e escrever o texto desejado, como apresentado no exemplo
da Figura 8.

FIGURA 8 – EXEMPLO DE INPUT DE DADOS COM TEXTO DIGITADO

FONTE: O Autor

Feito isso, com o Spark instalado e configurado, para rodar a aplicação


em outra janela do terminal, é necessário navegar até a pasta onde se encontra
o arquivo da classe ContadorPalavrasStreaming e executar o seguinte comando:

115
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

./bin/run-example ContadorPalavrasStreaming

Dessa forma, serão apresentados no terminal as palavras e os seus


respectivos números de contagem para cada uma delas, conforme apresentado
no exemplo da Figura 9.

FIGURA 9 – EXEMPLO DE SAÍDA PARA O EXEMPLO DE ENTRADA APRESENTADO NA FIGURA 8

FONTE: O Autor

Com isso, é possível conhecer uma visão geral sobre o Apache Spark
Streaming, observar suas características e diferenças entre ele e outros frameworks,
como o Apache Structured Streaming, o Apache Flink e o Apache Storm, bem
como entender como seria a programação em Java de uma aplicação simples de
ingestão de dados em streaming.

116
RESUMO DO TÓPICO 3
Neste tópico, você aprendeu que:

● Algumas das técnicas avançadas do Spark envolvem armazenamento de dados


em cache, utilização de acumuladores, variáveis de transmissão e pontos de
verificação.

● Assim como é feito nos RDDs, o Spark Streaming permite que os desenvolvedores
realizem a persistência dos dados em memória por meio da operação persist
() nos DStreams, que acontece por padrão no caso de operações que tratam
janelas, como a reduceByWindow e a reduceByKeyAndWindow.

● O armazenamento em cache é útil para dados que precisem ser reprocessados


múltiplas vezes, o que gera ganho de desempenho para a aplicação.

● O Spark Streaming também utiliza o conceito de acumuladores para


implementar contadores e operações de soma. São variáveis adicionadas
especificamente por meio de operações associativas e cumulativas que são
úteis de serem rastreadas nas interfaces gráficas para acompanhamento e
entendimento do progresso dos estágios de processamentos dos dados.

● As variáveis de transmissão, em inglês chamadas de broadcast variables,


permitem que o desenvolvedor mantenha uma variável apenas de leitura em
cada máquina em vez de enviar uma cópia com a tarefa.

● As variáveis de transmissão podem ser utilizadas como uma forma eficiente de


manter um grande conjunto de dados em cada um dos nós. Por meio dessas
variáveis e dos algoritmos de transmissão eficientes, os custos de comunicação
podem ser reduzidos.

● Os pontos de verificação, chamados de checkpoints em inglês, são similares aos


pontos de verificação dos jogos computacionais, em que o estado do jogo é
gravado para que possa ser o ponto de retomada caso o jogador falhe.

117
AUTOATIVIDADE

1 O Spark Streaming fornece uma abstração de alto nível para representar um


fluxo contínuo de dados. Marque a opção que representa a abstração de alto
nível fornecida pelo Spark Streaming.

a) ( ) DStream.
b) ( ) RDD.
c) ( ) Flatmap.
d) ( ) Receiver.
e) ( ) Reduce.

2 O Spark Streaming e o Spark Structured Streaming são frameworks para lidar


com fluxos contínuos de dados em tempo real, à medida que os dados chegam.
Marque a opção correta a respeito da diferença entre o Spark Streaming e o
Spark Structured Streaming.

a) ( ) Enquanto o Spark Streaming utiliza as APIs Dataframe e Dataset,


que internamente funcionam com RDDS, o Structured Streaming utiliza API
DStream.
b) ( ) RDDs do Spark são mais otimizados do que os Dataframes do
Structured Stream quando se trata de processamento.
c) ( ) Ambos apresentam tratamento a falhas, embora o Spark Streaming
utilize duas condições a mais e seja mais completo para tratar falhas.
d) ( ) Para armazenar os resultados, o Spark Streaming utiliza o conceito de
microlotes, e o Structured Streaming atualiza uma tabela de resultados.
e) ( ) O Structured Streaming só controla o tempo de ingestão do dado,
enquanto o Spark Streaming suporta controle do tempo com base no horário
de acontecimentos.

3 O Spark Streaming é considerado um framework que torna simples a criação


de aplicações em fluxos de dados. Marque a opção que representa uma
característica do Spark Streaming.

a) ( ) Ingestão de única fonte.


b) ( ) Sem tolerância a falhas.
c) ( ) É facilmente escalável.
d) ( ) Apresenta alta latência.
e) ( ) Não processa lotes.

4 Para criar uma aplicação utilizando o Spark Streaming, é necessário seguir


algumas etapas, sendo uma delas a criação de objetos de tipos específicos.
Marque a opção que representa o tipo do objeto em que é configurado o local
de execução da aplicação, o número de threads e o nome da aplicação.

a) ( ) JavaStreamingContext.
b) ( ) SparkConf.
c) ( ) JavaReceiverInputDStream.
d) ( ) JavaDStream.
e) ( ) JavaPairDStream.

118
UNIDADE 2
TÓPICO 4

FRAMEWORKS DE ARMAZENAMENTO
NÃO ESTRUTURADOS

1 INTRODUÇÃO
Os dados não estruturados representam mais de 80% dos dados existentes
no mundo. Com tanta informação em potencial, foi necessário desenvolver novas
soluções de armazenamento que não apenas pudessem guardar esses dados, mas
que fossem capazes de assegurar que eles ficassem íntegros e com fácil acesso.
Além disso, como as fontes dos dados são crescentes, as novas soluções devem
ser capazes de escalar o armazenamento o quanto for necessário, sem perder
tempo de execução enquanto isso é realizado.

Neste tópico, você vai aprender o que é o Hadoop Distributed File System
(HDFS) e quais são as suas principais vantagens e utilizações. Você conhecerá
também como o armazenamento em nuvem de grandes empresas — como
Amazon, Microsoft, Google e IBM — superou as limitações que existiam quanto
a custo e escalonamento. Por fim, você compreenderá quais são as principais
operações realizadas em dados não estruturados.

2 ECOSSISTEMA HADOOP E HDFS


É praticamente impossível falar de big data sem citar o Hadoop, um fra-
mework open-source que possibilita o processamento de grandes volumes de da-
dos. O Hadoop foi originalmente lançado pela empresa Yahoo!, em 2008. Anos
depois, passou a ser gerenciado pela Apache Software Foundation, que o mantém
até hoje. Graças à sua eficácia, o Hadoop se consolidou como um ecossistema de
tecnologias amplamente útil, sendo utilizado por uma gama de empresas conhe-
cidas mundialmente, como Adobe, Alibaba, ebay, Facebook, LinkedIn, Twitter, a
própria Yahoo!, dentre outras (ASF INFRABOT, 2019). Embora tenha sido criado
com o objetivo de realizar buscas em milhões de páginas web, o Hadoop se tor-
nou um conjunto versátil de ferramentas, podendo ser utilizado de diferentes
maneiras, por exemplo: sandbox para análise de dados e obtenção de insights,
armazenamento de dados brutos (componente de um data lake), armazenamento
de informações empresariais (data warehouse) e armazenamento geral de dados
de baixo custo.

119
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

O Hadoop é formado por quatro módulos básicos: Hadoop Common, que


constitui as bibliotecas e funções gerais necessárias para o funcionamento dos ou-
tros módulos; YARN (Yet Another Resource Negotiator), uma plataforma de geren-
ciamento de recursos computacionais; MapReduce, sistema para programação
paralela de grandes volumes de dados; Ozone, um sistema de armazenamento de
objetos; Submarine, uma plataforma unificada de ferramentas de machine e deep
learning; e HDFS, sistema de armazenamento distribuído de dados (APACHE
SOFTWARE FOUNDATION, 2020; WHITE, 2012).

O sistema de arquivos distribuídos Hadoop (HDFS, Distributed File Sys-


tem) é um dos mais conhecidos frameworks para armazenamento de grandes
volumes de dados no universo do Big Data, que podem ser estruturados, semies-
truturados ou não estruturados. Sendo um dos quatro componentes básicos do
Hadoop, ele foi projetado para armazenar os dados em uma estrutura distribuída
em hardware comum, para facilitar o seu escalonamento. Além da escalabilidade
para armazenar grandes volumes de dados, o Hadoop apresenta outras caracte-
rísticas, como alta disponibilidade, tolerância a falhas, realização de redireciona-
mento automático de dados e possibilidade de portabilidade entre hardwares e
sistemas similares (APACHE SOFTWARE FOUNDATION, 2020).

3 ARQUITETURA
Nesse sistema, os dados e metadados são armazenados separadamente. Os
metadados são armazenados em um servidor intitulado NameNode e, enquanto
os dados são armazenados em DataNodes, ambos ficam conectados entre si, com
comunicação constante. Dentro dos NameNodes, ficam registrados diferentes
atributos, que incluem tempo de modificação, permissão, acesso do arquivo e
espaço em disco. O conteúdo de cada arquivo é dividido em blocos de tamanho
definido e replicado em diferentes DataNodes para garantir a integridade e
durabilidade dos dados, conforme ilustra a Figura 10.

FIGURA 10 – EXEMPLO DE ESTRUTURA DO HDFS E REPLICAÇÃO DE UM NÓ QUANDO SEU


PULSO PARA DE SER ENVIADO

FONTE: Adaptado de Hanson (2013)

120
TÓPICO 4 | FRAMEWORKS DE ARMAZENAMENTO NÃO ESTRUTURADOS

Todos os blocos que constituem um arquivo, com exceção do último,


têm o mesmo tamanho, que é, por padrão, 128 megabytes, e são replicados em
três DataNodes, também por padrão. Cada cluster do HDFS possui um único
NameNode primário, que gerencia o espaço para a identificação do sistema
de arquivos e regula o acesso aos arquivos pelos clientes. Além disso, vários
DataNodes gerenciam o armazenamento anexado aos nós em que são executados.
Uma vantagem do HDFS é que são criados servidores web que possibilitam a
verificação do status atual de armazenamento dos NameNodes e DataNodes
(PATIL; SONI, 2013).

4 TOLERÂNCIA A FALHAS
Um sistema é tolerante a falhas quando continua funcionando correta-
mente mesmo que um dos seus componentes tenha parado de funcionar ade-
quadamente, ou seja, falhado. O objetivo principal do HDFS é armazenar dados
de maneira confiável mesmo na presença de falhas. Os dois métodos principais
que possibilitam a sua alta tolerância a falhas são: replicação de dados e ponto de
verificação e recuperação.

A replicação de dados consiste em copiar um mesmo dado várias vezes


e alocá-lo em nós diferentes. Essa é uma técnica eficaz que possibilita uma recu-
peração de falhas imediata e alta disponibilidade, mas tem como desvantagem
consumir uma grande quantidade de memória de armazenamento devido à re-
dundância de informações guardadas.

Sempre que é solicitado o acesso aos dados pelo usuário, o NameNode pro-
cura por todos os DataNodes onde esses dados estão contidos e fornece o primeiro
que está em funcionamento. Esse funcionamento é monitorado através de pulsos
enviados a partir dos DataNodes. Quando o NameNode para de receber a pulsação
de um DataNode, assume que ele não está funcionando. Nesse caso, é realizada a
verificação dos dados que estavam ali contidos e, após, é criada uma réplica deles.
No caso da identificação de um DataNode “morto” durante a solicitação de um
usuário, o NameNode busca o próximo nó em funcionamento para fornecer os da-
dos enquanto a replicação do nó morto realizada paralelamente, sem interrupção
do acesso aos dados. Portanto, no caso de falha de um dos nós, os dados continuam
altamente disponíveis para o usuário (SHVACHKO et al., 2010).

Já o ponto de verificação e recuperação possibilita a reversão de modifi-


cações causadas no sistema até um determinado intervalo de tempo após a mo-
dificação ter sido realizada. Isso funciona como um programa básico de texto,
por exemplo, onde são feitas diferentes modificações, mas há a opção de salvar
o arquivo sem salvar e abri-lo novamente com a versão do último salvamento.
Esse método é custoso e aumenta o tempo geral de execução do sistema, pois as
operações de reversão precisam voltar e verificar os últimos estágios consistentes
que existem, aumentando, portanto, o tempo de execução (PATIL; SONI, 2013).

121
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

Para cada NameNode, existem dois arquivos: fsimage, que armazena o


ponto de verificação mais recente; e log, que é como um diário de alterações des-
de o ponto de verificação. Quando o NameNode é inicializado ocorre uma união
das alterações (log) com o ponto de verificação ( fsimage) para criar um meta-
dado atualizado do sistema de arquivos. Então, esse se torna o novo fsimage e
um diário log é iniciado do zero, partindo desse novo ponto. Esse novo ponto de
verificação é atualizado periodicamente.

A atualização periódica do log e sua cópia para o fsimage é realizada por


um Namenode secundário. Esse segundo NameNode é controlado por dois pa-
râmetros de configuração: dfs.namenode.checkpoint.period, que define o tempo
máximo entre dois pontos de verificação consecutivos, que é de uma hora, por
padrão; e dfs.namenode.checkpoint.txns, que define o número exato de transa-
ções não verificadas no NameNode primário, que forçará uma atualização do
ponto de verificação mesmo que o tempo máximo não tenha sido atingido, isto é,
por padrão, um milhão (APACHE SOFTWARE FOUNDATION, 2020).

O HDFS suporta uma distribuição hierárquica tradicional de arquivos


que possibilita a criação de diretórios/pastas e o armazenamento de arquivos
dentro deles. A permissão para esses arquivos e diretórios é similar ao modelo de
interface portátil entre sistemas operacionais definido pelo Institute of Eletrical and
Eletronic Engineers. Nesse modelo de permissão, é possível executar operações de
leitura e gravação dos arquivos e cada arquivo/diretório pertence a um proprie-
tário e um grupo.

Embora as suas funcionalidades, capacidades de distribuição, integridade


de dados e tolerância a falhas sejam excelentes, o HDFS vem dividindo espaço
com ferramentas de armazenamento em nuvem. Isso ocorre porque o custo para
armazenar na nuvem pode ser mais baixo em longo prazo, possibilitando um
aumento de volume de armazenamento muito mais rápido e econômico.

O HDFS e o Hadoop não são a mesma coisa. O Hadoop é um ecossistema


onde estão contidas diferentes aplicações para o processamento, organização e
armazenamento de grandes volumes de dados. O HDFS faz parte desse ecossis-
tema, sendo um framework de armazenamento.

5 ARMAZENAMENTO EM NUVEM
O armazenamento em nuvem é um serviço que surgiu em conjunto com
a chamada computação em nuvem, que corresponde a uma gama de recursos da
tecnologia da informação que podem ser utilizados sob demanda, sem a necessi-
dade de uma estrutura física local robusta. Além do armazenamento, esses recur-
sos incluem ambientes pré-configurados para a criação de data lakes, plataformas
de análises de dados, aprendizado de máquina, dentre outros (AWS, 2020). Essa
utilização sob demanda pode reduzir os custos físicos e operacionais das empre-
sas, além de poder apresentar maior segurança em relação a alguns sistemas de
armazenamento físico.
122
TÓPICO 4 | FRAMEWORKS DE ARMAZENAMENTO NÃO ESTRUTURADOS

Segundo o estudo realizado pela RightScale, em 2018, com 997 represen-


tantes de empresas de pequeno, médio e grande porte, os principais serviços de ar-
mazenamento em nuvem utilizados naquele ano foram: Amazon Web Service, Mi-
crosoft Azure, Google Cloud Storage e IBM Cloud, conforme apresenta o Gráfico 1.

GRÁFICO 1 – UTILIZAÇÃO DA NUVEM PÚBLICA POR EMPRESA

FONTE: Adaptado de Right Scale (2018)

5.1. AMAZON S3
Amazon Web Services (AWS) é a plataforma de nuvem da empresa
transnacional Amazon. É a mais utilizada e abrangente do mundo, com mais de
175 serviços completos em nuvem disponíveis para o usuário. Além do maior
número de serviços, a AWS também possui a infraestrutura global mais extensa,
com 69 zonas de disponibilidade, em mais de 20 regiões geográficas, que são
conectadas por redes de baixa latência, alta taxa de transferência e redundância.

Dentre os serviços oferecidos, podem ser encontradas dez soluções de


armazenamento, com diferentes características e aplicações. O serviço que mais
se destaca para utilização em big data é o serviço de armazenamento simples
Amazon S3, que é uma plataforma com alta durabilidade, ajuste de escala,
possibilidade de disponibilização dos dados a partir de qualquer lugar com
acesso à internet e que pode ser utilizada para arquivamento ativo, computação
sem servidor e backup de dados.

Além das plataformas de armazenamento, também estão contidas na


AWS plataformas mais complexas para o processamento de big data, como:

● AWS Lake Formation: é um serviço que facilita a configuração de um data lake.


A partir dele, é possível coletar, catalogar, limpar e classificar os dados, além
de proteger o acesso confidencial.

123
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

● Amazon EMR: é uma plataforma de big data nativa da nuvem, que oferece
suporte a 19 projetos de código aberto, como Apache Spark, Hive, HBase,
Flink, dentre outros. Esses projetos podem ser combinados à escalabilidade
dinâmica do Amazon EC2 e ao armazenamento escalável do Amazon S3.

Essas e outras plataformas podem ser conhecidas e exploradas no site


oficial de soluções da Amazon, disponível no link a seguir (AWS, [201–?]).

Segundo a empresa, o S3 é líder em escalabilidade, disponibilidade,


segurança e desempenho frente a todas as outras soluções com esse propósito.
No serviço de armazenamento, são disponibilizados recursos de gerenciamento
de dados e configurações de controle de acesso aprimoradas para utilização
comercial e organizacional. Qualquer tipo ou volume de dados pode ser
armazenado utilizando o S3, de forma que não é necessário se preocupar em
como o dado é armazenado, podendo focar apenas na sua utilização.

Dentro do S3, existem diferentes classes de armazenamento de acordo


com o padrão de acesso esperado para os dados: S3 Standard, que é o mais geral,
podendo armazenar qualquer dado e ser utilizado com frequência; Intelligent-
tiering, utilizado para dados com padrão de acesso dinâmico; Standard Infrequent
Access e One Zone Infrequent Access, que são recomendados para dados de longa
vida pouco acessados; por fim, o Glacier, que recomendado para arquivamento
de dados. Essa disponibilidade de opções ajuda a calcular o custo de utilização da
plataforma, sendo o S3 o serviço mais caro e Glacier o mais barato.

Amazon S3 fornece proteção aos objetos armazenados em um bucket com


controle de versão. Esse controle pode ser usado para restaurar versões mais
antigas de um objeto no caso de corrupção ou exclusão, mesmo que tenha sido
realizada pelo usuário.

5.2 MICROSOFT AZURE STORAGE


O Azure é um serviço de armazenamento em nuvem da Microsoft, que
se caracteriza por ser altamente disponível, seguro, escalonável e redundante.
O armazenamento do Azure inclui blobs (objetos) do Azure, DataLake Gen2,
arquivos, filas e tabelas do Azure. Uma assinatura do Azure pode hospedar até
100 contas, cada uma com capacidade de armazenamento para 500 TB (COLLIER;
SHAHAN, 2015).

Cada conta de armazenamento pode ser configurada com diferentes


níveis de redundância: localmente redundante, que fornece alta disponibilidade,
garantindo que três cópias de todos os dados sejam feitas de forma síncrona
antes que uma gravação seja considerada bem-sucedida, fazendo com que eles
fiquem disponíveis mesmo que um nó de armazenamento falhe; redundância
geográfica, na qual existem três cópias síncronas dos dados na região principal
para alta disponibilidade, criando de forma assíncrona também três réplicas

124
TÓPICO 4 | FRAMEWORKS DE ARMAZENAMENTO NÃO ESTRUTURADOS

em uma região pareada para recuperação de desastres; geo-redundante, que é


um armazenamento de leitura adequado para recuperação parcial de desastres.
Se houver um problema com a região principal, é possível ter acesso, no modo
somente leitura, à região emparelhada (PETERSON, 2016).

O Azure pode ter redes virtuais e também pode ser conectado à rede
corporativa. Os requisitos de armazenamento podem ser tratados na categoria
padrão e também na categoria premium. A Microsoft possui 20 regiões
diferentes para o Azure em vários locais, como Ásia, Austrália, Europa e Brasil
(MICROSOFT AZURE, 2020b). Além do serviço de armazenamento em nuvem, a
plataforma também disponibiliza outros serviços para a construção de aplicações
distribuídas, como o SQL Azure Database, Azure AppFabric Platform e uma API
de gerenciamento e monitoração para aplicações colocadas na nuvem. Assim
como a Amazon, o Azure também oferece um serviço de data lake na nuvem. O
Azure Data Lake é baseado em Hadoop e em outras ferramentas do ecossistema
(MICROSOFT AZURE, 2020b).

5.3 GOOGLE CLOUD STORAGE


O Google Cloud Storage é uma solução de armazenamento do Google que
está contida na Google Cloud Platform, uma plataforma de ferramentas poderosas
com diferentes propostas e aplicações para big data. Além do armazenamento,
possível utilizá-la para processamentos, análises e arquivo. Embora existam
outras soluções dentro da plataforma, como Drive, Storage para Firebase,
Persistent Disk e FileStore, o Cloud Storage é o mais indicado pela empresa para
armazenamento de um grande volume de dados não estruturados em nuvem.

O armazenamento no Cloud Storage é feito a partir de objetos, de forma


que cada objeto contém um arquivo estruturado ou não, de qualquer formato. Um
grupo de objetos é chamado de intervalo e todos os intervalos ficam contidos em
um projeto. Dentro de cada projeto, é possível conceder permissões diferentes dos
objetos para distintos usuários, inclusive podendo deixá-los livres para acesso de
qualquer pessoa na internet. Existem quatro diferentes tipos de armazenamento
de acordo com o tempo de armazenamento e a frequência de acesso: Standard,
adequado para dados que são acessados globalmente, como veiculação em
páginas e streaming; Nearling, ideal para dados que serão lidos ou modificados,
em média, uma vez por mês; Coldline ideal para dados que serão acessados, no
máximo, uma vez por trimestre; por fim, o Archive, em que o tempo mínimo
de armazenamento é de 365 dias, sendo indicado para backup e recuperação de
desastres (GOOGLE CLOUD, 2020a).

5.4 IBM CLOUD STORAGE


O IBM Cloud Storage é um serviço de armazenamento altamente esca-
lável fornecido pela IBM. Assim como os outros serviços, apresenta diferentes

125
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

classes de armazenamento visando atender diferentes necessidades do usuário,


com custos distintos entre elas. Nesse caso, existem cinco tipos: Standard, para
cargas de trabalho ativas; Vault, para aqueles dados acessados em uma frequên-
cia menor; Cold Vault, para os dados muito pouco acessados; Flex, para cargas
de trabalho dinâmicas, e Archive, para retenção de dados por longos períodos,
como backups.

O IBM Cloud Object Storage é a solução do mercado com menor custo


para o armazenamento ativo de dados. Devido às tecnologias empregadas na
plataforma, é possível reduzir o custo de armazenamento em até 54% sobre os
sistemas de gerações anteriores e obter até 150% de melhor desempenho. O tipo
de armazenamento padrão (Standard) é utilizado para as cargas de trabalho ativas
que necessitam de alto desempenho e baixa latência, onde os dados precisam
ser acessados frequentemente. Nesse tipo de armazenamento, ao invés de ser
utilizada a replicação de dados a fim de obter alta disponibilidade, utilizada uma
tecnologia de codificação de eliminação (COYNE et al., 2018). A estrutura simples
e estável desse storage possibilita o escalonamento de forma flexível, sendo ideal
para dados não estruturados. O armazenamento distribuído e acessível por API
pode ser integrado diretamente aos aplicativos e essa integração simples torna
mais fácil estabelecer um fluxo de aplicativos nativos em cloud, possibilitando
uma forma eficiente e rápida de atualizar componentes de aplicativos.

DICAS

É possível estimar os gastos de um armazenamento em nuvem de forma


rápida, fácil e gratuita. Confira a seguir os links de calculadoras de custos de cada uma das
soluções apresentadas.
Calculadora de custos da Amazon (AWS, 2020c)
https://qrgo.page.link/d1dTe

Calculadora de custos da Google (GOOGLE CLOUD, 2020b)


https://qrgo.page.link/bnNLX

Calculadora de custos da Azure (MICROSOFT AZURE, 2020a)


https://qrgo.page.link/qK2Um

Calculadora de custos da IBM (IBM CLOUD, 2019)


https://qrgo.page.link/cyf7e

6 HDFS ON-PREMISE E ARMAZENAMENTO EM NUVEM


Para comparar as soluções de armazenamento apresentadas, é preciso
avaliar o custo total de aquisição e operação de cada uma delas para um mesmo
volume de dados. No exemplo a seguir, será utilizado o volume de 100 TB. O

126
TÓPICO 4 | FRAMEWORKS DE ARMAZENAMENTO NÃO ESTRUTURADOS

custo total é a soma de investimentos necessários para que a solução seja ad-
quirida e mantida, incluindo custo de trabalho humano e estrutura. De acordo
com o relatório da IDC liberado pela Amazon, utilizar o armazenamento do AWS
resulta em uma economia de 64,3% em comparação à implantação dos mesmos
recursos em ambientes locais. Já a alteração do armazenamento ativo do HDFS
para o Google Cloud Storage, geralmente, tem um custo total de propriedade
57% menor.

O custo de armazenamento de 1 TB correspondia a $ 206 por mês, em


2017, segundo o levantamento realizado por Xin, Rosen e Pistor (2017). Para o
exemplo de 100 TB, esse custo alcança o montante de $ 20.600. Para esse mesmo
volume de armazenamento, a calculadora on-line de custos mensais da Amazon,
para a América do Sul, na região de São Paulo, calculou o valor mensal de $ 4.070.
Já o serviço do Google Cloud Storage custaria $ 3.584 ao mês. O Azure, por sua
vez, teria um valor igual a $ 3.279 e o IBM Cloud Storage, por fim, acabou sendo
o mais barato, com um custo de $ 3.000/ TB/mês.

Diante desses valores de custo e levando em consideração que o armaze-


namento em nuvem possui outras vantagens, como alta elasticidade, capacida-
de computacional, distribuição global e integração com diferentes ferramentas
de processamento e análise, esse tipo de armazenamento parece apresentar um
maior custo-benefício que o HDFS local, além de possibilitar que as empresas
estejam sempre em armazenamento sem que seja necessário se preocupar com a
estrutura física e rotinas de manutenção. O Quadro 2 apresenta uma comparação
entre os diferentes serviços.

QUADRO 2 – VANTAGENS E DESVANTAGENS DE SOLUÇÕES DE ARMAZENAMENTO

FONTE: O Autor

127
UNIDADE 2 | PARTICIONAMENTO DE BANCO DE DADOS

7 OPERAÇÕES SOBRE DADOS NÃO ESTRUTURADOS


Para que todo banco de dados funcione bem, é necessário ter operações bá-
sicas de manipulação de dados, como operações de leitura e gravação. No HDFS,
essas operações são realizadas a partir do NameNode. Para gravar um dado é
preciso interagir com o NameNode, que fornece o endereço dos DataNodes onde
ocorrerá a gravação. Para ler um arquivo, o NameNode verifica os privilégios
necessários e fornece o endereço dos DataNodes em que o dado está armazenado.

Para gravar um dado, é executado um comando que cria um novo arqui-


vo sem blocos associados a ele no espaço do NameNode. Então, verificações são
executadas pelo NameNode para garantir que esse dado de fato ainda não existe.
No caso de existir, é necessária uma permissão para substituição. Em seguida,
o NameNode determina um local para gravar os blocos, onde são escritos pelo
cliente. Após a gravação dos dados, o HDFS começa a replicar os blocos em ou-
tros DataNodes, criando várias réplicas. Ao final da gravação existe um pipeline
e pelo menos três cópias de blocos diferentes conforme a lista a seguir.

• O cliente inicia a operação de gravação chamando o método create ().


• O objeto se conecta ao NameNode usando a chamada RPC (Remote Procedure
Call) e inicia a nova criação de arquivo. Se o arquivo já existir ou o cliente não
tiver permissão suficiente para criar um arquivo, será emitido um alerta de
erro para o cliente. Caso contrário, a operação será bem-sucedida e um novo
registro para o arquivo será criado pelo NameNode.
• Depois que um novo registro no NameNode é criado, um objeto é retornado ao
cliente. O cliente usa para gravar dados no HDFS. Enquanto o cliente continua
gravando dados, pacotes continuam sendo criados. Esses pacotes são enfileira-
dos.
• É escolhida através do NameNode a alocação de novos blocos, escolhendo,
assim, DataNodes desejáveis para serem usados para replicação.
• O processo de replicação começa criando um pipeline usando DataNodes.
• Todo DataNode em um pipeline armazena o pacote recebido por ele e encami-
nha para o segundo DataNode em um pipeline.
• Outra fila, Ack Queue, é mantida pelo DFSOutputStream para armazenar pa-
cotes que aguardam confirmação do DataNodes.
• Depois que o reconhecimento de um pacote na fila é recebido de todos os Data-
Nodes no pipeline, ele é removido da Fila de confirmação. No caso de qualquer
falha do DataNode, os pacotes dessa fila são usados para reiniciar a operação.
• Depois que um cliente finaliza a gravação dos dados, ele chama um método
close ().
• Ocorre a liberação dos pacotes de dados restantes no pipeline, seguido pela
espera pelo reconhecimento.
• Depois que uma confirmação final é recebida, o NameNode é contatado para
informar que a operação de gravação de arquivo está concluída.

Ao enviar uma solicitação de leitura ao NameNode, é realizada uma ve-


rificação de permissão de acesso. Se o cliente tiver permissão àquele dado, o en-
dereço dos DataNodes que contêm aqueles dados é liberado e pode ser lido pelo

128
TÓPICO 4 | FRAMEWORKS DE ARMAZENAMENTO NÃO ESTRUTURADOS

cliente. Agora, o cliente começa a ler os blocos usando uma API e os dados são
transmitidos continuamente para o cliente. Após atingir o final de um bloco, a
conexão é fechada. Confira o passo a passo a seguir.

• Um cliente inicia a solicitação de leitura chamando o método open () do objeto


FileSystem.
• Este objeto se conecta ao NameNode usando RPC e obtém informações de me-
tadados, como os locais dos blocos do arquivo. Observe que esses endereços
são os primeiros blocos de um arquivo.
• Em resposta a essa solicitação de metadados, os endereços dos Data-Nodes
com uma cópia desse bloco são retornados.
• Depois que os endereços de DataNodes são recebidos, um objeto é retornado
ao cliente. O cliente chama o método read () que faz com que se estabeleça uma
conexão com o primeiro DataNode com o primeiro bloco de um arquivo.
• Os dados são lidos na forma de fluxos em que o cliente chama o método read
() repetidamente. Esse processo de operação read () continua até atingir o final
do bloco.
• Quando o final de um bloco é atingido, é fechada a conexão e, em seguida,
ocorre a localização do próximo DataNode para o próximo bloco.
• Depois que um cliente conclui a leitura, ele chama um método close ().

Dados não estruturados podem ser perfeitamente armazenados local-


mente ou em nuvem, mas algumas outras características requeridas para arma-
zenamento devem ser levadas em consideração. Algumas delas são disponibili-
dade de infraestrutura, custos, elasticidade e disponibilidade de acesso. Em um
cenário onde a infraestrutura já está estabelecida, custo não um problema, não
há previsão de aumentar o volume armazenado e não há necessidade de acesso
remoto aos dados de forma simplificada. Portanto, o HDFS on-premise pode ser
uma boa opção. Caso contrário, as soluções de armazenamento em nuvem pos-
suem ferramentas que solucionam todos esses pontos.

Com a computação em nuvem, os dados não estruturados podem ser arma-


zenados de forma eficaz e elástica de modo praticamente infinito. Além disso, não
é necessário se preocupar com infraestrutura ou manutenção local, sendo também
possível ter uma alta disponibilidade e facilitação de acesso dos dados por um cus-
to até sete vezes mais reduzido do que outras alternativas, como o HDFS. Escolher
o armazenamento de uma empresa é uma decisão importante que precisa ser toma-
da com cautela e atenção. De qualquer forma, sempre possível fazer modificações e
testar novas soluções até encontrar a mais adequada ao tipo de negócio.

CHAMADA

Ficou alguma dúvida? Construímos uma trilha de aprendizagem


pensando em facilitar sua compreensão. Acesse o QR Code, que levará ao
AVA, e veja as novidades que preparamos para seu estudo.

129
RESUMO DO TÓPICO 4
Neste tópico, você aprendeu que:

• Embora o HDFS tenha sido, por muito tempo, “a menina dos olhos” do
universo do Big Data, a computação em nuvem vem conquistando cada vez
mais adeptos.

FONTE: O Autor

130
AUTOATIVIDADE

1 Sabe-se que, independente de qual seja, as formas de armazenamento


de dados devem ser capazes de gravar, armazenar e permitir a leitura de
informações. Entretanto, quando se trata de um grande volume de dados,
apenas isso não é o suficiente. É necessário que sejam cobertos pelo menos
outros três pontos cruciais para a manipulação de big data. Quais são eles?

a) ( ) Tamanho, volume e preço.


b) ( ) Volume, variedade e tamanho.
c) ( ) Velocidade, rapidez e volume.
d) ( ) Volume, variedade e velocidade.
e) ( ) Volume, variedade e preço.

2 Cada framework de armazenamento guarda os dados em um determinado


formato, de acordo com a arquitetura para a qual foi projetado. Esses dados
podem ser armazenados em forma de arquivo, bloco ou objeto. Qual é a
característica de um "objeto"?

a) ( ) Possuir metadado e dado.


b) ( ) Ser dividido em diferentes partes de tamanhos iguais.
c) ( ) Estar dentro de pastas.
d) ( ) Ter tamanho inferior a 1 GB.
e) ( ) Ter tamanho superior a 60 GB.

3 O armazenamento em nuvem vem ganhando cada vez mais espaço. Os


serviços prestados pela Amazon (S3), Microsoft (Azure) e Google (Cloud
Storage) são alguns dos principais do mercado. Entre eles existem muitas
coisas em comum, mas um se distingue principalmente por:

a) ( ) Preço.
b) ( ) Elasticidade.
c) ( ) Abordagem de armazenamento.
d) ( ) Quantidade de disponibilidade.
e) ( ) Durabilidade.

131
132
UNIDADE 3

DADOS SEMI-ESTRUTURADOS
E SHARDING

OBJETIVOS DE APRENDIZAGEM
A partir do estudo desta unidade, você deverá ser capaz de:

• compreender o papel de cada tipo de banco de dados na distribuição;

• conhecer o conceito de sharding;

• aplicar sharding utilizando bancos de dados NoSQL;

• ver o funcionamento de sharding utilizando framework.

PLANO DE ESTUDOS
Esta unidade está dividida em três tópicos. No decorrer da unidade você
encontrará autoatividades com o objetivo de reforçar o conteúdo apresentado.

TÓPICO 1 – FRAMEWORKS DE ARMAZENAMENTO


SEMIESTRUTURADOS

TÓPICO 2 – SHARDING

TÓPICO 3 – FRAMEWORKS QUE UTILIZAM SHARDING COMO


FORMA DE DISTRIBUIÇÃO

CHAMADA

Preparado para ampliar seus conhecimentos? Respire e vamos


em frente! Procure um ambiente que facilite a concentração, assim absorverá
melhor as informações.

133
134
UNIDADE 3
TÓPICO 1

FRAMEWORKS DE ARMAZENAMENTO
SEMIESTRUTURADOS

1 INTRODUÇÃO
Dados semiestruturados estão presentes em toda a web e representam
uma parcela dos dados que formam o big data. Esse tipo de dado necessita de
formas específicas de armazenamento e manipulação para que seja aproveitado
da melhor maneira. Por isso, é importante saber quais são os principais bancos
que comportam esses dados.

Neste tópico, você vai conhecer os bancos de dados NoSQL mais utiliza-
dos voltados para dados não estruturados, principalmente, os que são orientados
a documentos e grafos. Além disso, aprenderá sobre a capacidade de particiona-
mento e replicação deles, conhecendo as suas características e entendendo o que
possibilita que eles lidem com uma grande quantidade de dados. Por fim, você
será apresentado às operações de manipulação de gerenciadores de bancos de
dados CRUD (create, read, update e delete) e como elas são utilizadas no processo
de armazenamento.

2 CARACTERÍSTICAS DOS BANCOS DE DADOS NoSQL


Os bancos de dados mais populares do universo digital são os bancos
relacionais. Esses bancos utilizam como linguagem padrão a linguagem de con-
sulta estruturada (SQL, structured query language), que, devido a sua utilização.

Simples e de rápido aprendizado, é amplamente difundida e utilizada


desde a década de 1970. Esse uso amplo também pode ser justificado pelos seus
recursos, os quais, dentre outras funções, possibilitam a manipulação e definição
de dados (ORACLE BRASIL, 2020c).

Embora os bancos de dados relacionais sejam muito úteis, o grande aumen-


to de volume de dados nos últimos anos trouxe algumas limitações no seu uso.

Embora eficazes, essas bases não foram projetadas para comportar um


volume tão grande, nem para lidar com a necessidade imediata de aumento da
capacidade de processamento de forma simples. Outra limitação dos bancos re-
lacionais é não suportar objetos de forma nativa, sendo necessário mapear os ob-
jetos para a estrutura da base.
135
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

Para solucionar esses problemas e conseguir armazenar os dados de big


data eficientemente, surgiu o NoSQL. NoSQL significa, literalmente, não apenas
SQL (not only SQL) e, por isso, engloba todos os bancos que não seguem os prin-
cípios dos outros relacionais, estando associados a um grande volume de dados
(HIRIYANNAIAH et al., 2018).

Existem algumas características que fundamentam os NoSQL e os tornam


diferentes dos SQL:

• escalabilidade: o poder de processamento pode ser aumentado à medida que o


volume dos dados cresce;
• esquema flexível ou ausente: não existe obrigatoriamente uma estrutura dos
dados modelados, o que facilita a escalabilidade e contribui para uma maior
disponibilidade;
• suporte à replicação: diminui o tempo gasto para recuperar informações;
• API simples: promove uma forma eficiente de acesso aos dados, oferecendo
alta disponibilidade e escalabilidade, facilitando a recuperação dos dados;
• consistência eventual: tolera inconsistências temporárias e prioriza a
disponibilidade (NILSSON; BENGTSON, 2017).

Por conta da abrangência do NoSQL, há diferentes tipos de bancos de


dados. Uma das formas de classificar esses bancos é de acordo com o modelo de
dados: chave-valor, colunas, documentos e grafos, de forma que os dois últimos
estão mais associados a dados semi estruturados.

São também reconhecidos como NoSQL os modelos de bancos de dados


de RDF (triplestores), de XML nativo (native XML DBMS), orientados a conteúdo
(content stores) e motores de busca (search engines). Além disso, há outros modelos
alternativos que, apesar de não serem tão amplamente reconhecidos como não
relacionais, também são utilizados para armazenar dados semiestruturados:
séries temporais (time series), orientado a objetos (object oriented), banco de dados
multivalores (multivalue), banco de dados orientado a eventos (event stores) e
bancos de dados navegacionais (navigational).

As principais diferenças entre bancos de dados SQL e NoSQL são:

QUADRO 1 - PRINCIPAIS DIFERENÇAS ENTRE BANCOS DE DADOS SQL E NoSQL

SQL NoSQL
Sistema de dados relacionais Sistema de dados não relacionais
Escalável verticalmente Escalável horizontalmente
Estrutura estática Estrutura dinâmica
Downtime para aumentar a Aumento automático de
capacidade processamento
FONTE: O Autor

136
TÓPICO 1 | FRAMEWORKS DE ARMAZENAMENTO SEMIESTRUTURADOS

3 ONDE GUARDAR DOCUMENTOS E GRAFOS


No modelo de documento dos bancos de dados NoSQL, cada entrada é
um documento e cada um deles é decomposto em valor e identificador. Utilizan-
do essa estrutura, os documentos são codificados, principalmente, em formatos
como JSON, BSOn e XML, além dos formatos binários PDF e DOC, por exemplo.
Já o modelo de banco de dados que se baseia em grafos utiliza vértices e ramos
para representar a informação contida nos dados. Esse modelo possibilita acres-
centar ou remover vértices e ramos de forma simples e rápida, além de possibili-
tar uma busca de forma mais eficaz e veloz (NILSSON; BENGTSON, 2017).

Existem diversas soluções de NoSQL para esses dois modelos, mas, de


acordo com a iniciativa DB-Engines, que coleta e apresenta informações sobre
sistemas de gerenciamento de bancos de dados, no início de 2020, os bancos NoS-
QL mais utilizados eram MongoDB, DynamoDB, Neo4j e CouchBase, conforme
ilustra o Gráfico 1.

GRÁFICO 1 - RANKING DE PRINCIPAIS BASES NOSQL DOS MODELOS DE DOCUMENTOS E


GRAFOS, SEGUNDO DADOS DO DB-ENGINES

FONTE: Adaptada de DB-Engines (2020)

• MongoDB

O nome “Mongo” deriva da palavra inglesa humongous, que significa


enorme/ imenso/gigantesco, fazendo referência ao volume de dados que o banco
foi desenvolvido para trabalhar. Esse é o banco de dados orientado a documentos
mais utilizado no mundo, com clientes famosos, como Mercado Livre, EasyTaxi
e Petrobrás, por exemplo. MongoDB organiza os dados em documentos e agrupa
esses documentos em coleções, de forma que eles não precisam ter necessaria-
mente os mesmos atributos.
137
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

Além das características de um NoSQL, o MongoDB apresenta outras


vantagens, como linguagem de consulta dinâmica, extensões que permitem o
armazenamento de objetos binários (fotos e textos), indexação por georreferen-
ciamento incluída, além de suportar sharding (método de particionamento) auto-
mático e operações atômicas como funções que unem em uma só operação outras
duas funções.

quanto ao particionamento, o sharding é um escalonamento horizontal


que permite a distribuição automática de documentos entre nós, sem proble-
mas de integridade relacional. No MongoDB, os dados podem ser particionados
em 10, 100 ou 1000 nós, utilizando servidores Mongod e Mongos (MONGODB,
2020b). Além do particionamento, há a replicação automática dos dados para
diferentes nós, o que colabora para uma alta tolerância a falhas de forma que
um nó com problemas pode ser rapidamente substituído, deixando o ambiente
disponível. Além da cópia dos nós e da disponibilidade, a utilização desses nós
replicados é também útil para distribuir a carga de leitura e diminuir a latência
de acesso aos servidores, que são características muito úteis na manipulação de
grandes volumes de dados (KOBELLARZ, 2015).

O conjunto de nós replicados recebe o nome de replicaset, que é dividi-


do em dois tipos: primário (único que recebe operações de escrita) e secundário
(cópias sincronizadas do nó primário). Dentro de um replicaset, é possível haver
até 50 nós. Cada unidade de armazenamento do MongoDB (MMAPv1) permite o
armazenamento de 16 mil arquivos de dados.

• DynamoDB

DynamoDB é um banco de dados oferecido pela Amazon que engloba


dois modelos: chave-valor e documento. Ele é um banco durável, com desempe-
nho de milissegundos, totalmente gerenciado com segurança, backup e restau-
ração. Além de possuir o poder de processar mais de trilhões de solicitações, o
DynamoDB também comporta mais de milhões de solicitações por segundo.

Essa é a escolha de banco de dados para grandes empresas, como Nike,


Airbnb e Samsung. Além disso, milhares de clientes da Amazon Web Service
(AWS) também optam por esse banco, tanto para jogos e aplicativos web quanto
para tecnologias de marketing e internet das coisas.

No DynamoDB, todos os dados são armazenados em discos de estado só-


lido e replicados de forma automática entre diferentes zonas de disponibilidade
da AWS, com alta disponibilidade e durabilidade. No escalonamento de dados,
são criadas partições com tamanhos definidos de 10 GB, de forma que a cada vez
que esse limite é atingido é criada uma nova partição. Ainda, o DynamoDB é ca-
paz de manipular mil unidades de capacidade de gravação e até 3 mil unidades
de capacidade de leitura.

Cada uma das partições do DynamoDB possui três nós, com cópias iguais
da partição. Cada nó possui duas estruturas: um log de replicação, que registra
138
TÓPICO 1 | FRAMEWORKS DE ARMAZENAMENTO SEMIESTRUTURADOS

todas as alterações realizadas, e uma árvore utilizada para consultar itens ali con-
tidos. Um dos nós é sempre nomeado como líder, no qual as operações de grava-
ção ocorrem efetivamente. Caso haja alguma modificação, o que está armazenado
ali é replicado para os outros dois nós. Como um produto da AWS, uma caracte-
rística interessante desse sistema é a possibilidade de programar uma exclusão
automática de documentos em um determinado tempo, ajudando a reduzir o
espaço de uso e armazenamento, que é cobrado sob demanda.

• Neo4j

Neo4j é o sistema de gerenciamento de bancos de dados baseado em grafos


mais utilizado do mundo, tendo sido escolhido por grandes empresas, como
Bayer, Walmart e Volvo. Uma linguagem similar a SQL é utilizada para acessar
e atualizar os dados, chamada Cypher Query Language (CQL) e a estrutura deste
tipo de NoSQL é baseada em nós e arestas, onde os nós armazenam entidades de
dados e as arestas conectam os nós, armazenando o relacionamento entre eles.

NOTA

Cypher é uma linguagem de consulta de grafos simples e poderosa. Ela é, prin-


cipalmente, inspirada em SQL, mas também possui traços de SPARQL, Haskell e Python.
Essa linguagem descreve padrões de nós e relacionamentos, filtrando esses padrões com
base em rótulos e propriedades.

Baseada em ASCII, que é fundamentada em texto para computadores, a sintaxe do Cypher


é simploriamente eficaz e elegantemente baseada na língua inglesa, sendo muito visual
e fácil de ler, além de representar estruturalmente os dados da consulta. Por exemplo, na
linguagem, os nós são representados entre parênteses em torno dos atributos e informa-
ções. Já os relacionamentos são representados com uma seta, direcionada ou não, de
acordo com o tipo de relacionamento existente entre os parênteses (nós) (NEO4J, 2020a).
Para saber mais, acesse o manual do Cypher no link a seguir: https://qrgo.page.link/kFGez.

Nesse tipo de banco de dados, as buscas por associações ocorrem muito


rápido, pois a distância entre os nós (relacionamento) é calculada no momento
da entrada e persiste no banco. Por conta dessa característica, bancos de dados
baseados em grafos são indicados para redes sociais, sistemas de recomendação
de vendas, investigação de fraudes e qualquer outro sistema em que associações
precisam ser consultadas rapidamente.

Neo4j possui alta disponibilidade e é escalável a 34 bilhões de arestas e


vértices (nós). A sua estrutura em clusters, além de favorecer a disponibilidade,
também possibilita a tolerância a falhas. No cluster, cada banco possui uma cópia
perfeita e completa. Dentro do cluster, cada máquina possui uma função: líder ou
seguidor. O líder é responsável por coordenar o cluster e os seguidores dimensio-

139
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

nam a capacidade de carga de leitura e redundância. Toda a coordenação geral


do cluster é feita a partir do algoritmo consenso Raft (RATHLE, 2016).

• CouchDB

CouchDB é um sistema de gerenciamento de banco de dados em que o


armazenamento é feito em coleções de documentos independentes. Cada docu-
mento possui um esquema diferente de acordo com os dados que o compõem. É
o banco escolhido por empresas como Akamai Technologies e Hothead Games.

Esse sistema foi escrito na linguagem de programação Erlang, que possui


o foco na escrita de aplicações robustas e tolerantes a falhas. A principal interfa-
ce de programação do CouchDB é HTTP, enquanto o armazenamento de dados
ocorre utilizando JSON. Esse tipo de codificação é como um subconjunto de to-
dos os tipos nativos e ambientes de programação, contendo números, caracteres,
listas, booleanos, dentre outros (APACHE SOFTWARE FOUNDATION, 2020b).

Por conta disso, ter documentos em formato JSON facilita a troca de da-
dos entre diferentes sistemas, sendo necessário realizar apenas a tradução dessa
codificação para a mais adequada à situação. Outra vantagem é que JSON nativo
da programação web, de forma que a sua compactação é simples e rápida, sendo
uma escolha excelente para aplicativos móveis.

No CouchDB, a replicação de arquivos é de forma bidirecional, possibili-


tando a sincronização dos dados em diferentes dispositivos. Além disso, há uma
“árvore de revisão” para cada documento, nos quais, além da sua versão mais re-
cente, há também informações sobre o que foi alterado em cada versão na ordem
em que ocorreram as alterações. Isso auxilia na redução de conflitos de arquivos,
já que é possível identificar se a versão no local de destino é realmente a última
que foi adicionada. Os clusters do CouchDB realizam a fragmentação automática
dos bancos de dados e os distribuem em subconjuntos de documentos.

Uma das grandes vantagens do CouchDB é que, devido ao seu crescimen-


to e popularização atrelados ao fato de ser um sistema de código aberto, houve
diferentes implementações para outras linguagens e ambientes, que podem fa-
cilitar e expandir o seu uso. Algumas das mais notáveis são PouchDB, TouchDB
e Cloudant Sync. PouchDB é uma implementação em JavaScript projetada para
navegadores , enquanto os outros dois possuem implementações para IOS e An-
droid, podendo ser implementados em dispositivos móveis (IBM CLOUD, 2019).

4 OPERAÇÕES COM DADOS SEMIESTRUTURADOS


Os dados que são armazenados nos sistemas gerenciadores de bancos de
dados (SGBD) possuem uma estrutura de representação ou esquema predefini-
da. Esses esquemas são utilizados como base para a realização de operações de
usuários e aplicativos.

140
TÓPICO 1 | FRAMEWORKS DE ARMAZENAMENTO SEMIESTRUTURADOS

As quatro operações básicas necessárias para que um sistema de armazena-


mento funcione perfeitamente são criação, consulta, atualização e destruição de da-
dos (CRUD). Todos os sistemas apresentados possuem comandos para operações
CRUD, que, embora variem um pouco na semântica, possuem a mesma função.

A partir da operação de criação é possível inserir dados em uma dada


coleção. Quando um primeiro dado é inserido, o documento é automaticamente
criado, não sendo necessária uma ação exclusiva para isso. Ao inserir os dados
subsequentes, eles serão inseridos em novos documentos e armazenados numa
mesma coleção, sem interferir no primeiro dado criado.

A operação de consulta permite descobrir o que há em uma dada coleção.


Geralmente, se utilizada sem parâmetros, retorna todos os documentos ali conti-
dos. Em alguns SGBDs, é possível definir certos parâmetros, de forma que retor-
nam na consulta apenas os que correspondem ao que foi definido. Para realizar
uma atualização, é utilizada uma operação que modifica os documentos já exis-
tentes, sem criar uma segunda cópia deles. Em alguns sistemas, é possível resga-
tar o histórico dessas atualizações para garantir a integridade da última versão.

A última operação do CRUD é a deleção de documentos. Nesse tipo de


operação, é possível também especificar parâmetros para decidir se apenas um
documento será excluído ou se será uma exclusão em massa dos que atendem
àqueles requisitos. As operações CRUD são componentes fundamentais de um
sistema de armazenamento e, geralmente, são de sintaxe simples, facilmente dis-
poníveis nos manuais dos SGBDs. Saber quais elas são e como utilizá-las é fun-
damental para manipular um gerenciador de bancos de dados de forma correta.

DICAS

Você sabia que é possível aprender a utilizar o MongoDB gratuitamente com


cursos oficiais e on-line? Conheça a MongoDB University (2020) no link a seguir.

https://qrgo.page.link/8wFXn

Para saber mais sobre os conceitos básicos do Dynamo realizando tutoriais, visite o site da
Amazon DynamoDB (AWS, 2020d).

https://qrgo.page.link/uBKbo

O Neo4j fornece livros gratuitos, em inglês, para explicar o que são grafos, como o Neo4j
funciona e outros assuntos relacionados a bancos de dados. Acesse os livros no link a
seguir (NEO4J, 2020b).

https://qrgo.page.link/LCCjP

No tutorial apresentado no link a seguir (TUTORIALS POINT, 2020), é possível relembrar


os conceitos básicos do sistema CouchDB e acompanhar o passo a passo de como as
operações CRUD podem ser utilizadas.

https://qrgo.page.link/WM3xP

141
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

Neste tópico, foram estudadas soluções para o armazenamento de dados


semi estruturados em sistemas de gerenciamentos de bancos de dados NoSQL.
Esses sistemas rompem com o modelo relacional e introduzem novos modelos
de estrutura de gerenciamento e melhores técnicas de distribuição de dados.
Por serem NoSQL, todas as bases são livres de esquema de armazenamento,
possibilitando flexibilidade e fluidez adaptáveis aos dados ali inseridos.

Os principais modelos de sistemas de bancos de dados apresentados


foram os orientados a documentos e grafos, amplamente utilizados para redes
sociais, empresas de vendas de produtos e jogos. Essas são bases de dados que
possibilitam o escalonamento horizontal, permitem a sincronização de dados em
diferentes dispositivos (CouchDB) e a replicação pode ser feita automaticamente
(MongoDB). Por conta das características apresentadas, esse tipo de banco de
dados é apto a trabalhar com grandes volumes de dados, tendo em vista que a não
existência de restrições, como no modelo relacional, propicia um armazenamento
mais flexível e rápido acesso aos dados.

E
IMPORTANT

Operações CRUD na construção de um sistema de armazenamento


(MongoDB).

Ao imaginar um sistema simples de uma empresa de aluguel de carros,


é possível inferir como ele funciona no momento em que uma pessoa solicita
o serviço. Para começar, se uma cliente chamada Maria solicitar um carro do
modelo Agile para aluguel, será inserido no sistema algo similar a:

“Cliente”: {

“id”: 457

“nome”: Maria

“telefone”: 123456789

“carro solicitado”: Agile

Quando Maria vem uma segunda vez à locadora, a partir do ID será


possível consultar qual o documento e conferir os dados presentes neles, sem

142
TÓPICO 1 | FRAMEWORKS DE ARMAZENAMENTO SEMIESTRUTURADOS

alterar o conteúdo do arquivo. Em uma terceira vez, a cliente informa que


mudou o número do telefone, sendo necessário realizar uma atualização. Nessa
atualização, o valor do campo modificado é substituído pelo novo inserido,
podendo ser mantido um histórico ou não dessa atualização. Nesse caso, o novo
registro de Maria ficaria:

“Cliente”: {

“id”: 457

“nome”: Maria

“telefone”: 789456123

“carro solicitado”: Agile

Se Maria decide não utilizar mais o serviço de locação e solicita a exclusão


de seu cadastro, ele será excluído a partir da função de deleção do sistema.

143
RESUMO DO TÓPICO 1

Neste tópico, você aprendeu que:

• NoSQL é um termo designado para todo modelo de dados não relacional:


significa literalmente “não apenas SQL”.

• O objetivo do NoSQL não é substituir o SQL, mas atuar em situações —


armazenamento de dados semi e não estruturados e manipulação de grandes
volumes de dados (big data) — nas quais este não é mais capaz de atuar com
tanta eficácia.

• Os tipos mais de conhecidos de NoSQL são: documentos, chaves-valor, colunas


e grafos.

• Os documentos são coleções de atributos e valores, os quais são geralmente


utilizados nos casos em que não se pode utilizar um esquema.

• As chaves-valor armazenam objetos indexados por chaves e possibilitam a


busca por esses objetos a partir de suas chaves.

• As colunas são utilizadas para otimizar a busca de dados estruturados, já que


é possível acessar poucas colunas sem ler o registro inteiro.

• Os grafos são interessantes quando a interconectividade entre os dados é


importante, de forma a ser consultada de maneira rápida e eficiente.

144
AUTOATIVIDADE

1 Dentro de uma empresa existem dados sensíveis que requerem um maior


cuidado de quem tem acesso e pode manipulá-los. Os sistemas de gerencia-
mento de identidade e acesso armazenam informações sobre as pessoas de
uma empresa (nome, cargo, função e nível de acesso) e também sobre os da-
dos (onde estão contidos, quais flags têm, qual o tipo de dado, entre outros),
juntamente com as regras que regem o acesso a esses recursos.
Você trabalha como analista de dados em uma empresa que desenvolve sof-
twares relacionados à área de gestão de pessoas. A empresa está desenvolven-
do uma nova versão do software, e você foi convidado a ajudar na escolha de
um banco de dados NoSQL para esta solução.
Levando em consideração que o acesso a esse tipo de documento ​​​​​​​deve ser
rápido e garantir que o usuário tenha seguido todas as regras determinadas,
qual seria o melhor tipo de sistema de banco de dados entre documento, cha-
ve-valor, grafos e colunas para essa situação?

2 Os bancos de dados não relacionais abrangem inúmeras soluções de arma-


zenamento que não utilizam apenas SQL, sendo representados principalmen-
te por quatro tipos. Quanto a esses tipos, é correto afirmar que:​​​​​​​

a) ( ) O modelo de documento é um modelo estruturado em que cada cam-


po tem um tipo de valor fixo.
b) ( ) O modelo de chave-valor é aquele em que há uma chave (senha para
liberar cada conteúdo.
c) ( ) O modelo de grafos é utilizado principalmente quando há a necessida-
de de identificar uma conectividade entre os dados.
d) ( ) O modelo de colunas é totalmente não estruturado e só pode ser utili-
zado para dados desse tipo.
e) ( ) O modelo de grafos é aquele em que gráficos podem ser armazenados
e não têm nenhuma conectividade de documentos.

3 CouchDB é um sistema de banco de dados muito utilizado para aplicações


on-line em diferentes dispositivos. Isso ocorre porque:

a) ( ) Embora pago, o CouchDB é acessível e possível de desenvolver em


diferentes plataformas.
b) ( ) Para acessar em diferentes computadores é necessário utilizar um dis-
positivo como pen drive para ter acesso aos dados.
c) ( ) É possível fazer manualmente a sincronização sempre que fizer uma
alteração nos dados, acessando os dispositivos um a um.
d) ( ) A replicação é bidirecional e há um controle de alteração de arquivos
para garantir que não haja conflito de versões.
e) ( ) Na verdade, não é possível fazer a sincronização entre diferentes dis-
positivos.

145
4 MongoDb é o banco de dados NoSQL mais utilizado do mundo. Sobre ele,
é possível afirmar que:

a) ( ) É um banco orientado a documentos.


b) ( ) Suporta apenas dados estruturados.
c) ( ) Não agrupa os dados de nenhuma forma.
d) ( ) É orientado a grafos.
e) ( ) Nenhuma das alternativas.

5 Para que um banco de dados seja mantido, é necessário que seja possível
realizar quatro funções básicas. Quais são elas? ​​​​​​​

a) ( ) Copiar, colar, recortar e apagar.


b) ( ) Criar, consultar, atualizar e apagar.
c) ( ) Apagar, destruir, escrever e copiar.
d) ( ) Clonar, atualizar, resetar e apagar.
e) ( ) Nenhuma das alternativas.

146
UNIDADE 3
TÓPICO 2

SHARDING

1 INTRODUÇÃO
Com o avanço das tecnologias de informação e comunicação, surge um
grande aumento do fluxo de dados que trafegam nas redes de computadores.
Lidar com dados tem obrigado instituições e empresas (públicas ou privadas e em
diferentes setores da sociedade) a redobrarem seus cuidados quanto a tratamento,
armazenamento e manutenção da informação contida em servidores. Por terem
se tornado um dos maiores bens que uma empresa pode ter, os dados precisam
estar em segurança e devem ter sua estrutura planejada para uma expansão.
Um dos maiores desafios quando se trata de big data é a escalabilidade, isto é,
a capacidade de crescimento de maneira escalar. Isso é um dos problemas mais
comuns e importantes que toda empresa enfrenta, ou seja, lidar com negócios em
crescimento, o que traz a necessidade de armazenamento exponencial de dados e
grande demanda de disponibilidade deles.

Existem duas abordagens principais para realizar o dimensionamento


do armazenamento de dados: vertical e horizontal. Independentemente da
estratégia de escalabilidade que se decide seguir, é costume comprar máquinas
cada vez maiores, mais rápidas e mais caras para mover os dados entre eles e
realizar o aumento vertical ou agrupá-los para realizar a escala horizontalmente.
Embora esse processo funcione em grandes empresas com aporte financeiro
significativo, não funciona tão bem para as pequenas e médias instituições, que
precisam escalar muito além do que podem pagar. Por isso, técnicas e sistemas de
código aberto ganham destaque. Nesse contexto, encaixa-se o uso do sharding ou
fragmentação de dados. Sharding é uma arquitetura de escalabilidade horizontal
de dados e será o foco de estudo deste tópico.

2 O QUE É SHARDING?
Sharding é uma arquitetura de big data relativamente nova. Considerada
revolucionária por profissionais da área, tem sido adotada por desenvolvedores
e equipes responsáveis por projetos que lidam com dados em variados tipos
de organizações. Redes sociais como Facebook, Twitter, Friendster e o Flickr já
usam há algum tempo. O conceito define uma abordagem acessível para a escala
horizontal dos dados sem comprometer nada. O sharding é, portanto, um padrão
de arquitetura para sistemas distribuídos, relacionado ao particionamento
147
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

horizontal, em que cada partição tem o mesmo esquema e as mesmas colunas,


mas com linhas, isto é, os registros no banco em si, totalmente diferentes. Sistema
distribuído é um conjunto de diferentes computadores que, interligados através
de uma rede, apresentam-se ao usuário como um sistema único e com coerência
(TANENBAUM; BOS, 2016). De igual modo, os dados de cada nó são exclusivos,
sendo totalmente independentes entre os dados das demais partições.

Sharding é diferente da arquitetura tradicional do banco de dados de vá-


rias maneiras importantes, tendo algumas características particulares que tornam
o conceito bem diferente do armazenamento de dados de bancos relacionais tra-
dicionais. Algumas dessas características são as seguintes.

• Dados desnormalizados: em sistemas de armazenamento de dados tradicio-


nais, os dados são normalizados, dispostos em tabelas sem anomalias e, em
seguida, reunidos novamente quando precisam ser usados. Armazenam-se
juntos os dados que são usados juntos, mas com a possibilidade de separar os
dados por tipo. Com isso, em uma rede social, por exemplo, é possível manter
os dados do perfil de um usuário separados de seus comentários, blogs, e-mail,
fotos etc. Todavia, os dados do usuário são armazenados e recuperados como
um todo. Essa é uma abordagem muito rápida.
• Dados em várias instâncias físicas: historicamente, os servidores de banco de
dados são ampliados aumentando o número de máquinas em um datacen-
ter. Com o sharding, os dados são paralelos e aumentam de maneira escalar.
Usando essa abordagem, podem ser feitos muito mais trabalhos, porque isso
acontece em processamento paralelo.
• Os dados são pequenos: quanto maior o conjunto de dados que um servidor
manipula, mais difícil é obter retorno de maneira inteligente, porque há uma
diversidade muito grande de dados acessados. É preciso grande quantidade de
memória RAM, que pode não ser suficiente para armazenar em cache os dados
quando necessário. Ao isolar os dados em fragmentos menores, é mais prová-
vel que os dados que estão sendo acessados permaneçam em cache, agilizando
o processo de consulta e retorno dos dados.

Pode ser útil pensar no particionamento horizontal em termos de como


ele se relaciona com o particionamento vertical. Em uma tabela particionada
verticalmente, colunas inteiras são separadas e colocadas em tabelas novas e
distintas. Os dados mantidos em uma partição vertical são independentes dos
dados em todas as outras e cada um possui linhas e colunas distintas. O sharding
envolve dividir os dados em dois ou mais blocos menores, chamados shards
lógicos. Os shards lógicos são, então, distribuídos por nós de banco de dados
separados, chamados de shards físicos, que podem conter vários shards lógicos.
Apesar disso, os dados mantidos em todos os shards representam coletivamente
um conjunto de dados lógicos inteiro.

Os fragmentos de banco de dados exemplificam uma arquitetura de


dado compartilhado. Isso significa que os fragmentos são autônomos, ou seja,
eles não compartilham nenhum dos mesmos dados ou recursos de computação.

148
TÓPICO 2 | SHARDING

Em alguns casos, porém, pode fazer sentido replicar determinadas tabelas em


cada shard para servir como tabelas de referência. Por exemplo, caso exista um
banco de dados para um aplicativo que dependa de taxas de conversão fixas para
medições de peso, replicar uma tabela que contenha os dados necessários da taxa
de conversão em cada shard ajudaria a garantir que todos os dados necessários
para consultas sejam mantidos em todos os shards. Essa é uma forma de realizar
um balanço de carga.

Muitas vezes, o sharding é implementado no nível do aplicativo, o que


significa que o aplicativo inclui código que define em qual shard serão permitidas
leituras e gravações. No entanto, alguns sistemas de arquivos distribuídos
possuem recursos de sharding integrados, permitindo que ele seja implementado
diretamente no nível do banco de dados. O uso de aplicações de terceiros também
é bastante utilizado, afinal, existem diferentes ferramentas que auxiliam na
criação dos fragmentos de dados em bancos distribuídos.

Uma abordagem bastante recomendada para implementar shards de


dados a estrutura hibernate shards. Essa estrutura oferece cluster de dados
críticos e suporte para particionamento horizontal, juntamente dos serviços
hibernate padrão. Isso permite que as empresas mantenham os dados em mais
de um banco de dados relacional sem nenhuma complexidade adicional ao criar
os aplicativos.

NOTA

O hibernate shards é uma extensão do hibernate core projetada para encapsular


e minimizar a complexidade de trabalhar com dados fragmentados, isto é, particionados
horizontalmente. Os fragmentos de hibernação podem ser divididos conceitualmente em
duas áreas, as quais você precisará entender para ter sucesso. As duas áreas são: lógica de
sharding generalizada e lógica de sharding específica do aplicativo.

A generalizada permite que os desenvolvedores de aplicativos consultem e transacionem


conjuntos de dados fragmentados usando a API principal do hibernate core. A específica
garante que todo aplicativo que usa o hibernate shards terá suas próprias regras sobre
como os dados serão distribuídos pelos seus shards. Em vez de tentar antecipar todas essas
regras, é fornecido um conjunto de interfaces pelas quais você pode codificar a lógica de
distribuição de dados do seu aplicativo (HIBERNATE SHARDS, 2020).

Porém, além do hibernate, existem outras ferramentas em que shards


podem ser implementados por meio de sistemas de dados, como as ferramentas
Apache Slice e Websphere ObjectGrid. O Slice estende o tempo de execução do
OpenJPA (biblioteca em linguagem Java) para sistemas de armazenamento de
dados distribuídos, possivelmente heterogêneos e particionados de maneira
horizontal. A Figura 1 demonstra a utilização do plug-in Slice junto do OpenJPA.

149
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

FIGURA 1 – ARQUITETURA OPENJPA PARA PERSISTÊNCIA DE OBJETO DISTRIBUÍDO

FONTE: Adaptado de OpenJPA (2020)

Portanto, o Apache Slice funciona como uma camada plug-in interme-


diando o OpenJPA e a camada JDBC como a biblioteca de conexão com bancos
de dados da linguagem Java. Com o uso do plug-in, os dados são “fatiados” no
que se chama de slices, realizando, assim, seu particionamento na mesma ideia
dos shards.

O componente WebSphere ObjectGrid da IBM é um recurso ativado para


armazenamento de dados na memória para objetos Java e projetado para escala-
bilidade, resiliência e alto desempenho. Ele pode ser usado simplesmente como
um banco de dados de memória cache ou para distribuir dados através de uma
rede. O ObjectGrid adota uma arquitetura de segurança para autenticar e au-
torizar clientes. Essa arquitetura aberta e permite que o ObjectGrid se integre a
recursos externos de segurança em servidores (IBM CLOUD, 2020a).

150
TÓPICO 2 | SHARDING

3 UTILIZANDO SHARDING EM CLUSTERS


O sharding é um método para distribuir dados em várias máquinas. Di-
ferentes tipos de sistemas distribuídos usam sharding para oferecer suporte a
implantações com conjuntos de dados muito grandes e operações de alto rendi-
mento. Os sistemas com grandes conjuntos de dados ou aplicativos de alto ren-
dimento podem desafiar a capacidade de um único servidor. Por exemplo, um
volume muito grande de consultas em um mesmo intervalo de tempo pode es-
gotar a capacidade da CPU do servidor. Os tamanhos dos conjuntos de trabalho
maiores que a RAM do sistema enfatizam a capacidade de entrada e saída das
unidades de disco.

Uma das maneiras de controlar o consumo dos recursos de servidores é a


utilização de clusters em servidores de dados. Cluster é um termo da língua in-
glesa que pode ser traduzido como “aglomerar” ou “aglomeração”. Em compu-
tação, é o termo que define um sistema que une vários computadores em comum
a fim de transformar o seu conjunto como se fosse uma única máquina com a
soma de todas as capacidades reunidas (GOMES, 2015). A Figura 2 ilustra como
funciona esse esquema.

FIGURA 2 – ESQUEMA DE CLUSTERS

FONTE: <https://bit.ly/3cC8t5W>. Acesso em: 27 maio 2020.

Conforme a imagem, existe um computador central, também chamado


de node master ou nó mestre, e outros ligados a ele, os chamados nodes ou
nós. Cada nó representa um computador acoplado a esse esquema que, ao se
juntarem em nível de software dentro de uma rede, são vistos por computadores
externos como sendo uma só máquina. Cada membro de um cluster fragmentado

151
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

deve poder se conectar a todos os outros membros no cluster. Isso inclui todos
os shards e servidores de configuração. É preciso verificar se os sistemas de rede
e segurança, incluindo todas as interfaces e firewalls, permitem essas conexões.

O uso da arquitetura em cluster é variado, pois ela é utilizada, hoje, tanto


para atender à ideia de sistemas distribuídos, à fragmentação de dados (sharding)
como também para a formação dos chamados supercomputadores, que são
essenciais no processamento de algoritmos complexos com grandes volumes de
dados e bastante utilizados em projetos de inteligência artificial. Um exemplo
claro do uso de clusters ocorre na mineração de dados e, conforme Sharda, Delen
e Turban (2019, p. 268), “a análise de agrupamento é um método essencial de
mineração de dados para classificar itens, eventos ou conceitos em aglomerados
comuns chamados de clusters ou agrupamentos”.

O load balancing ou balanceamento de carga é uma prática em estrutu-


ras de cluster como forma de garantir que tarefas de processamento trabalhem de
maneira mais uniforme. Na prática, é a possibilidade de configurar que cada re-
quisição que chegue ao servidor seja direcionada para um nó (ou computador)
diferente, com objetivo de não sobrecarregar sempre a mesma máquina para todas
as requisições. O balanceamento tem sua importância justamente na tentativa de
garantir um equilíbrio no atendimento às requisições dos usuários. Sobre seu em-
prego, esse recurso é de uso variado, mas uma forma bastante comum de uso é em
servidores web ou de proxy em uma rede local, pois a tarefa principal é garantir o
acesso de seus usuários à grande rede, o que requer monitoramento constante.

DICAS

Uma ferramenta que utiliza o sharding para distribuição dos dados em cluster é
o ElasticSearch. Ele é comumente considerado um banco de dados não relacional (NoSQL),
mas foi criado para gerenciar e funcionar como um motor de busca, como os que são
utilizados pela Google, Yahoo, entre outros. A Elastic, empresa por trás do ElasticSearch, é
especializada em ferramentas de controle de tráfego em servidores, como o Logstash e o
Beats, que facilitam a coleta, agregação e enriquecimento de dados, armazenando-os no
ElasticSearch. Com o Kibana, toda a stack da Elastic permite explorar, visualizar e compartilhar
informações de maneira interativa sobre seus dados, além de gerenciar e monitorar a pilha.
No ElasticSearch, acontecem todas as operações de indexação, fragmentação, pesquisa e
análise. Acesse a ferramenta no link a seguir (ELASTIC, 2020): https://qrgo.page.link/whqHE.

Geralmente, os clusters são implantados para melhorar o desempenho


e a disponibilidade em relação a um único computador, além de serem muito
mais econômicos do que computadores individuais com velocidade ou dispo-
nibilidade comparáveis. Clusters de computadores surgiram como resultado da
convergência de várias tendências de computação, incluindo a disponibilidade
de microprocessadores de baixo custo, redes de alta velocidade e software para
152
TÓPICO 2 | SHARDING

computação distribuída de alto desempenho. Eles possuem uma ampla varieda-


de de aplicabilidade e implantação, variando de clusters de pequenas empresas
com vários nós a alguns dos supercomputadores mais rápidos do mundo.

3.1 CLUSTER LOCAL E REMOTO


Um cluster pode ser configurado em uma rede local ou também por aces-
so externo, ou seja, remoto. Enquanto um cluster local é, geralmente, conectado
em redes do tipo LAN, clusters remotos são usados em recursos que funcionam
se conectando por meio de clusters na camada de transporte. Os sistemas de com-
putação em cluster podem estar entre os recursos mais valiosos de propriedade
de uma organização. Como resultado, eles são alvos bastante visados por invaso-
res e hackers e é essencial que eles estejam bem protegidos.

Embora haja uma variedade de soluções de segurança para redes corpo-


rativas e máquinas individuais, o número de pesquisas focadas especificamente
na proteção de sistemas de cluster tem crescido, mesmo que ainda não atenda
aos requisitos que se apresentam ao lidar com big data e sua grande importância.

Com um cluster local, o nível de segurança pode ser melhor garantido


devido à possibilidade de controle da aplicação como um todo, uma vez que ela
pode estar com seu acesso limitado a quem estiver dentro da rede local. Porém,
um componente importante na configuração de um cluster é permitir que o sof-
tware de monitoramento de segurança da rede detecte uma classe inteira de ata-
ques vindos de um usuário local autorizado invadindo de maneira externa. De-
tectar esse tipo de ataque é uma das muitas responsabilidades dos profissionais
responsáveis pela criação e implantação de clusters em servidores de empresas e
organizações de toda espécie.

Um módulo de clusters remotos permite estabelecer conexões unidirecio-


nais para um cluster remoto. Essa funcionalidade é usada na replicação e na pes-
quisa de cluster cruzado. As conexões de cluster remoto funcionam configurando
um cluster remoto e se conectando apenas a um número limitado de nós nele.
Cada cluster é referenciado por um nome e uma lista de nós de semente. Quando
um cluster remoto é registrado, seu estado de cluster é recuperado de um dos nós
iniciais e até três nós de gateway são selecionados para serem conectados como
parte das solicitações de cluster remoto.

Nesse contexto, existem os serviços em nuvem. Empresas como Google,


Amazon e Microsoft apresentam soluções em nuvem para que empresas e projetos
possam utilizar os recursos de seus potentes servidores como solução para clusteri-
zação de suas aplicações com relação a dados e arquivos em ambiente distribuído.
A grande vantagem é que o custo diminui com a adesão a esses serviços, visto que
despesas como energia e manutenção física dos servidores são totalmente terceiri-
zadas, fazendo com que a equipe de TI de uma empresa foque apenas em criar as
soluções para armazenamento e transações com os dados ali armazenados.

153
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

ATENCAO

Existem diferentes tipos de clusters. Clusters podem ser utilizados em contextos


diferentes, com estruturas de computadores das mais modestas até grandes servidores. Antes
da criação dos clusters, mainframes — computadores de grande porte capazes de armazenar
grande número de informações — eram adotados como uma grande máquina com redun-
dância modular. Porém, o menor custo inicial dos clusters e o aumento da velocidade das
redes favoreceram a adoção de clusters em empresas de vários portes. Ainda hoje, algumas
empresas se utilizam de mainframes, mas esse número tem caído a cada ano.

A implementação de shards em cluster implica utilizar sistemas distribuí-


dos que tenham a capacidade de empregar a técnica de sharding. Em um sistema
de armazenamento de big data, cada shard contém um subconjunto dos dados
fragmentados. Cada shard pode ser implantado como um conjunto de réplicas. O
sistema distribuído atua como um roteador de consulta, fornecendo uma interfa-
ce entre aplicativos clientes e o cluster sharded. Nessa operação, os servidores de
configuração armazenam metadados e definições de configuração para o cluster.
Há diferenças de um sistema de armazenamento de dados para outro e, portanto,
as configurações e o modo de colocar em prática o sharding também será feito de
maneiras diferentes em cada um.

Existem requisitos a serem levados em consideração antes de realizar uma


operação como essa. A complexidade da infraestrutura de cluster fragmentada
exige planejamento, execução e manutenção cuidadosos. É necessária uma consi-
deração cautelosa na escolha da shard key (chave de fragmento) para garantir o
desempenho e a eficiência do cluster. Não se pode alterar a chave de fragmento
após o fragmento, nem desfazer uma coleção de fragmentos.

3.2 RELAÇÃO ENTRE SHARDING E ÍNDICES


Sistemas de armazenamento de dados possuem diversas formas de agru-
par e armazenar seus dados. Isso também interfere no modo como os dados serão
posteriormente acessados e pesquisados, o que gera uma cadeia de acontecimen-
tos que são impactados, como o tempo de resposta e a integridade dos dados.
Além do sharding, existem outras formas de organizar e trazer os dados em uma
consulta ou transação com bancos de dados.

Tradicionalmente, sistemas de armazenamento de dados do tipo relacio-


nal utilizam índices como forma de organizar os registros de dados nas tabelas
em operações de recuperação de dados. Ramakrishnan e Gehrke (2011) acrescen-
tam que por meio de um índice é possível recuperar de forma eficiente todos os
registros que satisfaçam alguma condição de pesquisa nos campos de chave do
índice. A ideia central é que um índice sirva como um ponteiro direto para um
registro específico, diminuindo o tempo de acesso a um dado. Como exemplo, é

154
TÓPICO 2 | SHARDING

possível criar índices para consultar dados, como um somatório dos salários de
funcionários de uma empresa. Para bancos de dados relacionais, índices podem
ser primários ou secundários. Em índices primários, os registros devem incluir a
chave primária, enquanto os demais registros sem a chave primária irão compor
os índices secundários (RAMAKRISHNAN; GEHRKE, 2011).

3.3 UTILIZANDO ÍNDICES EM BANCOS DE DADOS


Segundo Bianchi (2007), outra forma de utilizar índices é para identificar
dados em colunas, o que pode ajudar nas consultas que contenham a cláusula
WHERE da linguagem SQL, que, ao utilizar operadores como NOT, AND e OR,
acaba por alterar o desempenho das consultas. Ramakrishnan e Gehrke (2011)
também ressaltam que existem diferentes tipos de índices, como:

• booleano;
• de hashing;
• bitmap;
• de várias tabelas;
• em árvore B (B-tree);
• funcional.

A Figura 3 ilustra a ideia do uso de índices em bancos de dados relacionais.

FIGURA 3 – UTILIZANDO ÍNDICES EM BANCOS DE DADOS RELACIONADOS

FONTE: Adaptado de Reis (2019)

Esse é um exemplo de estrutura de um índice não clusterizado do tipo


B-tree ou árvore balanceada. Nele, ao utilizar o algoritmo chamado de árvore
balanceada, o desempenho de consultas aumenta, pois a busca por um nome é
155
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

feita em um conjunto de dados menor, separado por categorias representadas


pela primeira letra de um nome, filtrado pelo nome da pessoa, que é a coluna
com valor como sendo a chave indexada. Como exemplo, ao consultar os dados
de uma pessoa chamada Maria, ao usar essa coluna junto da cláusula WHERE em
SQL, a consulta será feita no nó mestre, que, por sua vez, determina o próximo
nó a ser acessado, no caso, o nó intermediário H-N, onde estaria a letra M, inicial
do nome de Maria.

Como é possível perceber, o uso de índices tem auxiliado muito na


produtividade de equipes de desenvolvimento de sistemas no projeto de bancos
de dados e em sua futura utilização. Afinal, é desde o projeto que se deve tentar
prever o aumento do consumo dos dados e dos serviços oferecidos por servidores
de dados. Pela falta de planejamento, muitos projetos do passado e alguns ainda
no presente sofrem quando precisam aumentar a capacidade de usuários que os
utilizam ao mesmo tempo. Em meio ao planejamento, a escolha entre um banco
de dados que possa ser utilizado de maneira distribuída uma possibilidade a ser
considerada. A escolha entre o uso de índices ou a divisão do banco de dados em
clusters desde o início, que auxilia no emprego da técnica de sharding, pode ser
um fator decisivo no futuro dos dados de uma organização.

O Quadro 2 apresenta uma relação entre algumas das principais caracte-


rísticas do uso de índices e de sharding em sistemas gerenciadores de bancos de
dados.

QUADRO 2 – CARACTERÍSTICAS DE ÍNDICES SHARDING

FONTE: Adaptado de Oracle (2020)

156
TÓPICO 2 | SHARDING

Portanto, índices e sharding possuem características bem específicas,


mas ambos são úteis na melhoria do desempenho das consultas em um sistema
de arquivos. Porém, ao mesmo tempo, a capacidade de escalabilidade do uso
de clusters ou a simplicidade do armazenamento único em banco de dados não
distribuído dos sistemas tradicionais são fatores que precisam ser colocados
na balança pela equipe responsável em criar um projeto de implementação e
manutenção de servidores de dados.

Utilizar índices em bancos de dados não têm apenas vantagens. Algumas


desvantagens ou contrapartidas são notadas em certas situações. Por ser
desenvolvida uma tabela virtual com todos os índices criados, aumenta o espaço
de armazenamento em disco no servidor de banco de dados. Outra situação é
que toda vez que um índice precisar ser alterado, a tabela com os índices também
precisa sofrer alterações. Em alguns casos, o uso de índices pode até prejudicar o
desempenho das consultas de bancos de dados, pois o uso dos índices pode fazer
com que se demore mais tempo procurando a partição onde o dado está do que
em uma consulta direta.

No que se refere ao desempenho, o uso de cada um desses recursos pode


variar. A verdade é que o uso de índices ou de sharding depende da situação em
que se encontra o projeto de uso dos dados. Quando se trata de big data, é inegável
a necessidade de preparar o ambiente de servidor para lidar com uma imensidão
de dados vindos a todo instante. Para o cenário atual de grandes conjuntos de
dados, trabalhar com clusters é o mais indicado. Portanto, sharding pode ser um
fator diferencial no acesso à informação vinda de big data.

157
RESUMO DO TÓPICO 2
Neste tópico, você aprendeu que:

• Bancos de dados para big data têm como característica a adaptação dos
processos de armazenamento e leitura de dados, uma vez que lidam com
altíssima quantidade deles.

• Um exemplo de implantação do método sharding em banco de dados não


relacional (NoSQL) é chamado Big Table.

• O Big Table é um serviço de bvanco de dados para big data do google. É o


mesmo banco de dados NoSQL usado em vários serviços principais do Google,
como Gmail, Maps, Pesquisa e Aanalytics.

• No cloud do Big Table, o sharding acontece quando uma tabela é fragmentada


em blocos (conjuntos de linhas contíguas). Essa fragmentação ajuda no
balanceamento da carga de trabalho das consultas.

• Com uma aplicação clusterizada, o profissional responsável e sua equipe podem


projetar e determinar quantos nós (nodes) deverão existir, compartilhando os
dados (criando participações) e até os replicando. Backups quase em tempo
real podem ser criados automaticamente.

• Com a escalabilidade e alta disponibilidade de dados, sendo seu principal


benefício, o Big Table é indicado para uso no processamento de dados não
estruturados em grande volume, para criação de visualizações de relatórios e
séries temporais de dados de marketing ou financeiro, para criação de gráficos,
entre outros.

• O Big Table permite conexão direta com serviços e banco de dados, como
Cassandra, HBase e MongoDB.

158
AUTOATIVIDADE

1 Empresas de todos os tamanhos estão adotando a rápida modernização de


aplicativos voltados para o usuário como parte de uma estratégia de transfor-
mação digital. A infraestrutura de banco de dados relacional, de que esses apli-
cativos dependem, repentinamente precisa suportar tamanhos de dados e vo-
lumes de transações muito maiores do que o planejado inicialmente. Um SGBD
monolítico pode ficar rapidamente sobrecarregado em um cenário de big data.
Suponha que a empresa em que você trabalha tem máquinas que chegam a arma-
zenar até 2 milhões de registros de dados de clientes. Com esse aumento repenti-
no, o SGBD está atingindo um ponto de interrupção e, provavelmente, ultrapas-
sará 2,5 milhões de usuários em breve. Assim, a empresa precisa de uma solução
que trate o problema do surgimento de um grande conjunto de dados.
Como profissional de dados, indique ao menos uma solução para que as con-
sultas de dados e a sobrecarga sobre os servidores seja resolvida, mantendo
os dados acessíveis e seguros.

2 Um dos maiores desafios em sistemas de armazenamento de dados é a es-


calabilidade: a capacidade de crescimento de maneira escalar. Esse é um dos
problemas mais comuns e importantes que toda empresa enfrenta. Lida-se
com negócios em crescimento, causando armazenamento exponencial de da-
dos, com necessidade e grande demanda de disponibilidade deles. Em termos
de dados e sistemas, analise as afirmações a seguir sobre escalabilidade:

I- Característica de um sistema que descreve sua capacidade de lidar e


executar bem sob aumento ou expansão.
II- Capacidade de lidar com crescimento sem ser prejudicada por sua
estrutura ou recursos disponíveis.
III- Possibilidade de atender a diversas demandas ao mesmo tempo.
IV- Está diretamente ligada a bancos de dados relacionais.

Está correto o que se afirma em:


a) ( ) I e II, apenas.
b) ( ) I e III, apenas.
c) ( ) II, III e IV.
d) ( ) I, II e III.
e) ( ) Nenhuma das alternativas.

3 Sharding é uma arquitetura de bancos de dados relativamente nova. Con-


siderada revolucionária por profissionais da área, tem sido adotada por de-
senvolvedores e equipes responsáveis por projetos que lidam com dados de
variados tipos. Sobre o conceito de sharding, pode-se afirmar:

a) ( ) Define uma abordagem acessível para escala horizontal dos dados.


b) ( ) A arquitetura do sharding é semelhante à arquitetura tradicional do
banco de dados em seus principais aspectos.
159
c) ( ) Com o sharding, os servidores de banco de dados são ampliados, au-
mentando o número de máquinas em um datacenter.
d) ( ) O sharding envolve dividir os dados em dois ou mais blocos menores,
chamados clusters lógicos.
e) ( ) Nenhuma das alternativas.

4 Diferentes tipos de bancos de dados usam sharding como forma de oferecer


suporte a implantações com conjuntos de dados muito grandes e operações
de alto rendimento. Os sistemas de banco de dados com grandes conjuntos de
dados ou aplicativos de alto rendimento podem desafiar a capacidade de um
único servidor. Sharding pode ser uma alternativa para um conhecido méto-
do de aceleração de consultas a bancos de dados. Esse método é conhecido
como:

a) ( ) Chave primária.
b) ( ) Chave estrangeira.
c) ( ) Índices.
d) ( ) NoSQL.
e) ( ) Shard keys.

5 Cluster é um termo na língua inglesa que pode ser traduzido como “aglo-
merar” ou “aglomeração”. Em computação, é o termo que pode definir um
sistema que junta vários computadores em comum, a fim de transformar seu
conjunto em uma única máquina com a soma de todas as capacidades reuni-
das. Sobre clusters, avalie as afirmações a seguir:

I- Requer o uso de supercomputadores em sua composição.


II- Ao unir vários computadores, é simulado um supercomputador.
III- Cada computador em um cluster é chamado de node ou nó.
IV- O computador principal é chamado de node master.

Sendo assim, é correto o que se afirma em:


a) ( ) I, apenas
b) ( ) I e II, apenas
c) ( ) II, III e IV.
d) ( ) I, III e IV.
e) ( ) I, II, III e IV.

160
UNIDADE 3
TÓPICO 3

FRAMEWORKS QUE UTILIZAM SHARDING COMO


FORMA DE DISTRIBUIÇÃO

1 INTRODUÇÃO
O sharding é uma forma de particionamento que possibilita o crescimento
do banco de dados de forma horizontal e praticamente infinita. Assim, caso a
demanda de armazenamento e processamento aumente de forma rápida, é
possível manter as funcionalidades e a disponibilidade de dados presentes nesse
banco sem que seja necessário aumentar o número de máquinas. Atualmente, o
sharding já é incorporado em alguns bancos de dados distribuídos.

Neste tópico, você vai conhecer a estrutura básica do particionamento


horizontal conhecido como sharding e vai aprender de que modo ele é
implementado nos populares bancos de dados Apache Cassandra e MongoDB.

2 ARQUITETURA DO SHARDING
Naturalmente, a tendência de um banco de dados é sempre crescer.
Em alguns casos, esse crescimento pode chegar ao ponto em que a estrutura
inicial das máquinas já não é capaz de atender à demanda, sendo necessário
realizar melhorias. Uma das opções é realizar um redimensionamento vertical,
melhorando as máquinas em si de forma que possuam mais memória RAM e
espaço em disco, por exemplo. O problema é que essa alternativa, além de
trabalhosa, pode se tornar muito cara se for realizada localmente e, mesmo em
casos de armazenamento em nuvem, essa solução não é infinita. Por conta dessas
questões, é interessante recorrer a opções de bancos de dados que possibilitem
um dimensionamento horizontal, no qual, ao invés de melhorar as máquinas
existentes, mais máquinas são adicionadas e o conjunto de dados é particionado
e redistribuído. Esse particionamento também é conhecido como sharding.

O sharding possibilita o aumento da capacidade de armazenamento


e processamento de um conjunto de dados, que já não são necessariamente
armazenados em um único local ou servidor. Nesse método, os dados são
divididos em pequenas partições (shards) e distribuídos em vários servidores, que
inclusive podem ser sempre adicionados ao conjunto (cluster). O agrupamento
dessas partições permite o armazenamento de grandes conjuntos de dados
161
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

e o crescimento da capacidade de armazenamento e tráfego de acordo com a


demanda exigida, pois, embora uma única máquina possa não apresentar uma
alta capacidade geral ou velocidade, o cluster delas promove isso, de forma a
possibilitar alta capacidade e alta velocidade ao sistema. O gargalo da utilização
do sharding é a necessidade de aumentar a complexidade operacional do seu
sistema: já não é mais possível acessar os dados em um único local e é necessário
gerenciar várias máquinas ao mesmo tempo. Funções como pesquisa de texto e
análises de dados, por exemplo, são beneficiadas por esse método.

Os shards de um mesmo banco de dados podem estar localizados na mesma


máquina (coresident) ou em máquinas diferentes (remotas). O particionamento
coresident tem como vantagem a redução do tamanho dos índices individuais
e da quantidade de ações de E/S (entrada/saída) que se faz necessária durante a
atualização de registros. Já o particionamento remoto possibilita o aumento da
largura de banda do acesso aos dados, por meio do aumento de memória RAM
para armazenamento, e disponibiliza mais interfaces de rede e canais de E/S do
disco. A Figura 1 ilustra as diferenças entre um banco de dados particionado e
um não particionado.

FIGURA 5 – EXEMPLO DE DISTRIBUIÇÃO DE DADOS EM UM BANCO NÃO PARTICIONADO E


EM UM BANCO PARTICIONADO (SHARDING)

FONTE: O Autor

Cada unidade de shard possui a mesma estrutura de banco de dados que


o banco original e todos os shards juntos constituem o banco de dados lógico
chamado de banco de dados particionados (SDB, Sharded DataBase). O SDB é a
união de vários bancos de dados gerenciados coletivamente ou individualmente,
de forma que, embora pareça único, o número de shards e a distribuição de da-
dos são completamente transparentes para os aplicativos de banco de dados. Um
162
TÓPICO 3 | FRAMEWORKS QUE UTILIZAM SHARDING COMO FORMA DE DISTRIBUIÇÃO

shard é sempre gerenciado por um único servidor e, geralmente, há um esquema


de replicação, em que o shard pode ser replicado duas vezes, por exemplo. Como
vão acumulando dados ao longo do tempo, os shards podem ser configurados
para passar por uma divisão automática quando chegam a um determinado li-
mite de volume e redirecionar essas novas partições. O sharding automático re-
duz a carga da programação em comparação ao sharding manual, facilitando o
gerenciamento do banco de dados quanto ao particionamento e à recuperação de
dados do código do aplicativo.

Nesse processo de particionamento, a diferença dos conceitos de sharding


e replicação pode não ficar tão evidente, mas na verdade eles são bem distintos.
Enquanto o sharding é o particionamento de dados em fragmentos e os shards
armazenam subconjuntos desses dados, a replicação é a cópia exata de dados
inteiros. A replicação de dados é extremamente importante, tendo em vista que
sem ela há um ponto de falha no sistema, no qual, se um dos nós do cluster ficar
inativo, parte dos dados não estará disponível. A criação de cópias dos dados (ré-
plicas) supera esse desafio, tornando o sistema tolerante a falhas e mais confiável.
Dessa forma, apesar de ter conceitos diferentes, apenas por meio da integração do
particionamento e da replicação é possível obter um sistema de banco de dados
eficaz. O Quadro 3 apresenta as diferenças entre replicação e particionamento.

QUADRO 3 – DIFERENÇAS ENTRE REPLICAÇÃO E PARTICIONAMENTO

FONTE: Adaptado de Bhamra (2017)

O conceito e a aplicação do sharding são antigos e, ao longo do tempo,


diferentes tipos de estratégias e implementações desse método foram utilizados
na construção de sistemas de grande escala. De forma geral, sharding é um
tipo de arquitetura "nada compartilhada" (SN, Shared Nothing), em que não há
centralização de dados e cada um dos fragmentos é independente. Os fragmentos

163
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

são identificados a partir de chaves de fragmentação, que podem ser obtidas


por estratégias distintas. Em relação às estratégias de chave de fragmentação
no sharding, de acordo com Carpenter e Hewitt (2016), as três mais comuns são
baseadas em: hash, intervalo e diretório, que serão detalhadas a seguir.

3 SHARDING BASEADO EM HASH


O sharding baseado em hash (ou baseado em chave) utiliza valores cons-
tantes dos dados de cada fragmento para gerar um hash específico ou token,
como é chamado em alguns bancos de dados. Esse novo hash é utilizado como
uma chave de identificação que permite identificar quais dados serão armazena-
dos em determinados shards. Por exemplo, na fragmentação de uma tabela cuja
primeira coluna possui o nome completo de pessoas e esses nomes não se repe-
tem, essa coluna poderia ser utilizada para criar uma chave de fragmentação e ser
transformada em hash, para identificar cada porção fragmentada. Essa é uma ar-
quitetura excelente para operações de dados direcionados, mas, além de o cálculo
de hash poder adicionar uma carga adicional ao sistema, pode ser complicado
adicionar ou remover servidores dinamicamente ao longo do tempo.

O valor do campo/coluna escolhido para ser a chave de fragmentação aca-


ba por determinar o limite inferior inclusivo e o exclusivo de cada shard. Por
exemplo, se um banco que possui identificadores que iniciam com números de 1
a 1000 (por exemplo: = 57ABD, 1GRS, 999ITR) fosse dividido em quatro shards,
seria determinado que os shards armazenariam os ids em quatro grupos orde-
nados, podendo ser, respectivamente: S1: 1-250, S2: 251-500, S3:501-750 e S4: 751-
1000. Sendo assim, além de determinar os limites dos shards, as chaves acabam
também determinando o local em que cada fragmento ficará alocado. A cada
adição, é verificado o lugar no qual a chave daquele fragmento melhor se encai-
xa para, então, alocá-lo. No caso de um shard ficar muito desproporcional aos
outros, ocorre um redimensionamento dos dados. Essa chave também pode ser
utilizada para as consultas, o que possibilita uma forma rápida de chegar a um
fragmento específico.

NOTA

Hash é uma sequência de bits que permite a visualização de dados por


meio de letras e números em uma variável de comprimento fixo. Em outras palavras,
é a transformação de uma grande quantidade de dados em uma pequena quantidade
de informações. Este tópico inteiro, por exemplo, pode ser representado pelo hash:
ffb2ef732291fc82135c9ba765163ded.

164
TÓPICO 3 | FRAMEWORKS QUE UTILIZAM SHARDING COMO FORMA DE DISTRIBUIÇÃO

4 SHARDING BASEADO EM INTERVALOS


O sharding baseado em intervalos particiona os dados com base em
“intervalos de chave”, que correspondem aos intervalos de valores dos dados,
de forma que o shard preserva o mesmo esquema do banco original e é possível
identificar facilmente o intervalo dos dados correspondente a cada shard. Por
exemplo: em um banco de dados de uma loja de produtos em um shopping,
dentre as informações, há o preço de cada item. Em um sharding baseado em
intervalos, esse banco poderia ser dividido de acordo com faixas de preço, de
forma que cada shard guardaria todos os produtos correspondentes àquela faixa.

A estratégia de sharding baseado em intervalos torna a implementação


relativamente fácil, mas é preciso estar atento ao desequilíbrio de cargas, à
acessibilidade e velocidade de cada shard: a partir da definição de intervalos,
possível que o número de objetos (ou itens, no exemplo) seja diferente em cada
parte fragmentada, o que pode interferir no rebalanceamento de cargas e no acesso
aos dados. Por outro lado, essa é uma boa estratégia no caso do planejamento
baseado em intervalo, como no exemplo dos preços, pois a consulta, basicamente,
será realizada em um único shard, que é o que possui o preço do produto embutido
em seu intervalo, em vez de ter que consultar todos os shards. Geralmente, essa é
a estratégia de sharding padrão dos aplicativos.

5 SHARDING BASEADO EM DIRETÓRIO


O sharding baseado em diretório necessita de um serviço de pesquisa
estática, que permita rastrear e identificar qual shard mantém quais dados, como
um mapa. Nesse tipo de particionamento, o aplicativo cliente, primeiro, realiza uma
consulta no serviço de pesquisa a fim de identificar o shard correto e, em seguida,
esse shard é retornado. A principal vantagem desse tipo de particionamento é a
flexibilidade, pois, ao invés de estar limitado ao uso de chaves ou intervalos fixos,
é possível utilizar qualquer sistema ou algoritmo que se deseja atribuir dados
a shards. Dessa forma, o mapeamento entre um shard virtual e uma partição
física pode mudar sem a necessidade de modificar o código do aplicativo e é
relativamente fácil adicionar shards dinâmicos. O principal problema do sharding
baseado em diretórios é que, se o sistema de busca for corrompido, a capacidade
de gravação e acesso de dados é afetada.

Além dessas três estratégias, a depender do banco de dados escolhido,


também é possível fragmentar os dados de outras maneiras. Eles podem ser
fragmentados de acordo com a carga de trabalho, localização, prioridade e
privacidade de acesso dos usuários ao sistema, por exemplo. Embora pareça ter
apenas vantagens, o particionamento horizontal deve ser complementar a outras
formas de particionamento, como o vertical e o funcional. Antes de escolher esse
tipo de particionamento, independentemente da estratégia, de forma geral, é
necessário estar atento a alguns pontos, como a escolha da chave de fragmentação,
o equilíbrio e o redimensionamento, e a eficiência de consultas de dados.
165
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

Os shards devem ter o volume de dados o mais semelhante possível entre


si. Como a soma ou a remoção de dados podem ser comuns no banco, é necessário
que haja um rebalanceamento periódico a fim de garantir uma distribuição
uniforme e reduzir a chance de geração de problemas. Como esse processo pode
ser oneroso, o ideal é planejar o crescimento do banco, de forma que em cada
shard haja o espaço necessário para as alterações esperadas. É necessário também
ter uma equipe capaz de desenvolver estratégias para reequilibrar rapidamente
os shards, sempre que necessário.

Os dados que serão utilizados como chave de fragmentação devem ser


escolhidos cuidadosamente, pois precisam ser informações estáveis e pouco
voláteis. Isso porque, se a chave de fragmentação for alterada, talvez seja
necessário mover o fragmento correspondente, o que aumenta as operações de
atualização e a movimentação de dados. Por isso, a informação escolhida como
chave de fragmentação deve ser, preferencialmente, invariável e exclusiva.

A eficácia dos sistemas de consulta varia de acordo com a estratégia de


chave de fragmentação que será utilizada. Aquelas nas quais é preciso acessar
apenas um shard são mais eficientes do que as que recuperam dados de vários
shards. É por isso que se deve conhecer os dados e possíveis buscas, a fim de
evitar a implementação de um sistema que acabe resultando em aplicativos
que precisam executar grandes números de consultas para chegar ao resultado
esperado. Além disso, é possível incluir a chave de fragmentação de um objeto
como parte do esquema de um outro objeto, caso eles sejam referenciados entre si.
Por exemplo, se houver diferentes resultados de exames de sangue de um paciente
ao longo dos anos em um banco dividido por anos, é possível fazer referências
interligando todos os resultados desse mesmo paciente. Assim, possível melhorar
o desempenho das consultas em bancos que possuem dados referenciados.

O ato de utilizar o processo de escalonamento horizontal, possibilitando


distribuir uma grande quantidade de dados em diferentes shards, permite obter
ganhos de desempenho horizontal, com alta disponibilidade de dados, tolerância
a falhas, segurança, paralelização dos processos de backup, restauração e
sincronização inicial. Alguns bancos de dados famosos utilizam esse tipo de
dimensionamento, como Cassandra (APACHE SOFTWARE FOUNDATION,
2016b), MongoDB (2020a) e Hbase (APACHE SOFTWARE FOUNDATION, 2020c),
além do sistema de arquivos HDFS do Apache Hadoop (APACHE SOFTWARE
FOUNDATION, 2020a).

6 FRAGMENTAÇÃO NO APACHE CASSANDRA


Apache Cassandra é um sistema de banco de dados distribuído projetado
para lidar com grandes cargas de trabalho (big data). Ele foi projetado com base
no DynamoDB (AWS, c2020d), da Amazon Web Services e do BigTable (GOOGLE
CLOUD, 2020c), de forma que a construção final promove alta escalabilidade
e tolerância a falhas. Cassandra possui uma arquitetura SN, já que não tem

166
TÓPICO 3 | FRAMEWORKS QUE UTILIZAM SHARDING COMO FORMA DE DISTRIBUIÇÃO

controlador central nem uma relação de mestre/escravo entre os nós, de forma


que todos são iguais (CARPENTER; HEWITT, 2016).

No Cassandra, cada linha de uma tabela é referenciada por uma chave


primária, também conhecida como chave de linha. Há um número de colunas em
uma linha que pode variar em linhas diferentes. Assim, enquanto a linha 1 possui
cinco colunas, a linha 2 pode possuir três. A linguagem de consulta do Cassandra
(CQL, Cassandra Query Language) é baseada na linguagem SQL (Structured
Query Language), seguindo o formato de tabelas, linhas e colunas. Para cada
dado é criada uma chave primária, que é constituída de “chave de partição”
e, opcionalmente, de colunas do cluster. A chave primária difere da chave de
partição gerada pelos particionadores, de forma que essa última representa uma
partição de dados exclusiva.

De forma geral, cada tabela do Cassandra possui uma chave de partição,


que pode ser autônoma ou composta e determina a localidade dos dados por meio
da indexação. Essa chave deve criar partições com tamanhos possivelmente ideais,
a fim de minimizar a movimentação de dados para redimensioná-los. O tamanho
dessa partição deve ser igual ou inferior a 10 MB, podendo ser até de 100 MB.

Nesse sistema, cada servidor é um shard com seus dados replicados por
meio de outros servidores e, geralmente, a estrutura do sharding utilizada chave/
hash, que, nesse caso, é chamado de token. A partir dos tokens, os objetos são
atribuídos a cada shard em partes iguais e distribuídos uniformemente no cluster
principal. O Cassandra também replica os shards para outros nós no cluster, de
acordo com as configurações de replicação predefinidas.

O balanceamento de cargas é simplificado a partir dos intervalos de hash


que definem cada shard, deixando-os, em média, com um número igual de linhas.

Nesse sistema, existem três mecanismos para realizar o sharding, sendo


que todos resultam na estrutura de token: Murmur3Partitioner (padrão),
RandomPartitioner e ByteOrderedPartitioner, cuja diferença está relacionada à
forma de gerar o código chave/hash de cada dado. Murmur-3Partitioner possibilita
a distribuição uniforme dos dados pelo cluster com base nos valores de hash
MurmurHash e pode melhorar o desempenho de três até cinco vezes em relação
aos outros. Já RandomPartitioner realiza a mesma função com base nos valores de
hash MD5, mas, como ele um hash criptográfico, a geração das chaves demora mais
tempo. Byte-OrderedPartitioner, por sua vez, mantém a distribuição ordenada
por bytes-chave de forma léxica, mas não é muito utilizado. Esses particionadores
não são compatíveis entre si, de forma que os dados particionados por meio de
um particionador dificilmente serão convertidos em outro tipo de forma correta.

167
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

7 HASH CONSISTENTE
No Cassandra, o processo de hash é um pouco diferente que o usual. Nes-
se sistema, há hashing consistente, que se distingue do hash comum porque, ao
invés de alocar as chaves em “baldes” (buckets), o Cassandra armazena as chaves
em uma estrutura anel contínuo. Isso permite que, ao invés de ter que mapear
todos os hashes a cada acréscimo de objeto, o hash simplesmente seja movido
para a próxima posição. O hash consistente é um processo de hash mais sofistica-
do, em que um grande número de intervalos de tokens é distribuído igualmente
entre os servidores. Cada linha armazena um pedaço de registros, com base em
um hash de valores-chave que se encaixam no intervalo de um determinado ser-
vidor. Quando servidores são adicionados, fragmentos de registros podem ser
migrados lentamente, reduzindo a quantidade de movimentação de dados no
sistema. O hash consistente também minimiza os movimentos das teclas durante
os procedimentos de adição ou decréscimo de nós no cluster.

Na inicialização do cluster no Cassandra, cada nó recebe um intervalo de


token que determina sua posição e a quantidade dos dados armazenados nele.
Cada nó recebe um intervalo proporcional dos intervalos de token para garantir
que eles sejam distribuídos uniformemente pelo anel (NAZEER et al., 2017). De
acordo com a documentação do Cassandra (APACHE SOFTWARE FOUNDA-
TION, 2016a), é possível haver até 255 tokens em um nó. Caso haja adição de
um novo fragmento, ele será adicionado ao nó cujo número do seu token está
contido no intervalo que determina o limite entre os nós. Por exemplo, no caso
do acréscimo de um fragmento cujo token é 127, na estrutura da Figura 6, ele será
armazenado no nó 4.

FIGURA 6 – HASH CONSISTENTE EM ESTRUTURA DE ANEL

FONTE: O Autor

168
TÓPICO 3 | FRAMEWORKS QUE UTILIZAM SHARDING COMO FORMA DE DISTRIBUIÇÃO

Quando uma solicitação de leitura ou gravação é recebida por qualquer


nó no cluster, os seguintes passos são executados:

1. identificação dos nós que possuem os dados cujas chaves correspondem à busca;
2. encaminhamento das solicitações para os nós, seguido da espera pela resposta;
3. caso não haja retorno em um determinado valor de tempo limite pré-configu-
rado, retorno de “falhar na solicitação” para o aplicativo cliente;
4. caso haja retorno, determinação da resposta mais recente de acordo com os
registros de data e hora;
5. agendamento do reparo dos dados nas réplicas, caso haja modificações.

A integração da replicação e do particionamento promovem a alta dis-


ponibilidade de dados. A replicação do Cassandra acontece dentro da estrutura
de anel. Nela, cada fragmento de dado é replicado em N hosts, em que N é o
fator de replicação configurado "por instância" e cada chave é atribuída a um nó
coordenador, que é responsável pela replicação dos fragmentos de dados que se
enquadram dentro do seu alcance.

O Cassandra elege um líder entre os nós do anel, utilizando uma ferra-


menta do sistema chamada Zookeeper (APACHE SOFTWARE FOUNDATION,
2020d). Assim, cada nó que ingressa no cluster entra em contato com o nó líder
que, de certa forma, decide para quais outros nós ele vai ser replicado. Os seus
metadados e os dos outros nós são armazenados em cache localmente (um para
cada nó), de forma que são tolerantes a falhas (ainda utilizando o Zookeeper)
(LAKSHMAN; MALIK, 2010).

Os protocolos utilizados para a realização da replicação e do particiona-


mento são dependentes da identificação da atividade de cada shard no cluster.
No Cassandra, as informações sobre um shard que sinalizam se ele está ativo
(vivo) ou inativo (morto) são compartilhadas por um mecanismo de detecção de
falhas baseado em “fofocas” (gossip protocol, em inglês, que literalmente pode ser
traduzido para “protocolo de fofocas”).

A partir desse protocolo, os nós recebem informações de estado sobre ou-


tros nós interligados (com o máximo de três), facilitando a detecção de falhas no
sistema. Essa detecção também é usada para evitar tentativas de estabelecer uma
comunicação com nós inacessíveis durante várias operações. O protocolo basea-
do em fofocas apresenta uma excelente precisão e ótima velocidade, além de se
ajustar bem às condições de sobrecarga da rede e do servidor.

Além de indicar o estado de atividade de cada nó, o protocolo de fofocas


também fornece informações a respeito da posição do nó, dos metadados e da esque-
matização. Após o posicionamento da partição em um dos shards, as informações
associadas ao token e sua posição dentro do anel são fofocadas para todo o cluster,
possibilitando que todos os nós possam ter as mesmas informações e desempenhar
as mesmas funções, inclusive executar o algoritmo de inicialização (bootstrap). A fofo-
ca acontece a cada segundo, em que cada nó/shard do cluster seleciona outro nó de
forma aleatória para trocar informações sobre o estado de atividade.
169
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

A arquitetura simplificada (uma única máquina) do Cassandra para o


particionamento por sharding necessita de, basicamente, quatro itens: módulo de
particionamento, associação de cluster, módulo de detecção de falhas e módulo
do mecanismo de armazenamento. Cada um desses módulos possui uma progra-
mação própria que se torna uma fase ou um estágio do processo em geral.

O procedimento de sharding, no sistema de armazenamento de bancos de


dados do Cassandra, contribui para que o sistema apresente alta escalabilidade,
alto desempenho e ampla aplicabilidade.

Além disso, Cassandra pode suportar uma taxa de transferência de atu-


alização de dados muito alta, enquanto fornece baixa latência, o que é uma van-
tagem que deve ser levada em conta durante a tomada de decisão sobre qual
sistema utilizar.

8 FRAGMENTAÇÃO NO MONGODB
O MongoDB, segundo os próprios desenvolvedores, é “um banco de dados
distribuído, baseado em documentos e de propósito geral, desenvolvido para
desenvolvedores de aplicativos modernos e para a era da nuvem” (MONGODB,
2020a, s.p., tradução nossa).

Esse banco suporta o particionamento automático de dados, o que


simplifica a arquitetura do aplicativo e o seu manejo, utilizando a estrutura de
chave/hash. Operacionalmente, esse banco de dados automatiza o balanceamento
de dados entre os shards e facilita a adição e a remoção de máquinas que vão
alterar a capacidade de armazenamento.

São necessários três componentes principais para constituir o MongoDB


por completo: shards, roteadores de consulta e servidores de configuração. Os
shards são conjuntos de réplicas de servidores que armazenam os subconjuntos
de dados; os roteadores de consulta são a interface entre o aplicativo cliente e os
shards propriamente ditos.

Para consultar o shard correto, a consulta utiliza informações fornecidas


pelos servidores de configuração, que, por sua vez, armazenam apenas metadados
dos shards que possuem a localização de cada dado e outras configurações
gerais (BRADSHAW; BRAZIL; CHODOROW, 2019). A Figura 7 ilustra o que é
necessário para um banco de dados particionado.

170
TÓPICO 3 | FRAMEWORKS QUE UTILIZAM SHARDING COMO FORMA DE DISTRIBUIÇÃO

FIGURA 7 – DIAGRAMA DO MÍNIMO NECESSÁRIO PARA UM BANCO DE DADOS


PARTICIONADO (SHARDED)

FONTE: O Autor

Para cada conjunto de dados em um cluster fragmentado, há um shard


primário, que contém toda a informação não fragmentada desses dados. Após
a fragmentação, são criados shards secundários que possuem um conjunto de
réplicas de si. Cada um dos clusters que contém o shard primário e o conjunto de
réplicas deve possuir o próprio servidor de configuração, já que as operações re-
alizadas nesses servidores podem ter um impacto significativo no desempenho e
na disponibilidade do shard. Se, por acaso, o cluster de um determinado servidor
de configuração perder o primário, os metadados do cluster se tornarão somente
leitura. Dessa forma, será possível ler e gravar dados dos shards, mas as opera-
ções de migração ou divisão de fragmentos não ocorrerão até que um novo shard
seja eleito para essa posição.

Em clusters que passaram pelo processo de sharding, é preciso configurar


os roteadores de consulta, que são chamados de mongos. Os mongos utilizam as
chaves primárias para executar a consulta solicitada pelo usuário. Em um banco
de dados de uma universidade, por exemplo, as chaves podem ser o CPF dos
alunos e as consultas podem ser realizadas a partir desse identificador em shards
que foram divididos a cada 1000 registros na ordem crescente. Para saber em qual
shard está o arquivo que corresponde à consulta, os mongos utilizam os metada-
dos de cada partição, a partir dos quais é possível, inicialmente, reduzir a busca,
se o número buscado iniciar com 3, por exemplo. Esses metadados, que estão nos
servidores de configuração, são mutáveis e talvez a razão mais comum dessas
modificações seja quando é necessário fazer uma redistribuição de dados entre
os shards no caso de um acréscimo ou decréscimo de informações no banco. Por
isso, a cada consulta, os mongos acessam os metadados para identificar a localiza-
ção do arquivo, mesmo que essa consulta já tenha sido realizada anteriormente.

Uma outra importante função dos mongos é a mesclagem de dados antes


de retornar à consulta para o aplicativo cliente. Se no banco de dados exemplificado
anteriormente, que foi dividido pelo número de CPF, for solicitada uma busca pelo
171
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

valor de mensalidade X, essa consulta será realizada em todos os shards do cluster.


Cada um dos shards enviará seus resultados aos mongos, nos quais serão reunidos
e poderão ser classificados por outros critérios, se assim a consulta exigir. Após a
mesclagem de todos os resultados de todos os shards ser finalizada, os mongos
retornarão os resultados ao aplicativo cliente, como se fosse um único banco.

O MongoDB suporta as estratégias de sharding de chave/hash e de inter-


valo, que devem ser cuidadosamente escolhidas antes da fragmentação, já que a
seleção de qual campo será utilizado para gerar chave de fragmentação imutável.
A escolha dessa chave pode afetar o desempenho, a eficiência e a escalabilidade de
um cluster fragmentado, mesmo que ele possua o melhor hardware e a melhor in-
fraestrutura possíveis. A escolha do que será utilizado como chave de fragmento e
o seu índice de suporte também podem afetar a estratégia que poderá ser utilizada.

No caso da estratégia baseada em hash, o sistema calcula automaticamen-


te cada um dos hashes dos fragmentos, o que gera um custo de sobrecarga. Nesse
tipo de estratégia, a probabilidade de os dados buscados estarem contidos em
um único fragmento é menor, resultando em mais operações de busca em todo
o cluster, pois, possivelmente, ela deverá ser realizada em mais de um shard. Já
nas situações em que a estratégia adotada é a de intervalo, a sobrecarga é menor,
tendo em vista que essa é a estratégia padrão e há uma maior probabilidade de
se encontrar todos os dados procurados em um mesmo shard, caso a busca esteja
limitada a um determinado intervalo de valores.

O MongoDB possui alta tolerância e disponibilidade, de forma que um


cluster fragmentado pode continuar executando as operações parciais de leitura e
gravação mesmo quando um ou mais shards estão em estado inativo, embora os
fragmentos armazenados nesses shards não possam ser acessados caso não haja ré-
plicas. Caso o cluster possua um conjunto de réplicas do servidor de configuração
(CSRS, Config Server Replica Set), é possível continuar o processamento de leituras
e gravações enquanto a maioria desse conjunto de réplicas estiver disponível. Por
isso, é muito importante manter a implementação do conjunto de réplicas, o que
garante maior redundância e disponibilidade dos dados (BOAGLIO, 2015).

O sharding é um processo importante para dimensionar bancos de dados


de forma horizontal, possibilitando o aumento da capacidade de processamento
e armazenamento sempre que necessário. A principal diferença entre a arquitetu-
ra de sharding do MongoDB e do Cassandra é a forma de replicação dos dados.
No Apache Cassandra, cada shard é um único servidor e um mesmo objeto é ar-
mazenado em vários shards. Já no MongoDB, cada shard um conjunto de réplicas
de vários servidores. Desse modo, cada objeto está contido apenas em um shard,
embora replicado várias vezes. No caso de falha do servidor do Cassandra, outro
shard conterá os dados, enquanto no MongoDB, dentro do próprio shard, outra
unidade do conjunto de réplicas irá substituí-lo. Essas falhas associadas a esse
processo resultarão em uma maior (Cassandra) ou menor (MongoDB) movimen-
tação dos dados entre os nós, o que impacta em um desempenho menos ou mais
estável desses sistemas de bancos de dados (BHAMRA, 2017).

172
TÓPICO 3 | FRAMEWORKS QUE UTILIZAM SHARDING COMO FORMA DE DISTRIBUIÇÃO

O foco principal do processo de particionamento é melhorar o desem-


penho e a escalabilidade de um sistema e, como adicional, ainda possibilitar a
melhora da disponibilidade, a depender de como esses dados serão divididos
e replicados. Caso haja falha em uma partição, isso não significa que necessa-
riamente um aplicativo cliente seja impedido de acessar os dados, que podem
estar replicados em outras partições. Por isso, ao estudar a utilização do sharding
como estratégia para o particionamento de bancos de dados, é preciso atenção
quanto às formas de replicação que o banco permite, pois é com o bom manejo
entre esses dois conceitos que o sistema de banco de dados escolhido pode ser
aproveitado da melhor forma.

173
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

LEITURA COMPLEMENTAR

Apache Cassandra

Kerlla de Souza Luz


Thiago Vinícius de Melo Almeida

1 INTRODUÇÃO

Atualmente, Amazon, Facebook e Google, empresas conhecidas em


nível mundial, caracterizadas por terem de manipular grandes volume de
dados e por operarem online 24 horas por dia, baseadas em suas necessidades,
desenvolveram suas próprias soluções de banco de dados NoSQL (SOARES,
2013). Cassandra é um banco de dados pósrelacional. Mas como esse termo não é
muito conhecido, utiliza-se o termo NoSQL. De acordo com Lopes (2010), apesar
do ganho no desempenho (não apresenta a sobrecarga de recurso do banco de
dados convencionais), a transição é considerada como complexa. Atualmente
o projeto Cassandra é baseado na tecnologia emergente NoSQL e encontrase
incubado pela Fundação Apache (FARIA, 2015).

É importante ressaltar que o Big Data foi um estopim para a ascensão


dos bancos NoSQL, mas como cita (Fowler, 2015), ele não é o único motivo.
A facilidade do uso de bancos NoSQL em ambientes distribuídos pode ser,
entre outros, um motivo para a escolha desse tipo de software. Dessa forma, o
Cassandra, trata-se de um projeto de alto nível da fundação Apache iniciado pelo
Facebook e construído levando em consideração aspectos estruturais dos projetos
Amazon’s, Dynamo e Google’s Bigtable. Tem como características escalabilidade
linear, tolerância a falha de forma transparente, alta disponibilidade, alta
performance, particionamento de dados e gerenciamento de dados estruturados,
semiestruturados e não estruturados (DATASTAX, 2015).

Muitos dos aplicativos on-line de hoje têm requisitos de banco de dados que
excedem as capacidades dos bancos de dados relacionais tradicionais. A necessidade
de baixa latência, os níveis desconhecidos de escalabilidade, tempo de atividade con-
tínua, distribuição global de dados, capacidade tanto de escrita e leitura de dados em
qualquer lugar, reduzindo o software e os custos operacionais, deu à luz a categoria
de banco de dados não relacional (PEREIRA, 2012). Esse tipo de banco de dados faz
uso de novos e desconhecidos modelos de arquiteturas e de dados. Para satisfazer as
exigências da moderna linha de aplicações, estes novos bancos de dados devem fazer
trocas com regras ditadas pelo teorema CAP (SOUSA, 2010).

2 APACHE CASSANDRA

Apache Cassandra é um banco de dados não-relacional de código aberto


altamente escalável que oferece disponibilidade contínua, desempenho em escala
linear, simplicidade operacional e fácil distribuição de dados em vários centros

174
TÓPICO 3 | FRAMEWORKS QUE UTILIZAM SHARDING COMO FORMA DE DISTRIBUIÇÃO

de dados e zonas de disponibilidade em nuvem (DATASAX, 2015). Cassandra


foi originalmente desenvolvido pelo Facebook, com código aberto em 2008, e
tornou-se um projeto de alto nível do grupo Apache em 2010.

2.1 PRINCIPAIS CASOS DE USO

Cassandra é um projeto que pode ser usado para qualquer propósito ou


área, contudo há um número de casos de uso onde esse se sobressai em muito das
outras opções. Por exemplo:

● Internet das coisas – perfeito para ser utilizado quando se precisa de escritas
rápidas vindas de dispositivos, sensores e mecanismos similares existentes em
diferentes localidades.
● Monitoramento de atividades de usuários – muitas companhias de entreteni-
mento fazem uso do Cassandra para acompanhar e coletar as interações dos
usuários com seus filmes, músicas, sites e aplicações.
● Serviços de mensagens e redes sociais – Cassandra atua como servidor de ba-
ckbone para vários provedores de serviços de telefonia.

2.2 VISÃO GERAL DA ARQUITETURA

Um dos fatores para a alta performance da solução Apache Cassandra é a


sua arquitetura, a qual se dá na forma de anel, porém sem as figuras de “máster”
e “slave”, logo todos os nós exercem a mesmo papel (DATASTAX, 2005).

Como a arquitetura do Apache Cassandra é linearmente escalável, e


sem ponto único de falha, em casos de necessidade de mais capacidade para
processamento de leitura e escrita basta adicionar mais nós em um cluster já
existente, isso a “quente”, sem downtime do serviço.

2.3. LEITURA E ESCRITA DE DADOS

O processo de escrita dos dados se dá primeiramente em uma área de disco


chamada commit log e depois em uma estrutura baseada em memória chamada

175
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

memtable. Quando uma memtable excede a um limite pré-definido o dado é


escrito em um arquivo imutável chamado SSTable. Cassandra aloca escritas em
buffer fazendo com que as escritas sejam sempre uma operação sequencial, isso
com várias operações de entrada e saída em disco acontecendo ao mesmo tempo.
Esse fluxo faz com que a performance da tecnologia Cassandra seja tão alta.

Atualizações ou inserções de colunas são tratadas como operações de


escrita e fazem uso de time stamp para determinar o valor mais atual.

Devido a forma como o Cassandra faz a sua escrita muitas SSTables


podem existir para uma única tabela de dados, porém um processo chamado
compaction ocorre de tempos em tempos mesclando as múltiplas SSTables em
uma a fim de deixar o acesso para leitura mais rápido. Para uma requisição de
leitura, Cassandra consulta uma área de memória chamada Bloom filter a qual
verifica a probabilidade de uma SSTable ter o dado requisitado. O Bloom Filter
pode responder rapidamente caso uma SSTable possui ou não o dado requisitado.
Cassandra ao identificar que uma SSTable não possui o dado requisitado não faz
a sua leitura por inteiro e já passa para a próxima SSTable.

176
TÓPICO 3 | FRAMEWORKS QUE UTILIZAM SHARDING COMO FORMA DE DISTRIBUIÇÃO

2.4 DISTRIBUIÇÃO E REPLICAÇÃO AUTOMÁTICA DE DADOS

A subseção anterior trouxe uma visão global de como se dá o processo


de leitura e escrita em um único nó, porém em uma arquitetura de banco de
dados distribuídos dois conceitos que impactam consideravelmente o processo
de leitura e escrita são distribuição e replicação, objeto das próximas sessões.
Os bancos de dados relacionais, e alguns NoSQL, na tentativa de contornar o
problema da grande massa de dados por muitas vezes fazem uso de uma técnica
chamada “sharding”, que consiste em um particionamento horizontal dos dados
entre vários servidores, os quais também são chamados de shards. Cada shard é
uma base de dados independente, porém em conjunto eles formam uma única
base de dados lógica. A Figura 4 ilustra a arquitetura em Sharding.

Cassandra ao invés de fazer uso do método sharding, faz uso de um


componente interno chamado partitioner, o qual determina como os dados
serão distribuídos pelo cluster. Um partitioner é um mecanismo de hashing
que pega uma chave primária de uma linha de uma tabela, processa um token
numérico para ela e atrela essa informação a um nó do cluster de um jeito que
seja previsível e consistente (DATASTAX, 2015). Ainda de acordo com a empresa
DataStax, o Partitioner é uma propriedade configurável do cluster Cassandra que
por padrão distribui os dados pelo cluster e garante uma distribuição uniforme
destes. Cassandra também mantém, de forma automática, o balanceamento dos
dados mesmo quando um nó do cluster é retirado ou adicionado. Em um cluster,
uma requisição de leitura ou escrita pode ser direcionada para qualquer nó. O nó
selecionado atuará como coordenador para aquela operação para aquele cliente.

2.5 REPLICAÇÃO NO CASSANDRA

Ao contrário de muitas outras bases de dados o mecanismo de replicação


do Cassandra é bem direto e fácil de configurar, assim diferenciando a solução de
muitas outras relacionais ou não-relacionais. Primeiramente é preciso entender

177
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

que réplicas são cópias de uma linha e quando esta é escrita pela primeira vez, isto
também é considerado como uma réplica. Durante a configuração de um cluster
é preciso definir um grupo de replicação, também chamado de snitch. Todos os
snicthes usam uma camada snitch dinâmica, a qual monitora a performance do
grupo e escolhe a melhor réplica para leitura.

A configuração de replicação é feita no nível de keyspace, assim é


possível obter diferentes modelos de replicação, sendo um para cada keyspace.
Cassandra é capaz de replicar para múltiplos nós do cluster, isso garante confiança,
disponibilidade contínua e operações de entrada e saída em alta velocidade.
O número total de replicações é referenciado como replication factor (fator de
replicação). Um fator de replicação 1 significa que há apenas uma réplica de cada
linha no cluster. Um fator de replicação igual a 3 significa que há 3 réplicas dos
dados dentro do cluster. Para realizar o trabalho de replicação Cassandra faz uso
de um protocolo chamado gossip, que é um protocolo peerto-peer para descoberta
e compartilhamento de informações entre os nós de um cluster (DATASTAX, 2015).

Uma vez que um keyspace e um fator de replicação foram configurados o


banco de dados Cassandra, automaticamente mantém essa replicação até mesmo
quando os nós são removidos, adicionados ou falham (DATASTAX, 2015). É
importante ressaltar que o fator de replicação não pode ser superior ao número de
nós do cluster. Quanto à estratégia de replicação existem duas estratégias possíveis:

● SimpleStrategy: utilizada para um único centro de dados;


● NetworkTopologyStrategy: recomendado para casos de possível expansão
ou vários centros de dados. Ao utilizar a estratégia de topologia em rede, o
Cassandra tenta alocar as réplicas em nós de diferentes racks, pois comumente,
nós em um mesmo rack falham ao mesmo tempo. As configurações mais
comuns são:
● Duas réplicas para cada centro de dados: esta configuração tolera falhas de um
nó por grupo de replicação.
● Três réplicas para cada centro de dados: esta configuração tolera falhas tanto
de um nó por grupo de replicação em um nível de consistência QUORUM_
LOCAL quanto várias falhas por centro de dados com nível de consistência um
(DATASTAX,2015).

2.6 DETECÇÃO DE FALHAS E RECUPERAÇÃO

Ao perceber que um nó está indisponível ou com a performance degradada,


uma das estratégias do Cassandra é evitar direcionar requisições para este. Para
realizar este processo de detecção de falhas e recuperação Cassandra utiliza o
protocolo peer-to-peer chamado gossip, mencionado anteriormente. Ao invés de
definir um limiar marcando a falha de um nó, Cassandra usa um mecanismo de
detecção que calcula para cada nó a performance de rede, carga de trabalho e
histórico de condições.

Quando um nó se recupera de uma falha ele pode ter perdido algumas


requisições de escritas, logo uma vez que um nó foi marcado como down, as

178
TÓPICO 3 | FRAMEWORKS QUE UTILIZAM SHARDING COMO FORMA DE DISTRIBUIÇÃO

escritas perdidas por este são armazenadas pelo coordenador daquela operação
em tabela local chamada system.hints por um período de tempo que é configurado
na variável max_hint_window_in_ms. No entanto, para que isso ocorra o recurso
hinted handoff precisa estar habilitado. Ao habilitar esse recurso o administrador
está configurando Cassandra para executar plano de ação a fim de contornar
casos de nós indisponíveis.

A Figura 5, ilustra um exemplo onde uma keyspace tem o fator de


replicação igual a 2 e o nível de consistência é igual a 1.

Na imagem anterior o nó C seria o proprietário da escrita para a linha


K porém, ele está inoperante. O nó A armazena o hint para quando o nó C se
recuperar e replica a escrita para o nó B. Quando o nó C se recuperar, o nó A irá
executar o hint armazenado, ou seja, irá replicar a escrita da linha K para C. O
nível de consistência em Cassandra é definido a nível tanto de leitura quanto de
escrita e são vários os níveis de consistência. A seguir abordamos alguns deles:

● ALL – quanto ao nível de escrita, o dado deve ser replicado para todos nós do
cluster para aquela chave de partição. Quanto ao nível de leitura, todos os nós
devem responder à operação de leitura. Provê o maior nível de consistência
dos dados e o menor nível de disponibilidade.
● ANY – quanto ao nível de escrita, o dado precisa ser escrito pelo menos em um
nó. Provê o maior nível de disponibilidade e o menor nível de consistência.
● LOCAL_QUORUM – Usado para múltiplos centros de dados. O dado precisa
ser escrito em um quórum de nós no mesmo centro de dados que possui o
coordenador da operação, o qual funcionará como coordenador para o quórum
local bem como para o quórum remoto. Provê um nível de consistência forte,
bem como evitar latência na comunicação entre os centros de dados. Segue
uma imagem como exemplo.

179
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

2.7 SUPORTE A CLOUD E MÚLTIPLOS CENTROS DE DADOS

Cassandra possui suporte para implementações com múltiplos centros de


dados e serviço de cloud, podendo ser com ambos ao mesmo tempo, ou seja, é
possível ter parte da solução em um centro de dados, on-premise, e outra parte em
cloud, conforme Figura 7. O fator de replicação em uma estrutura com múltiplos
centros de dados ou múltiplas zonas de cloud pode ser configurado de forma
personalizada para cada centro ou zona, assim é perfeitamente aceitável um fator
de replicação igual a 1 em centro de dados e fator de replicação igual a 2 em uma
zona de cloud ou um outro centro de dados.

180
TÓPICO 3 | FRAMEWORKS QUE UTILIZAM SHARDING COMO FORMA DE DISTRIBUIÇÃO

2.8 GERENCIAMENTO DE DADOS

Cassandra faz parte de uma linha de banco de dados que utiliza um


modelo não normalizado projetado para capturar e consultar a performance dos
dados. Embora Cassandra tenha objetos que se assemelham a um banco de dados
relacional (por exemplo, tabelas, chaves primárias, índices etc.), em Cassandra,
técnicas de modelagem de dados, necessariamente, afastam-se da tradição
relacional. Por exemplo, o legado do paradigma de modelagem de dados de
relação de atributo de entidade não é adequado para Cassandra do jeito que é com
um banco de dados relacional. O sucesso com Cassandra quase sempre se resume
em dois fatos: o modelo de dados e o hardware, especialmente o subsistema de
armazenamento selecionado.

Ao contrário de um banco de dados relacional, que penaliza o uso de


várias colunas de uma tabela, Cassandra é de alto desempenho com tabelas que
têm milhares ou até dezenas de milhares de colunas. Cassandra fornece alta
abstração de modelagem de dados para fazer este paradigma acessível para o
desenvolvedor.

2.8.1. Objetos de dados Cassandra

Entre os principais objetos básicos encontrados no Cassandra incluem:

● Keyspace - corresponde a um banco de dados no mundo relacional, e assim


como no mundo relacional as Keyspaces possuem nomes e atributos que define
seu comportamento. Keyspace – um grupo de várias famílias de colunas juntas.
É apenas um agrupamento lógico de famílias de colunas e fornece um escopo
isolado para nomes. O Cassandra permite a criação de várias Keyspaces por
aplicação, mas esta prática não é muito recomendada.
● Table (Tabela) - pouco parecida com uma tabela relacional, mas capaz de reter
grandes volumes de dados. A tabela também é capaz de fornecer inserções de
linha e leitura rapidamente.

181
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

● Coluna - a unidade mais básica do modelo de dados do Cassandra, contendo


um nome, um valor e um registro de data e hora.
● Primary Key (Chave primária) - utilizados para identificar uma linha única
em uma tabela e também distribuir as linhas da tabela em vários nós em um
cluster.
● Index (Índice) - semelhante a um índice relacional na medida em que acelera
algumas operações de leitura, porém difere de índices relacionais em aspectos
importantes.

2.9. CQL - CASSANDRA QUERY LANGUAGE

As primeiras versões do Cassandra utilizavam exclusivamente a interface


Thrift programático para criar objetos de banco de dados e manipular dados.
Enquanto Thrift ainda é suportado e mantido, a Cassandra Query Language
(CQL) tornou-se a principal API usado para interagir com um cluster Cassandra
hoje. Isto, representa uma melhoria substancial na usabilidade de Cassandra.

CQL se assemelha ao padrão SQL usado por todos os bancos de dados


relacionais. Devido a essa semelhança, a curva de aprendizagem para aqueles
que vêm do mundo relacional é reduzida. DDL (CREATE, ALTER, DROP), DML
(INSERT, UPDATE, DELETE, TRUNCATE) e consulta (SELECT) operações são
todos suportados. Tipos de dados CQL também refletem sintaxe RDBMS numérica
(int, bigint, decimal etc.), caracteres (ascii, varchar etc.), dados (timestamp etc.),
não estruturadas (blob etc.) e tipos de dados especializados (set, list, map etc.)são
suportados. Vários comandos CQL utilizam utilitários como cqlsh e ferramentas
gráficas como DataStax DevCenter podem ser usados para interagir com um
cluster de Cassandra, e os drivers cliente para Cassandra (Java, C # etc.) também
suportam CQL para o desenvolvimento de aplicações.

2.10 GERENCIAMENTO DE TRANSAÇÕES

Enquanto Cassandra não suporta transações ACID (Atomicidade,


Consistência, isolamento e durabilidade), como a maioria dos bancos de dados
relacionais mais antigos, que oferecem a parte de "AID" do ACID. Escritas para
Cassandra são atômicas, isoladas e duráveis. O "C" do ACID - consistência - não
se aplica a Cassandra, como não existe o conceito de integridade referencial ou
chaves estrangeiras.

Cassandra oferece a consistência dos dados regulável através de um cluster


de banco de dados. Isto significa que se pode decidir, caso se deseje consistência
forte ou eventual para uma transação particular. Podendo solicitar um pedido
especial para completar, se apenas um nó responde, ou solicitar a espera até todos
os nós responderem. A consistência de dados regulável é suportada em todos
os centros de dados únicos ou múltiplos, e você tem um número de diferentes
opções de consistência para escolher.

182
TÓPICO 3 | FRAMEWORKS QUE UTILIZAM SHARDING COMO FORMA DE DISTRIBUIÇÃO

A consistência é configurável em uma base por consulta, ou seja, você


pode decidir como a consistência forte ou eventual deve ser por operações
SELECT, INSERT, UPDATE e DELETE. Por exemplo, se você precisa de uma
transação particular para estar disponível em todos os nós em todo o mundo,
você pode especificar que todos os nós devem responder antes de uma transação
ser marcada como concluída. Por outro lado, uma peça menos crítica de dados
(por exemplo, uma atualização de meios de comunicação social), apenas pode
precisar de ser propagado, eventualmente, de modo que, nesse caso, o requisito
de consistência pode ser relaxado.

Cassandra também fornece transações leves, ou um mecanismo compare-


-and-set. Usando e estendendo o protocolo de consenso Paxos (que permite que
um sistema distribuído concorde sobre as modificações de dados propostas com
um algoritmo baseado em quórum, e sem a necessidade de qualquer commit
vindo de um banco de dados "mestre" ou de duas fases), Cassandra oferece uma
maneira de garantir um nível de isolamento da transação similar ao nível sinali-
zável oferecido pelo banco de dados relacional.

2.11 MIGRAÇÃO DE DADOS PARA O CASSANDRA

Exportar dados de um RDBMS ou de outro banco de dados para Cassan-


dra é considerado por muitos autores da área, como fácil, dependendo do estado
dos dados existentes. As seguintes opções existem atualmente para a migração de
dados para Cassandra:

● Comando COPY - O utilitário cqlsh fornece um comando de cópia que é capaz


de carregar dados de um arquivo do sistema operacional em uma tabela Cas-
sandra, porém, não recomendado para arquivos muito grandes.
● SSTable loader – este utilitário é projetado para carregar mais rapidamente
uma tabela Cassandra com campos delimitadores de alguma forma (por exem-
plo, vírgula, tabulação, etc).
● Sqoop – Sqoop é um utilitário usado em Hadoop para carregar dados de ban-
cos de dados relacionais em um cluster Hadoop. Como exemplo, o banco de
dados DataStax suporta dados em pipelining de uma tabela de banco de dados
relacionais diretamente em uma tabela Cassandra.
● ETL tools – há uma variedade de ferramentas de ETL (no português, extração,
transformação e carga) que suportam Cassandra tanto como uma plataforma
de dados de origem e de destino. Muitas destas ferramentas não só extraem os
dados de carga, mas também fornecem rotinas de transformação que podem
manipular os dados de entrada de muitas maneiras. Existem algumas destas
ferramentas livres para uso (por exemplo, Pentaho, Jaspersoft, Talend).

Cassandra foi desenhado de forma a minimizar gerenciamento e manu-


tenção constantes, como backup e restauração de dados, segurança e verificação
da consistência dos dados. Quanto a backup e restauração Cassandra possui vá-
rias opções de implementação dessas funções, podendo ser um snapshot ou um
backup incremental.

183
UNIDADE 3 | DADOS SEMI-ESTRUTURADOS E SHARDING

Quanto à segurança, por padrão Cassandra não possui nenhuma configu-


ração habilitada, porém quem é responsável pela sua administração pode imple-
mentar tais configurações de segurança como, por exemplo, conceder ou remover
privilégios com os conhecidos comandos grant e revoke, além das opções de crip-
tografia de dados entre cliente-servidor e servidor-servidor (DATASTAX, 2015).

2.12 CONSISTÊNCIA DOS DADOS

Como Cassandra faz uso de uma arquitetura distribuída sem


compartilhamentos há certas ocorrências de inconsistências de dados no cluster
devido a incidentes como nós indisponíveis ou falha na conectividade de rede.
Dessa forma, Cassandra toma automaticamente as medidas necessárias para
reduzir o impacto dessas inconsistências no cluster, porém o administrador
precisa periodicamente executar operações de manutenção para garantir que
todos os dados estejam consistentes. Para tal, Cassandra dispõe de um script
chamado repair que o administrador pode fazer uso sempre que necessitar
verificar a “saúde” do cluster.

3 CONCLUSÃO

De forma resumida, percebe-se que Cassandra é a melhor escolha quando


há exigência de replicação de dados em massa, pesada carga em cima do banco
de dados e maior tendência a leitura do que escrita.

Todavia, a inserção de dados ainda se mostra um pouco mais lenta que a


leitura e atualmente ainda não é um banco de dados considerado como referência
no mercado. A alta disponibilidade, escalabilidade, flexibilidade do esquema
e alta performance e gerenciamento de dados dos bancos NoSQL, trazem a
desvantagem de nem sempre ser possível garantir a consistência dos dados,
porém não deixam de ser uma ótima solução para cargas elevadas de dados.

FONTE: LUZ, K. S.; ALMEIDA, T. V. M. Apache Cassandra. Brasília: CIC UNB, 2016. Disponível em:
https://cic.unb.br/~alchieri/disciplinas/posgraduacao/sd/artigoG2.pdf. Acesso em: 13 abr. 2020.

184
RESUMO DO TÓPICO 3

Neste tópico, você aprendeu que:

• O Apache Cassandra é um banco de dados não relacional cuja arquitetura é


baseada no big Table, no Amazon Web Service e no DynamoBD.

• O particionamento horizontal de dados (sharding) do Apache Cassandra é um


método que aumenta a escalabilidade do sistema.

• O Cassandra utiliza um hash consistente para a replicação (3x) e o


particionamento de dados.

• Os hashs são organizados em um anel token.

• No mecanismo de busca os dados são desnormalizados e duplicados, criando


várias versões de uma mesma tabela, o que facilita o mecanismo de consulta.

• A escalabilidade do Apache Cassandra se torna quase infinita, com a vantagem


de que, se dobrar o número de nós, o sistema poderá lidar com quase o dobro
de leituras e gravações.

• O Cassandra se tornou um sistema de banco de dados com alta disponibilidade


de dados, rápida leitura, rápida gravação de dados e potencial de escalabilidade
linear.

CHAMADA

Ficou alguma dúvida? Construímos uma trilha de aprendizagem


pensando em facilitar sua compreensão. Acesse o QR Code, que levará ao
AVA, e veja as novidades que preparamos para seu estudo.

185
AUTOATIVIDADE

1 Quando um aplicativo é desenvolvido, há uma estrutura de bancos de dados


por trás dele com um tamanho e configurações predefinidos inicialmente.
Com o grande fluxo de informações na Internet, o cenário de aplicações
digitais pode mudar do dia para a noite, e aquele aplicativo pouco utilizado
pode começar a ter mais usuários e um tráfego de dados muito maior do que,
até aquele momento, pode suportar. Considere a seguinte situação:

Você trabalha na empresa que desenvolveu e administra um aplicativo, e


lhe foi atribuída a função de realizar o escalonamento do banco de dados
por trás dele. Algumas pessoas da equipe acham que você deve escalonar
horizontalmente, enquanto outras acham que o escalonamento vertical é
melhor. Veja, a seguir, mais informações sobre o aplicativo.

FONTE: O Autor

2 O particionamento horizontal de um banco de dados (ou shardind) é


realizado utilizando estruturas que permitem a identificação de cada partição.
Quanto a essas, as três mais comuns são:

a) ( ) Chave, hash e hash consistente.


b) ( ) Hash, zona e intervalo.
c) ( ) Hash, intervalo e diretório.
d) ( ) Chave, intervalo e faixas.
e) ( ) Intervalo, zona e localização.

3 O particionamento de dados está intimamente ligado à replicação. Quantos


a esses dois processos, é verdade que:

a) ( ) Apenas o conceito está associado, mas na prática não há ligação entre eles.
b) ( ) Apesar de terem nomes distintos, significam a mesma coisa.

186
c) ( ) Se a replicação não ocorrer, não há nenhum prejuízo para o sistema.
d) ( ) A integração do sharding com a replicação promove a alta
disponibilidade.
e) ( ) A utilização do sharding torna o processo de replicação desnecessário.

4 O Apache Cassandra utiliza uma estrutura de hash consistente para


particionar os dados. Quanto a essa estrutura, escolha a alternativa correta:

a) ( ) É organizado em uma estrutura visualizada como um cubo.


b) ( ) Acaba gerando alta movimentação de dados.
c) ( ) É organizado em uma estrutura visualizada como uma estrela.
d) ( ) No particionamento do Cassandra, o número de tokens é limitado a
100.
e) ( ) É organizado em uma estrutura visualizada como um anel.

5 Para realizar o sharding, o MongoDB necessita de uma estrutura mínima


com três componentes: shards, roteadores de consulta e servidores de
configuração. Quanto a esses componentes, é verdade que:

a) ( ) Os roteadores de consulta são a interface entre o aplicativo cliente e os


shards propriamente ditos.
b) ( ) Os roteadores de consulta utilizam informações fornecidas pelos
próprios shards.
c) ( ) Os servidores de configuração armazenam os dados e metadados de
forma conjunta.
d) ( ) Os shards armazenam metadados dos dados que estão nos servidores.
e) ( ) Os shards armazenam unicamente o dado bruto não particionado.

187
188
REFERÊNCIAS
ABADI, D. J. Data management in the cloud: limitations and
opportunities. IEEE Data Eng. Bull., New Haven, v. 32, p. 3-12. 2009. Disponível
em: http://www.cs.umd.edu/~abadi/papers/abadi-cloud-ieee09.pdf. Acesso em:
4 abr. 2020.

ABOUZEID, A. et al. HadoopDB. Proceedings of the Vldb endowment, [s.l.], v.


2, n. 1, p. 922-933, ago. 2009.

APACHE SOFTWARE FOUNDATION. The Apache Hadoop project develops


open-source software for reliable, scalable, distributed computing. Apache
Hadoop, [s.l.], c2020a. Disponível em: http://hadoop.apache.org/. Acesso em: 16
fev. 2020.

APACHE SOFTWARE FOUNDATION. Why CouchDB? CouchDB Relax, [s.l.],


c2020b. Disponível em: https://docs.couchdb.org/en/stable/intro/why.html.
Acesso em: 7 fev. 2020.

APACHE SOFTWARE FOUNDATION. Welcome to Apache HBase. Apache


HBase. [s.l.], c2020c. Disponível em: https://hbase.apache.org/. Acesso em: 10
abr. 2020.

APACHE SOFTWARE FOUNDATION. Welcome to Apache Zookeeper. Apache


Zookeeper, [s.l.], c2020d. Disponível em: https://zookeeper.apache.org/. Acesso
em: 10 abr. 2020.

APACHE SOFTWARE FOUNDATION. MapReduce tutorial. Apache Hadoop,


[s.l.], 2019. Disponível em: https://hadoop.apache.org/docs/stable/hadoop-
mapreduce-client/ hadoop-mapreduce-client-core/MapReduceTutorial.html.
Acesso em: 21 mar. 2020.

APACHE SOFTWARE FOUNDATION. Architecture. Apache Cassandra. [s.l.],


c2016a. Disponível em: http://cassandra.apache.org/doc/latest/architecture/
index.html. Acesso em: 9 abr. 2020.

APACHE SOFTWARE FOUNDATION. What is Cassandra? Apache Cassandra.


[s.l.], c2016b. Disponível em: http://cassandra.apache.org/. Acesso em: 10 abr.
2020.

APACHE SPARK. Spark streaming programming guide. Apache Spark,


[s.l.], c2020. Disponível em: https://spark.apache.org/docs/latest/streaming-
programming-guide.html. Acesso em: 30 mar. 2020.

189
ASF INFRABOT. Powered by. Confluence, [s.l.], 9 jul. 2019. Disponível em:
https://cwiki.apache.org/confluence/display/HADOOP2/PoweredBy. Acesso em:
15 fev. 2020.

ATZENI, P.; BUGIOTTI, F.; ROSSI, L. Uniform access to non-relational


database systems: the sos platform. Notes on numerical fluid mechanics and
multidisciplinary design, [s.l.], v. 7328, p. 160-174, 2012.

AWS - AMAZON WEB SERVICE. Data lakes e análises na AWS. AWS, [s.l.],
c2020a. Disponível em: https://aws.amazon.com/pt/big-data/datalakes-and-
analytics/. Acesso em: 16 fev. 2020.

AWS - AMAZON WEB SERVICE. Overview of Amazon web services. AWS,


[s.l.], c2020b. Disponível em: https://d1.awsstatic.com/whitepapers/aws-
overview.pdf. Acesso em: 16 fev. 2020.

AWS - AMAZON WEB SERVICE. Simple monthly calculator. AWS, [s.l.],


c2020c. Disponível em: https://calculator.s3.amazonaws.com/index.html?lng#.
Acesso em: 16 fev. 2020.

AWS - AMAZON WEB SERVICE. Amazon DynamoDB. Amazon Web Service,


[s.l.], c2020d. Disponível em: https://aws.amazon.com/pt/dynamodb/. Acesso
em: 10 abr. 2020.

AWS - AMAZON WEB SERVICE. AWS. Amazon Web Service, [s.l.], c2020e.
Disponível em: https://aws.amazon.com/pt/?nc2=h_lg. Acesso em: 10 abr. 2020.

AWS - AMAZON WEB SERVICE. Conceitos básicos do Amazon DynamoDB.


Amazon Web Service, [s.l.], c2020f. Disponível em: https://aws.amazon.com/pt/
dynamodb/getting-started/. Acesso em: 7 fev. 2020.

BAER, H. Particionamento no banco de dados Oracle 11g. Oracle, São Paulo,


jun. 2007. Disponível em: https://www.oracle.com/technetwork/pt/database/
enterprise-edition/ documentation/particionamento-banco-de-dados-11g-
432098-ptb.pdf?source=ad:p as:go:dg:bd+:ow:lp:cpo. Acesso em: 13 fev. 2020.

BERMAN, J. J. Principles of big data: preparing, sharing, and analyzing


complex information. Boston: Newnes, 2013.

BHAMRA, K. A comparative analysis of MongoDB and Cassandra. 2017.


65f. Dissertação (Mestrado em Ciências) - University of Bergen, Bergen, 2017.
Disponível em: http://bora.uib.no/bitstream/handle/1956/17228/kb-thesis.
pdf?sequence=1&isAllowed=y. Acesso em: 9 abr. 2020.

BIANCHI, W. Entendendo e usando índices: parte 1. DevMedia, Rio de Janeiro,


2007. Disponível em: https://www.devmedia.com.br/entendendo-e-usando-
indices-parte-1/6567. Acesso em: 21 fev. 2020.

190
BOAGLIO, F. MongoDB: construa novas aplicações com novas tecnologias. São
Paulo: Casa do Código, 2015.

BRADSHAW, S.; BRAZIL, E.; CHODOROW, K. MongoDB: the definitive guide


powerful and scalable data storage. 3. ed. Sebastopol: O'Reilly Media, 2019.

CARPENTER, J.; HEWITT, E. Cassandra: the definitive guide distributed data at


web scale. 2. ed. Sebastopol: O'Reilly Media, 2016.

CATTELL, R. Scalable SQL and NoSQL data stores. Acm sigmod record, [s.l.], v.
39, n. 4, p. 12-25, maio 2011. DOI: http://dx.doi.org/10.1145/1978915.1978919.

CODD, E. F. A relational model of data for large shared data


banks. Communications of the Acm, [s.l.], v. 13, n. 6, p. 377-387, jun. 1970.
Disponível em: http://dx.doi.org/10.1145/362384.362685. Acesso em: 4 abr. 2020.

COLLIER, M.; SHAHAN, R. Fundamentals of Azure: Microsoft Azure


essentials. Redmond: Microsoft Corporation, 2015.

CORMEN, T. H. et al. Algoritmos: teoria e prática. Rio de Janeiro: Editora


Campus, 2012.

COULOURIS, G. et al. Sistemas distribuídos. 5. ed. Porto Alegre: Bookman,


2013.

COYNE, L. et al. IBM private, public, and hybrid cloud storage solutions. 5.
ed. [s.l.]: Red-books, 2018. Disponível em: http://www.redbooks.ibm.com/
redpapers/pdfs/redp4873.pdf. Acesso em: 16 fev. 2020.

DAYANANDA, S. Spark streaming tutorial: sentiment analysis using apache


spark. Edu-reka! [s.l.], 22 maio 2019. Disponível em: https://www.edureka.co/
blog/spark-streaming/. Acesso em: 30 mar. 2020.

DB-ENGINES. DB-Engines Ranking. CreatDB, [s.l.], c2020. Disponível em:


https://db-engines.com/en/ranking. Acesso em: 7 fev. 2020.

DEAN, J.; GHEMAWAT, S. MapReduce: simplified data processing on large


clusters. In: OPERATING SYSTEMS DESIGN E IMPLEMENTATION, 6., 2004,
San Francisco. Proceedings [...]. San Francisco: ACM, 2004. p. 1–13. Disponível
em: https://static.googleusercontent. com/media/research.google.com/pt-BR//
archive/mapreduce-osdi04.pdf. Acesso em: 21 mar. 2020.

DIANA, M. de; GEROSA, M. A. NoSQL na web 2.0: um estudo comparativo


de bancos não relacionais para armazenamento de dados na web 2.0. In:
WORKSHOP DE TESES E DISSERTAÇÕES EM BANCO DE DADOS, 9., 2010,
São Paulo. Anais [...]. São Paulo: Universidade de São Paulo, 2010.

191
ELASTIC. O coração do Elastic Stack gratuito e aberto. Elasticsearch, [s.l.],
c2020. Disponível em: https://www.elastic.co/pt/elasticsearch. Acesso em: 21 fev.
2020.

GITHUB. Apache/Spark. GitHub, [s.l.], 8 mar. 2018. Disponível em: https://


github.com/apache/spark/blob/master/examples/src/main/python/wordcount.
py. Acesso em: 22 mar. 2020.

GOMES, P. C. T. O que é e como funciona um cluster? OPServices, Porto


Alegre, 3 mar. 2015. Disponível em: https://www.opservices.com.br/o-que-e-
um-cluster. Acesso em: 21 fev. 2020.

GOOGLE CLOUD. Cloud Storage. Google Cloud, [s.l.], c2020a. Disponível em:
https://cloud.google.com/storage. Acesso em: 16 fev. 2020.

GOOGLE CLOUD. Google cloud platform pricing calculator. Google


Cloud, [s.l.], c2020b. Disponível em: https://cloud.google.com/products/
calculator#id=ae05eb83-7e70-4f9c-a5b3-671b01ea4e00. Acesso em: 16 fev. 2020.

GOOGLE CLOUD. Cloud Bigtable. Google Cloud, [s.l.], c2020c. Disponível em:
https://cloud.google.com/bigtable. Acesso em: 10 abr. 2020.

GORASIYA, D. Comparison of open-source data stream processing engines:


Spark streaming, Flink and Storm. Technical Report, [s.l.], 2019. Disponível em:
https://www. researchgate.net/publication/336141201_Comparison_of_Open-
Source_Data_Stream_ Processing_Engines_Spark_Streaming_Flink_and_Storm.
Acesso em: 30 mar. 2020.

HANSON, J. Uma introdução ao Hadoop distributed file system. IBM, [s.l.], 30


ago. 2012. Disponível em: https://www.ibm.com/developerworks/br/library/wa-
introhdfs/index.html. Acesso em: 16 fev. 2020.

HIBERNATE SHARDS. Horizontal partitioning with hibernate: reference guide.


Docs, [s.l.], c2020. Disponível em: https://docs.jboss.org/hibernate/stable/shards/
reference/en/html_single/. Acesso em: 21 fev. 2020.

HIRIYANNAIAH, S. et al. Semi-structured data analysis and visualisation


using NoSQL. Internatio-nal Journal of Big Data Intelligence, [s.l.], v. 5, n. 3,
p. 133–142, 2018. DOI:10.1504/ijbdi.2018.092657. Disponível em: https://www.
inderscience.com/info/inarticle.php?artid=92657. Acesso em: 7 fev. 2020.

IBM CLOUD. IBM websphere application server. IBM Cloud, [s.l.], c2020a.
Disponível em: https://www.ibm.com/cloud/websphere-application-server.
Acesso em: 21 fev. 2020.

IBM CLOUD. Apache CouchDB. IBM Cloud, [s.l.], 6 ago. 2019b. Disponível em:
https://www.ibm.com/cloud/learn/couchdb. Acesso em: 7 fev. 2020.

192
IBM CLOUD. Cloud object storage. IBM Cloud, [s.l.], 2019. Disponível em:
https://cloud.ibm.com/catalog/services/cloud-object-storage. Acesso em: 16 fev.
2020.

IDG. Worldwide external disk storage systems factory revenue increased [...].
IDG, Framingham, 3 Mar. 2013. Disponível em: https://www.idg.com/news/
worldwide--external-disk-storage-systems-factory-revenue-increased-2-3-
during-the-fourth--quarter-of-2012-and-4-7-for-the-full-year-according-to-idc/.
Acesso em: 13 fev. 2020.

KIRAN, R. MapReduce tutorial: fundamentals of MapReduce with MapReduce


example. Edureka! [s.l.], 11 fev. 2020. Disponível em: https://www.edureka.co/
blog/mapreduce--tutorial/. Acesso em: 22 mar. 2020.

KOBELLARZ, J. MongoDB: sharding. Jordan Kobellarz, [s.l.], 11 ago. 2015.


Disponível em: http://jordankobellarz.github.io/mongodb/2015/08/11/mongodb-
sharding.html. Acesso em: 7 fev. 2020.

LAKSHMAN, A.; MALIK, P. Cassandra: a decentralized structured storage


system. ACM SIGOPS Operating Systems Review, [s.l.], v. 44, n. 2, p. 35-40,
2010. DOI: https://doi. org/10.1145/1773912.1773922. Disponível em: http://www.
cs.cornell.edu/Projects/ladis2009/papers/Lakshman-ladis2009.PDF. Acesso em: 9
abr. 2020.

MANNINO, M. V. Projeto, desenvolvimento de aplicações e administração de


banco de dados. 3. ed. Porto Alegre: Bookman, 2008.

MICROSOFT. Usando o particionamento de tabela e índice. Microsoft, [s.l.],


6 ago. 2017. Disponível em: https://docs.microsoft.com/pt-br/sql/relational-
databases/server--management-objects-smo/tasks/using-table-and-index-
partitioning?view=sql-server--ver15. Acesso em: 13 fev. 2020.

MICROSOFT AZURE. Particionamento horizontal, vertical e funcional de


dados. Microsoft Azure, [s.l.], 4 nov. 2018. Disponível em: https://docs.
microsoft.com/pt-br/azure/archi-tecture/best-practices/data-partitioning#why-
partition-data. Acesso em: 13 fev. 2020.

MICROSOFT AZURE. Calculadora de preço. Microsoft Azure, [s.l.],


c2020a. Disponível em: https://azure.microsoft.com/pt-br/pricing/
calculator/#storage4491fcd3-b2a8-4738-b456-3c331329107c. Acesso em: 16 fev.
2020.

MICROSOFT AZURE. Introdução ao Azure. Microsoft Azure, [s.l.], c2020b.


Disponível em: https://docs.microsoft.com/pt-br/azure/. Acesso em: 16 fev. 2020.

MONGODB. The database for modern applications. [s.l.]: MongoDB, c2020a.


Disponível em: https://www.mongodb.com/. Acesso em: 10 abr. 2020.

193
MONGODB. Sharding reference. MongoDB, [s.l.], c2020b. Disponível em:
https://docs.mongodb.com/manual/reference/sharding/. Acesso em: 10 abr. 2020.

MONGODB. MongoDB limits and thresholds. MongoDB, [s.l.], c2020c.


Disponível em: https://docs.mongodb.com/manual/reference/limits/. Acesso em:
7 fev. 2020.

MONGODB UNIVERSITY. Welcome to MongoDB University. MongoDB, [s.l.],


c2020. Disponível em: https://university.mongodb.com/. Acesso em: 7 fev. 2020.

NAZEER, H. et al. Real-time text analytics pipeline using open-source big


data tools. Arxiv, [s.l.], v. 1, 12 dez. 2017. Disponível em: https://arxiv.org/
pdf/1712.04344.pdf. Acesso em: 10 abr. 2020.

NEO4J. Introduction. In: NEO4J. The Neo4j Cypher Manual v4.0. [s.l.]: Neo4j,
Inc., c2020a. (capítulo 1). Disponível em: https://neo4j.com/docs/cypher-
manual/4.0/introduction/. Acesso em: 7 fev. 2020.

NEO4J. Neo4j bookshelf. Neo4J, [s.l.], c2020b. Disponível em: https://neo4j.com/


books/. Acesso em: 7 fev. 2020.

NILSSON, C.; BENGTSON, J. Storage and transformation for data analysis


using NoSQL. 2017. 80f. Dissertação (Mestrado em Tecnologia da Informação) -
Linköping University, Linköping, 2017. Disponível em: http://www.diva-portal.
org/smash/get/diva2:1149908/FULLTEXT01.pdf. Acesso em: 7 fev. 2020.

OPENJPA for distributed object persistence. Slice, c2020. Disponível em: http://
people.apache.org/~ppoddar/slice/site/index.html. Acesso em: 21 fev. 2020.

ORACLE. Oracle sharding. Oracle, Database, [s.l.], c2020. Disponível em:


https://www.oracle.com/database/technologies/high-availability/sharding.html.
Acesso em: 21 fev. 2020.

ORACLE BRASIL. O que é um banco de dados relacional. Oracle Brasil, Banco


de Dados, [s.l.], c2020. Disponível em: https://www.oracle.com/br/database/
what-is-a-relational-database/. Acesso em: 7 fev. 2020.

PATIL, V. S.; SONI, P. D. Hadoop skeleton & fault tolerance in Hadoop


clusters. International Journal of Application or Innovation in Engineering &
Management, [s.l.], v. 2, n. 2, p. 247-250, fev. 2013. Disponível em: https://pdfs.
semanticscholar.org/e31b/59b5f6e 0c13bd3fe5ced614653bf3aea260e.pdf. Acesso
em: 16 fev. 2020.

PENCHIKALA, S. Big Data com Apache Spark Part 3: Spark streaming. Info
Q, [s.l.], 5 dez. 2016. Disponível em: https://www.infoq.com/br/articles/apache-
spark-streaming/. Acesso em: 30 mar. 2020.

194
PETERSON, N. Get started guide for Azure IT operators. [s.l.]: Microsoft, 2016.
Disponível em: https://docsmsftpdfs.blob.core.windows.net/guides/azure/azure-
ops-guide.pdf. Acesso em: 16 fev. 2020.

PRAKASH, C. Spark streaming vs Flink vs Storm vs Kafka Streams vs Samza:


Choose your stream processing framework. Medium, [s.l.], 1 maio 2018.
Disponível em: https:// medium.com/@chandanbaranwal/spark-streaming-vs-
flink-vs-storm-vs-kafka-streams--vs-samza-choose-your-stream-processing-
91ea3f04675b. Acesso em: 30 mar. 2020.

RAMAKRISHNAN, R.; GEHRKE, J. Sistemas de gerenciamento de banco de


dados. 3. ed. Porto Alegre: AMGH, 2011.

RATHLE, P. Official release: 3 essentials of Neo4j 3.0, from scale to productivity


& deployment. Neo4j, [s.l.], 26 abr. 2016. Disponível em: https://neo4j.com/blog/
neo4j-3-0-massive-scale-developer-productivity/#capabilities-data-size. Acesso
em: 7 fev. 2020.

REIS, F. dos. O que são índices em bancos de dados: indexação em tabelas.


Bóson Treinamentos em Tecnologia, [s.l.], 15 out. 2019. Disponível em: http://
www.bosontreinamentos.com.br/bancos-de-dados/o-que-sao-indices-em-
bancos-de-dados-indexacao-em-tabelas/. Acesso em: 21 fev. 2020.

RIGHT SCALE. RightScale 2018 state of the cloud report: data to navigate your
multi-cloudstrategy. Santa Bárbara: Right Scale, 2018. Disponível em: https://
www.suse.com/media/report/rightscale_2018_state_of_the_cloud_report.pdf.
Acesso em: 16 fev. 2020.

SADALAGE, P. J.; FOWLER, M. NoSQL Essencial: um guia conciso para o


mundo emergente da persistência poliglota. São Paulo: Novatec Editora, 2019.

SAXENA, A. Spark streaming vs. structured streaming. DZone, [s.l.], 29 mar.


2019. Disponível em: https://dzone.com/articles/spark-streaming-vs-structured-
streaming. Acesso em: 30 mar. 2020.

SHARDA, R.; DELEN, D.; TURBAN, E. Business intelligence e análise de


dados para gestão do negócio. 4. ed. Porto Alegre: Bookman, 2019.

SHVACHKO, K. et al. The hadoop distributed file system. In: SYMPOSIUM


ON MASSIVE STORAGE SYSTEMS AND TECHNOLOGIES, 26., 2010,
Incline Village, NV. Proceedings [...]. Incline Village, NV: IEEE, 2010. p. 1-10.
Disponível em: https://storageconference.us/2010/Papers/ MSST/Shvachko.pdf.
Acesso em: 16 fev. 2020.

SILBERSCHATS, A.; KORTH, H. F.; SUDARSHAN, S. Sistema de banco de


dados. 6. ed. Rio de Janeiro: Elsevier, 2012.

195
STONEBRAKER, M. New opportunities for New SQL. Communications of the
Acm, [s.l.], v. 55, n. 11, p. 10-18, nov. 2012. Disponível em: https://www.cs.cmu.
edu/~pavlo/courses/fall2013/static/papers/p10-stonebraker.pdf. Acesso em: 4
abr. 2020.

TANENBAUM, A. S.; BOS, H. Sistemas operacionais modernos. 4. ed. São


Paulo: Pearson Education do Brasil, 2016.

TUTORIALS POINT. Learn CouchDB: simply easy learning. Tutorials Point,


[s.l.], c2020. Disponível em: https://www.tutorialspoint.com/couchdb/index.htm.
Acesso em: 7 fev. 2020.

WHITE, T. Hadoop: the definitive guide. 3. ed. Sebastopol: O'Reilly Media, Inc.,
2012.

XIN, R.; ROSEN, J.; PISTOR, K. Top 5 reasons for choosing S3 over HDFS.
Databricks, [s.l.], maio 2017. Disponível em: https://databricks.com/
blog/2017/05/31/top-5-reasons--for-choosing-s3-over-hdfs.html. Acesso em: 16
fev. 2020.

196

Você também pode gostar