coisas que aprendemos usando mongoid com grande quantidade de dados

64
Coisas que aprendemos usando Mongoid com grande quantidade de dados @fabioperrella

Upload: fabio-perrella

Post on 25-May-2015

1.178 views

Category:

Documents


6 download

TRANSCRIPT

Page 1: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Coisas que aprendemos usando Mongoid com grande quantidade de

dados

@fabioperrella

Page 2: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Créditos também para:Claudio Bruno Martins

@marciotrindade

Page 3: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Objetivos

● Mostrar coisas que descobrimos

● Mostrar técnicas que usamos

● Ver se alguem fala "NAO FAÇAM ISSO!"

● Fazer alguem pensar ou falar "NOSSA, DA

PRA FAZER ISSO!"

Page 4: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Email Marketing - Locaweb

● SaaS

● Multi Tenant

● Grande quantidade de dados

● Grande histórico de dados

● Sistema antigo, baseado no php-list

● ==> Nova plataforma em Rails + MongoDB!

● Lançamento na próxima semana

Page 5: Coisas que aprendemos usando Mongoid com grande quantidade de dados

MongoDB● Simplicidade

● Sharding: grande quantidade de dados

● Schema-free: campos customizados contatos, filtros

● Replica Set: Alta disponibilidade

● Operações Atomicas: inc, addToSet, pull, push...

● Boa performance

● Maturidade: mongosp 2011!

● Atualizações constantes! (estamos na v2.0.5)

Page 6: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Mongoid

● Simplicidade

● Boa documentação

● Mongo Mapper tinha bug com muitos

documentos embedados (faz tempo)

● .. e está chegando a versão 3 muito melhor!

Page 7: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Implementação de Campos Customizáveis

Page 8: Coisas que aprendemos usando Mongoid com grande quantidade de dados

● 1a ideia - Mongoid dynamic fields (allow_dynamic_fields)

Implementação de Campos Customizáveis

Page 9: Coisas que aprendemos usando Mongoid com grande quantidade de dados

● 1a ideia - Mongoid dynamic fields (allow_dynamic_fields)

● Problemas○ Proteção de campos internos (status, id, etc..)

○ Restrição no nome dos campos customizáveis

○ allow_dynamic_fields no Mongoid é global!

● Vantagens?○ Indice nos campos

Implementação de Campos Customizáveis

Page 10: Coisas que aprendemos usando Mongoid com grande quantidade de dados

● 2a ideia - field custom_fields, type: hash

Implementação de Campos Customizáveis

Page 11: Coisas que aprendemos usando Mongoid com grande quantidade de dados

● 2a ideia - field custom_fields, type: hash

● Vantagens○ Proteção dos campos internos

○ Liberdade no nome dos campos

● Problemas?○ Índice nos campos

Implementação de Campos Customizáveis

Page 12: Coisas que aprendemos usando Mongoid com grande quantidade de dados

● Indice nas chaves de um hash! (inclusive em chaves que não existem)

Implementação de Campos Customizáveis

Page 13: Coisas que aprendemos usando Mongoid com grande quantidade de dados

● Cuidado com indices!● Geração de indice faz lock do DB inteiro!

○ 10min collection com 50milhoes de documentos

● Custo alto (memoria, espaço em disco, escrita)

Implementação de Campos Customizáveis

Page 14: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Implementação de Campos Customizáveis● Se o cliente quiser trocar o nome dos

campos?○ Toma essa!! operador $rename =~ Alter table

Page 15: Coisas que aprendemos usando Mongoid com grande quantidade de dados

● Buscas tipadas (string, date, int)Contact.where("custom_fields.date" =>

{"$lt" => Time.parse("1982-01-1")})● Operadores de condição:

http://www.mongodb.org/display/DOCS/Advanced+Queries

Implementação de Campos Customizáveis

Page 16: Coisas que aprendemos usando Mongoid com grande quantidade de dados

● Bug no MongoDB, ordenação de indices

● Case Sensitive (http://jira.mongodb.

org/browse/SERVER-90)

● Fix: criar campo em lowercase{ "_id": ObjectId("4fdfd0ada53bd0206a000003"), "email": "[email protected]", "name": "PopoLala", "name_lc": "popolala"}

Implementação de Campos Customizáveis

Page 17: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

Page 18: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

● Opções de modelagem:○ 1) Embed Documents

○ Vantagens:■ Consulta rápida dos dados

○ Desvantagens:■ Tamanho do documento

Page 19: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

Page 20: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

● Problemas!

○ Tamanho máximo de um documento 4MB, 8, 16..

■ melhor não passar de 100KB

○ Alternativa quebrar em chunks -> complexidade!

○ Gridfs? não

Page 21: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

● Opções de modelagem:○ 2) Has And Belongs to Many

○ Vantagens:■ Tamanho dos documentos menor?

■ Consistência

○ Desvantagens:■ Busca

■ Tamanho dos documentos!!!

Page 22: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

Page 23: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

● Opções de modelagem:○ 2) Has And Belongs to Many

■ Tamanho do documento com 201mil ObjectIds!

Page 24: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

● Problemas!

○ Complexidade no codigo para usar only(:fields)

Page 25: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

● Opções de modelagem:○ 3) Has And Belongs to Many!!

Page 26: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

● Opções de modelagem:○ 3) Has And Belongs to Many!!

http://agendaculturalpiracicabana.blogspot.com.br/2012/01/dia-13-sexta-feira-vamos-cacar-o-saci.html

Page 27: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

● Opções de modelagem:○ 3) Has And Belongs to Many

○ Vantagens:■ Tamanho dos documentos menor!

■ Consistência

○ Desvantagens:■ Busca?

■ Implementação fora do padrão

Page 28: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

Page 29: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

Page 30: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

GEM (wip):

https://github.com/fabioperrella/mongoid_belongs_to_many

Page 31: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Belongs To Many

● Opções de modelagem:○ 3) Has And Belongs to Many

○ Indice em campos tipo array!

index :message_ids

Page 32: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Mongoimport

● Feature: Importação de contatos em massa

● Problema○ Listas com mais de 100mill contatos

○ Concorrência entre clientes

○ Precisa ser rápido!

● Solução○ mongoimport

Page 33: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Mongoimporthttp://www.mongodb.

org/display/DOCS/Import+Export+Tools#ImportExportTools-mongoimport

● Ponto positivo:○ Velocidade (mais de 8mil documentos/segundo)

● Pontos Negativos○ Validação dos dados

Não há como fazer "Merge" de dados○ Dificil tratar de erros pois roda com system

Page 34: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Mongoimport

● Validação dos dados

Page 35: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Mongoimport● to_mongo_json

○ carregar objeto com dados do CSV e validar!

○ conversão de ObjectIds

○ conversão de datas (timestamp em miliseconds)

○ conversão de Array de ObjectIds (relacionamentos)

○ conversão de Hashes

○ gerar JSON no formato do mongoimport

● Bug data < epoch (https://jira.mongodb.org/browse/SERVER-

961)

Page 36: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Mongoimport

● Merge de dados nao existe!○ opção "upsert" atualiza documento inteiro, não é

possivel fazer merge https://jira.mongodb.

org/browse/SERVER-1674

○ PERIGO com dados que podem ser atualizados

por outro lugar (counts, etc..)

○ Solução: Mongoid collection.update!

Page 37: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Mongoimport

● Merge de dados não existe!○ collection.update apenas nos campos que

precisam ser atualizados

Page 38: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Mongoimport

● Tratamento de erros

Page 40: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Updating - Atomic Operators● http://www.mongodb.org/display/DOCS/Updating

● inc

● set / unset

● push

● pushAll

● addToSet e each

● pop / pull

● pullAll

● rename

Page 41: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Updating - Atomic Operators● inc: incrementa um número

○ pode ser usado com campo nil

Page 42: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Updating - Atomic Operators● inc

○ pode ser usado em hashes (mesmo vazios!)

Page 43: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Updating - Atomic Operators● inc com multi:true (em N documentos)

○ somente com o collection.update no mongoid

Page 44: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Updating - Atomic Operators● set: seta valor de um campo

○ no mongoid só é possível atualizar 1 campo com

o .set

Page 45: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Updating - Atomic Operators● addToSet

○ insere 1 elemento em um array se já não existir nele

○ pode fazer mais de uma operação por vez, por exemplo

com INC

Page 46: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Updating - Atomic Operators● addToSet com each

○ insere N elementos em um array se não existirem nele

Page 47: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Updating - Atomic Operators● pull / pullAll

○ remove 1 / N elementos de um array

Page 48: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Updating - Atomic Operators● rename

○ renomeia nome de campos, inclusive de hashes!

Page 49: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Sharding● Não deixe pra depois se já sabe que vai precisar!

○ tempo para implementação, testes...

○ shard balancing pode sobrecarregar máquina se já

estiver no limite

○ algumas coisas não funcionam (ou não funcionam

direito) com shard, exemplo:

■ counts

■ mongodb unique index

Page 50: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Sharding● não deixe pra depois se ja sabe que vai precisar!

○ mongoid shard_key (se nao tiver, dá erro em update,

inserts..)

Page 51: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Sharding● não deixe pra depois se ja sabe que vai precisar!

○ Safe mode: ligar no test / development, desligar em prod!

Page 52: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Sharding● mongoS, configServer, replicaSet, mongoDB

Page 53: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Sharding● Chunks, splitting e balancing

○ Chunk: pedaço de uma collection

○ Splitting: quebra de chunk quando fica grande (64M)

○ Balancing: mover chunk para outro shard quando o atual

está mais cheio

Page 54: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Sharding● Chunks, splitting e balancing

○ Exemplo: Collection Users com campo mês de aniversário

○ Sharding key: mês de aniversário

Começo Fim Shard

fevereiro março A

setembro +infinito A

Começo Fim Shard

-infinito fevereiro B

março setembro B

Page 55: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Sharding● Chunks, splitting e balancing

○ após splitting

Começo Fim Shard

fevereiro junho A

junho março A

setembro +infinito A

Começo Fim Shard

-infinito fevereiro B

março setembro B

Page 56: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Sharding● Escolha da shard key

○ "It is important to choose the right shard key for a

collection. If the collection is gigantic it is difficult to

change the key later. When in doubt please ask for

suggestions in the support forums or IRC". (1a linha

no site do mongodb)

○ http://www.mongodb.

org/download/attachments/2097354/how+queries+w

ork+with+sharding.pdf

Page 57: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Sharding● Escolha da shard key

○ pensar na escrita e leitura dos dados:

■ load balancing: na escrita deve dividir dados entre

os shards

■ na leitura tentar não varrer vários shards para ter

a resposta

Page 58: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Sharding● Escolha da shard key

○ como não deve ser:

■ low-cardinality: por exemplo continentes (africa,

america, europa)

■ ascending shard key: por exemplo objectid, vai

concentrar todas leituras e escritas em um shard

■ random shard key: por exemplo md5, quase sempre

vai precisar juntar os dados de varios chunks, nao vai

conseguir deixar dados parecidos juntos

Page 59: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Sharding● Escolha da shard key

○ recomendado: objectid + search key

Exemplo:

Inicio Fim Shard

-infinito Africa,000111 A

Africa,000111 Africa,999999 B

Africa,999999 Europa,22233 A

Europa,22233 Europa,87652 B

Europa,87652 +infinito B

Page 60: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Replicaset● Prefira escalar usando shards e não replicasets com leitura

nos secundário (slave_ok = true no Mongoid)

● Leitura insegura. Nos secundários podem haver dados

antigos

● Ainda em estudo por nós..

○ estratégia de backup em secundários

○ compactação de dados nos secundários

○ journaling habilitado apenas no secundário de backup

Page 61: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Monitoração● mongostat --discover

Page 62: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Monitoração● db.stats()

● db.collecionName.stats()

● rs.serverStatus()

● rs.status()

● db.currentOp()

● MongoDB Monitoring Service (MMS)

○ SaaS

○ Free!

Page 63: Coisas que aprendemos usando Mongoid com grande quantidade de dados

Testes de carga● velocidade de escrita (ex: importação de contatos)

● ambiente de homologação rodando com base carregada

● analisar queries lentas com explain() no console do mongo

● simular casos extremos (ex: cliente grande com muitos

contatos)

● definir limites de segurança

Page 64: Coisas que aprendemos usando Mongoid com grande quantidade de dados

● http://www.mongodb.org

● Scaling MongoDB (Kristina Chodorow)

● 50 Tips and Tricks for MongoDB Developers

(Kristina Chodorow)

● MongoDB in Action (Kyle Banker)

Referências