Hands-on Workshop: Como configurar e utilizar uma estrutura MongoDB para Big Data

Post on 14-Jan-2015

139 views 2 download

description

Hands-on Workshop: Como configurar e utilizar uma estrutura MongoDB para Big Data No workshop, um ambiente MongoDB distribuído será configurado de maneira a possibilitar a escalabilidade de sua aplicação. Serão abordadas boas práticas para a utilização da infra-estrutura além dos seguintes temas: - Replicas e sharding; - Definição, utilização e manutenção de índices; - Map Reduce vs Aggregate; - Ferramentas úteis. Pre-requisitos: Computador pessoal com MongoDB 2.6 instalado (http://www.mongodb.org/downloads) No Ubuntu, o pacote é o mongodb-org; repositório disponível em http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/. Gabriel Campos Co-fundador e CTO da Zahpee. Bacharel em Ciência da Computação pela UFMG. Há mais de quatro anos atua no desenvolvimento de coleta, processamento e visualização de dados. MongoDB entusiasta e administrador do banco de dados da Zahpee.

Transcript of Hands-on Workshop: Como configurar e utilizar uma estrutura MongoDB para Big Data

Gabriel Campos

Como configurar e utilizar uma estrutura MongoDB para Big Data

Gabriel Campos

gabriel.campos@zahpee.com | @gcouti

Como funcionará?Iremos fazer diversos ciclos que irão

compreender apresentações de conceitos e

como implementá-los

Ok! Let’s do itLeeroy Jenkins

NoSQL x SQLNão relacional

Sem esquema

Escalabilidade

Relacional

Esquema bem definido

Transacional

Qual escolher?

Porque o mongoDB

Porque MongoDB?

Após alguns benchmarks, vimos uma boa

relação de custo benefício.

Além de uma boa documentação e

uma comunidade bastante ativa.

Inserindo alguns dados

Outras operações do mongoDB

use bdw

db.People.insert({ "nm" : "Gabriel Campos" , "pgt" : true })db.People.insert({ "nm" : "Thiago Cardoso" , "pgt" : false, "city": "BH" })

db.People.update({ "nm" : "Thiago Cardoso" },{ $set :{ "pgt" : true }})

db.People.find({"nm": "Gabriel Campos"})

MongoDB explaindb.People.find({"nm":"Gabriel Campos"}).explain(){

"cursor" : "BasicCursor", -> Não usou índice "isMultiKey" : false, -> Utilizou multikey index"n" : 1, -> Número de elementos que “casaram” com a query"nscannedObjects" : 2, -> Número de objetos escaneados"nscanned" : 2, -> Número de itens do índice que foram escaneados"nscannedObjectsAllPlans" : 2, -> Número de objetos escaneados em todos os planos"nscannedAllPlans" : 2, -> Número de itens escaneados em todos os planos"scanAndOrder" : false, -> Ordenou os elementos"indexOnly" : false, -> Objetos retornados estavam apenas no índice"nYields" : 0, -> Número de vezes que a query deixou

de ser feita por algum motivo"nChunkSkips" : 0, -> Número de chunks pulados devido

a “migração”"millis" : 0, -> Tempo para completar a query

}

Mais informações do comando explain

Índices

Os índices devem ser escolhidos com base nas consultas.

O tamanho dos índices costuma ser um dos principais fatores do custo da infraestrutura.

Evitar campos com grande cardinalidade.

db.People.ensureIndex({nm: 1 })

Um pouco mais sobre índices

for (var i=0;i<100000;i++){ var people = {}; people.nm = "Nome "+ i; people.pgt = i%2 == 0; db.People.save(people);}

A Inserção de dados dummy a-dummy.js

E agora? Como saber se ficou bom?

db.People.find({"nm":"Gabriel Campos"}).explain(){

"cursor" : "BtreeCursor nm_1", -> Indice utilizado"isMultiKey" : false, -> Utilizou multikey index"n" : 1, -> Número de elementos que “casaram” com a query"nscannedObjects" : 1, -> Número de objetos escaneados"nscanned" : 1, -> Número de itens do índice que foram escaneados"nscannedObjectsAllPlans" : 1, -> Número de objetos escaneados em todos os planos"nscannedAllPlans" : 1, -> Número de itens escaneados em todos os planos"scanAndOrder" : false, -> Ordenou os elementos"indexOnly" : false, -> Objetos retornados estavam apenas no índice"nYields" : 0, -> Número de vezes que a query deixou

de ser feita por algum motivo"nChunkSkips" : 0, -> Número de chunks pulados devido

a “migração”"millis" : 0, -> Tempo para completar a query

}

MongoDB explain

Mais informações do comando explain

MapReduce

Modelo utilizado para processar e agregar um grande volume de informação.

Funções de map e reduce são programadas em javascript.

Uma solução para contornar certos consultas que não são possíveis de fazer com Mongo puro.

db.People.mapReduce(function(){ emit(this.nm,this.pgt);},function(key,values){ return Array.sum(values)},{ query:{pgt:true}, out:"numero_pgt"})

B MapReduce b-mapreduce.js

Framework que auxilia o agrupamento de operações no mongoDB.

Pipeline de comandos.

Internamente o mongo otimiza algumas fases do pipeline.

Aggregate

db.People.aggregate({$match:{}

},{

$group:{_id:"$pgt","total":{

$sum:1}

}})

C Aggregate c-aggregate.js

Qual escolher?

Com mongoDB, sempre use aggregate.

Aggregate é implementado em C++ dentro

do MongoDB e o MapReduce é um javascript

interpretado em tempo de execução.

MapReduces podem gerar lock no banco.

Configurando a estrutura MongoDB

ReplicaSet

Redundância de informação.

Aumento da disponibilidade dos dados.

Distribuição de carga.

Em produção, a criação dos indices deve ser feita nas máquinas secundárias.

SecondarySecondary

Primary

cd ~mkdir -p mongo-bdwcd mongo-bdwmkdir -p rs0-0 rs0-1 rs0-2

D ReplicaSet, 1

# Iniciando replicas

mongod --port 27000 --dbpath ~/mongo-bdw/rs0-0 --replSet rs0 --smallfiles --nopreallocmongod --port 27001 --dbpath ~/mongo-bdw/rs0-1 --replSet rs0 --smallfiles --nopreallocmongod --port 27002 --dbpath ~/mongo-bdw/rs0-2 --replSet rs0 --smallfiles --noprealloc

D ReplicaSet, 2

mongo --port 27000

rs.initiate()rs.add("jarvis:27001")rs.add("jarvis:27002")rs.status()

D ReplicaSet, 3

Shards

Distribuir os dados em diversas máquinas de banco de dados.

Com o crescimento da quantidade de dados, os índices ocupam a memória e o número de page fault consequentemente também aumenta.

O processo de “shardeamento” deve acontecer antes que a memória esteja completamente ocupada.

cd ~cd mongo-bdwmkdir configmongod --configsvr --dbpath ~/mongo-bdw/config --port 20001mongos --configdb jarvis:20001 --port 27017 --chunkSize 1

E Shards, 1

mkdir -p rs1-0 rs1-1 rs1-2

mongod --port 27010 --dbpath ~/mongo-bdw/rs1-0 --replSet rs1 --smallfiles --nopreallocmongod --port 27011 --dbpath ~/mongo-bdw/rs1-1 --replSet rs1 --smallfiles --nopreallocmongod --port 27012 --dbpath ~/mongo-bdw/rs1-2 --replSet rs1 --smallfiles --noprealloc

E Shards, 2

mongo --port 27010rs.initiate()rs.add("<hostname:27011>")rs.add("<hostname:27012>")rs.status()

E Shards, 3

#Shardeandomongosh.addShard("rs0/jarvis:27000,jarvis:27001,jarvis:27002")sh.addShard("rs1/jarvis:27010,jarvis:27011,jarvis:27012")sh.enableSharding("bdw")

sh.shardCollection("bdw.People", { nm: 1} )

E Shards, 4

Como escolher as shards keys?

A aplicação da shard key é um processo irreversível.

Evitar shard keys que vão fazer com que os dados mudem de chunks constantemente.

Evitar com que os dados fiquem acumulados no mesmo chunk.

Já sei tudo! Estou pronto para criar minha

estrutura mongoDB?

Gabriel Campos

gabriel.campos@zahpee.com | @gcouti

Obrigado!

ReferênciasLeeroy Jenkins - https://www.youtube.com/watch?v=LkCNJRfSZBUOperações com MongoDB - http://goo.gl/xzFeCADocumentação do explain - http://goo.gl/a81gKfDocumentação dos indices - http://goo.gl/ckoZrpDocumentação replicaSet - http://goo.gl/ZvCQSYDocumentação shards - http://goo.gl/JaPYmA

ÍCONES*

SLIDE 13Redirect designed by Alexander Bickov from the Noun Project

SLIDE 17Keys designed by Michael Rowe from the Noun Project

* Os ícones não mencionados são de domínio público.

SLIDE 2Mortar Board designed by Monika Ciapala from the Noun ProjectBeaker designed by Shmidt Sergey from the Noun Project

SLIDE 8Talking designed by Hadi Davodpour from the Noun Project

SLIDE 9Tag designed by baabullah hasan from the Noun Project

SLIDE 12Share designed by Stephanie Wauters from the Noun Project

Árvore de indices