Scalabilité de MongoDB

Post on 30-Jun-2015

558 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

Transcript

MongoDB Days, Paris, 2014

Scalabilité

Alain Hélaïli – alain.helail@mongodb.com AlainHelaili

Vitesse

Volume

Scalabilité de MongoDB

• Cluster shardé de plus de 250 serveurs

• Plus de 300 000 opérations par seconde, 200 serveurs, 5.5 milliards de documents

• 12 shards, 108 serveurs, 10 TB de données, 12 milliards de documents, croissance de 1.5M docs par an

• 100 applications déployées sur plus de 1 000 nœuds, 20 milliards d’opérations par jour

5

Better Data Locality In-Memory Caching In-Place Updates

Performance

vs.

Relational MongoDB

Facteurs de succès

Stockage : vitesse des accès disque, IOPS

RAM : capacité suffisante pour données actives et index

Requêtes : utilisation efficace d’index et projections

Remove : opération la plus coûteuse

Update : attention aux déplacements

Real-time ou bulk

Index : Ni trop, ni trop peu

Sharding : stratégie et clé de sharding

Ressources : ne partez pas seuls !

Outils

MongoDB Management Services (MMS)mongoperf : Test la capacité du disquemongostat : Activité des mongodmongotop : Activité des collections

Profiler : db.setProfilingLevel(0|1|2, slowms=100ms)

Explain : db.scores.find({student:0}).explain()

mTools : https://github.com/rueckstiess/mtools- mlogfilter, mloginfo, mplotqueries, mlogvis

mtools mlogvis

mongoperf

Sharding

Données de travail trop volumineuses

Débit I/O insuffisant

Modèle de scalabilité

Vertical Horizontal

Shard

• Un shard est un nœud du cluster• Il peut être un simple mongod ou un replica set

Stockage des métadonnées du cluster

• Config Server– Stocke les définitions des intervalles (chunks)

et leur localisation– 1 config server en dév, 3 en production– Ce n’est pas un replica set

Routing and Managing Data

• mongos– Agit comme routeur et équilibreur de charge– Aucune donnée stockée, processus light– On peut en avoir un ou plusieurs– Localisé avec l’application ou sur serveur dédié

Sharding infrastructure

Config

Config

Config

Partionnement de la donnée

Partionnement de la donnée

Activation du sharding sur la db

L’utilisateur définit une clé de sharding (fonctionnelle ou hash) par collection

La clé de sharding définit un ensemble ordonné de données

Chaque valeur de clé appartient à un intervalle

Les intervalles sont scindés et déplacés au fil du temps

Chunk initial

Découpage (split) des Chunks

Un chunk est scindé lorsqu’il atteint la taille maximum (64 Mo par défaut)

On ne peut découper qu’entre 2 valeurs distinctes

Un split n’entraine pas forcément de déplacement

Initialement 1 seul chunk

Les chunks sont scindés automatiquement lorsqu’ils atteignent la taille limite (64 Mo par défaut)

Les chuncks sont déplacés automatiquement

Déplacement des Chuncks

Nombre de Chunks Seuil de migration

< 20 chuncks 2

20 à 79 chuncks 4

> 80 chuncks 8

Le balancer d’un des mongos s’approprie le balancer lockUn seul lock une seule migration à la foisStatus du lock:

use configdb.locks.find({ _id: “balancer” })

Déplacement des Chuncks

mongos envoie une commande moveChunk à la source

Le shard source notifie le shard de destination

Le shard de destination construit les index nécessaires

Le shard de destination récupère les documents depuis la source

Les documents reste accessibles en R/W sur la source

Déplacement des Chuncks

Une fois les documents copiés

- Processus de synchronisation pour vérifier la transmission

- Mise à jour des config servers

Déplacement des Chuncks

Le shard source supprime les données déplacées

– Tous les curseurs ouverts doivent être fermés ou en timeout

– Curseurs avec NoTimeout empêche la libération du lock

Le mongos libère le lock

Déplacement des Chuncks

Routage des requêtes

Routage des requêtes : Targeted Query

• Des éléments de la clé de sharding sont présents dans la requêtes

• Le mongos peut cibler un sous ensemble de shard

• Une partie des shards n’est pas sollicité

Routage des requêtes : Scatter/Gather

• Le mongos ne peut pas sélectionner un sous ensemble de shard

• La requête est envoyée à l’ensemble des shards

• La fusion des résultats et le tri final sont effectués sur le shard primaire de la base de données

• Aggrégation : pipeline est découpé en 2 à partir du premier $group ou $sort

Choix de clé de sharding

• La clé de sharding est immutable• Les valeurs de la clé sont immutables• La clé de sharding doit être indexée• Taille limitée à 512 octets• Clé de sharding requise pour insertions• Clé de sharding utilisée pour le routage des

requête : critique pour la peformance

Choix de clé de sharding

• Cardinalité• Distribution des écritures• Isolation des requêtes• Performance des tris

Shard Key Hash

• Pros:– Très bonne distribution des écritures

• Cons:– Mise à jour des données et maintenance des index coûteuses

– Requêtes sur des intervalles et tris scatter gather

Shard 1

mongos

Shard 2 Shard 3 Shard N

Shard Key à faible cardinalité

• Peut introduire l’effet « jumbo chunks »• Equilibre de la charge incertain• Exemple : booléen, année de naissance…

Shard 1

mongos

Shard 2 Shard 3 Shard N

[ a, b[ [ c, d[

Shard Key Monotonique

• Clé toujours croissante ou toujours décroissante• Introduit des "hot spots" à l’insertion • Vitesse d’insertion non liée au nombre de shards• Examples: timestamps, _id

Shard 1

mongos

Shard 2 Shard 3 Shard N

[ ISODate(…), $maxKey )

Optimisations

Pre Splitting

• Permet de prédéfinir le partitionnement de la

collection : évite scissions et déplacements

• Cas d’ingestion massive de données

• Lorsque la collection est vide uniquement

for ( var x=97; x<97+26; x++ ) { //a, b, c, d….

for( var y=97; y<97+26; y+=6 ) { //a, g, m, s, y

var prefix = String.fromCharCode(x)+String.fromCharCode(y);

//prefix = aa, ag, am, as, ay, ba, bg…

db.runCommand( { split : "myapp.users" , middle : { email : prefix } } );

}

}

Tag-aware sharding

• Découpage macroscopique du cluster

• Splits et Move ont toujours lieu, en respectant les contraintes

• Un tag définit un intervalle • Recouvre plusieurs chunks• Recouvre plusieurs shards

sh.addShardTag("shard0000", "NYC")

sh.addShardTag("shard0001", "NYC")

sh.addShardTag("shard0002", "NYC")

sh.addShardTag("shard0003", "SFO")

sh.addTagRange("records.users", { zipcode: "10001" }, { zipcode: "10281" }, "NYC")

sh.addTagRange("records.users", { zipcode: "11201" }, { zipcode: "11240" }, "NYC")

sh.addTagRange("records.users", { zipcode: "94102" }, { zipcode: "94135" }, "SFO")

Read Global/Write Local

Primary:NYC

Secondary:NYC

Primary:LON

Primary:SYD

Secondary:LON

Secondary:NYC

Secondary:SYD

Secondary:LON

Secondary:SYD

Pilotage du balancer

Pilotage manuel Arrêt pendant les imports de masse

sh.startBalancer() / sh.stopBalancer()

Scheduling Fonctionnement pendant les périodes calmes

db.settings.update({ _id : "balancer" }, { $set : { activeWindow :

{ start : "23:00", stop : "6:00" } } }, true )

Conclusion

Conclusion

#1 – Modélisation

#2 – Index

#3 – IOPS et RAM

#4 – Sharding… avec la bonne clé

#5 – Monitoring

#6 – Améliorations 2.8

#7 – Nous pouvons vous aider

top related