web-dev-qa-db-fra.com

Comparaison des performances d'insertion en bloc de MongoDB et de RethinkDB

Ceci est ma première question officielle ici; Toutes les critiques sur mon message sont les bienvenues pour que je puisse apprendre à être un meilleur SO citoyen.

J'utilise actuellement un SGBD non relationnel pour stocker des listes de désinscription potentiellement volumineuses, orientées vers MongoDB ou RethinkDB, à l'aide de leurs bibliothèques clientes Python respectives. Le point critique de mon application étant les performances d'insertion en masse, j'ai donc configuré deux scripts Python pour insérer 20 000 enregistrements par lots de 5 000 dans une collection MongoDB et une collection RethinkDB.

Le script python MongoDB mongo_insert_test.py:

NUM_LINES = 20000
BATCH_SIZE = 5000

def insert_records():
    collection = mongo.recips
    i = 0
    batch_counter = 0
    batch = []
    while i <= NUM_LINES:
        i += 1
        recip = {
            'address': "test%d@test%d.com" % (i, i)
        }
        if batch_counter <= BATCH_SIZE:
            batch.append(recip)
            batch_counter += 1
        if (batch_counter == BATCH_SIZE) or i == NUM_LINES:
            collection.insert(batch)
            batch_counter = 0
            batch = []

if __== '__main__':
    insert_records()

Le script python RethinkDB presque identique, rethink_insert_test.py:

NUM_LINES = 20000
BATCH_SIZE = 5000

def insert_records():
    i = 0
    batch_counter = 0
    batch = []
    while i <= NUM_LINES:
        i += 1
        recip = {
            'address': "test%d@test%d.com" % (i, i)
        }
        if batch_counter <= BATCH_SIZE:
            batch.append(recip)
            batch_counter += 1
        if (batch_counter == BATCH_SIZE) or i == NUM_LINES:
            r.table('recip').insert(batch).run()
            batch_counter = 0
            batch = []

if __== '__main__':
    insert_records()

Dans mon environnement de développement, le script MongoDB insère 20 000 enregistrements en moins d'une seconde:

$ time python mongo_insert_test.py 
real    0m0.618s
user    0m0.400s
sys     0m0.032s

Dans le même environnement, le script RethinkDB est beaucoup plus lent, insérant 20 000 enregistrements en plus de 2 minutes:

$ time python rethink_insert_test.py
real    2m2.502s
user    0m3.000s
sys     0m0.052s

Me manque-t-il quelque chose d’énorme en ce qui concerne le fonctionnement de ces deux SGBD? Pourquoi RethinkDB fonctionne-t-il si mal avec ce test?

Ma machine de développement disposait d'environ 1,2 Go de mémoire disponible pour ces tests.

25
njyunis

RethinkDB implémente actuellement des insertions par lot en effectuant une insertion à la fois sur le serveur. Dans la mesure où Rethink efface tous les enregistrements sur disque (car ils ont été conçus avec le souci de la sécurité), cela a un effet très négatif sur des charges de travail telles que celle-ci.

Nous faisons deux choses pour résoudre ce problème:

  1. Les insertions en bloc seront mises en œuvre via un algorithme d’insertion en bloc sur le serveur afin d’éviter d’effectuer une insertion à la fois.
  2. Nous vous donnerons la possibilité d'assouplir les contraintes de durabilité afin de permettre à la mémoire cache d'absorber des insertions à haut débit si vous le souhaitez (en échange de la synchronisation sur disque non aussi souvent).

Cela sera absolument réglé dans 4-12 semaines (et si vous en avez besoin, n'hésitez pas à m'envoyer un email à [email protected] et je verrai si nous pouvons redéfinir les priorités).

Voici les problèmes pertinents de github:

https://github.com/rethinkdb/rethinkdb/issues/207

https://github.com/rethinkdb/rethinkdb/issues/314

J'espère que cela t'aides. S'il vous plaît, n'hésitez pas à nous contacter si vous avez besoin d'aide.

46
coffeemug

Laissant de côté ce coffemug posté:

  1. en fonction de la version du pilote que vous utilisez et de la manière dont vous configurez la connexion à mongodb, il est possible que ces inserts ne soient pas reconnus par le serveur. Si vous utilisez la dernière version du pilote Python, ces opérations n'attendent qu'un accusé de réception du serveur (ce qui ne signifie pas que des données ont même été écrites en mémoire). Pour plus de détails sur ce à quoi je fais référence, consultez le paramètre Mongodb write Concern concern

  2. vous pouvez accélérer le cas de Rethinkdb en parallélisant les insertions. En gros, si vous exécutez plusieurs processus/threads, la vitesse augmentera. Dans le cas de Mongo, en raison des verrous impliqués, le parallélisme n’aidera pas.

Cela étant dit, RethinkDB pourrait améliorer la vitesse d'écriture.

PS: Je travaille pour Rethink, mais les points ci-dessus sont basés sur ma connaissance impartiale des deux systèmes.

6
Alex Popescu

Développeur Pymongo ici - juste au cas où vous ne le feriez pas, veuillez vous assurer que vous utilisez la dernière version de pymongo et MongoClient ou MongoRepicaSetClient afin que vos écritures soient reconnues et ne soient pas lancées et oubliées. Comme @Alex le dit, ils seront probablement ce dont vous avez besoin.

Les autres considérations à prendre en compte sont les suivantes: s’agit-il du principal cas d’utilisation de la base de données ou simplement du principal problème? Avant de prendre votre décision, vous pouvez envisager d’autres modèles de données, interrogation des données, facilité d’utilisation et facilité de maintenance.

4
Ross

S'il vous plaît, excusez l'analogie - mais cela rend mon propos parfaitement clair.

Il ne faut pas beaucoup de temps pour enfermer quelque chose de précieux dans un coffre-fort, mais faites-le des milliers de fois. Si vous avez posté dans le coffre d'une banque à la place, considérez le moment où votre valeur n'est pas sécurisée pendant son voyage vers votre banque; ce colis serait probablement empilé avec beaucoup d'autres colis - de déposants aux vues similaires. Quelqu'un s'empressera d'ouvrir votre colis, puis l'empilera avec d'autres objets à placer dans un coffre-fort sécurisé.

C'est là que réside la différence entre les validations habituelles de données sur disque et le traitement par lots ou l'écriture paresseuse de données sur disque. C'est un compromis entre une plus grande intégrité des données et de meilleures performances en écriture. Si la perte de données importe moins, il est parfaitement acceptable de procéder à une synchronisation moins fréquente sur le disque, à des mises à jour par lots ou paresseuses. Faire le mauvais choix vous fera mordre dans le cul un jour, alors choisissez judicieusement!

0
user924272