Le moyen le plus rapide d'importer des millions de documents JSON dans MongoDB
J'ai plus de 10 millions de documents JSON de la forme :
["key": "val2", "key1" : "val", "{\"key\":\"val", \"key2\":\"val2"}"]
dans un seul fichier.
De l'importation à l'aide de JAVA API de Pilote a pris environ 3 heures, alors que l'aide de la fonction suivante (de l'importation d'un BFILS à un moment):
public static void importJSONFileToDBUsingJavaDriver(String pathToFile, DB db, String collectionName) {
//open file
FileInputStream fstream = null;
try {
fstream = new FileInputStream(pathToFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("file not exist, exiting");
return;
}
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
//read it line by line
String strLine;
DBCollection newColl = db.getCollection(collectionName);
try {
while ((strLine = br.readLine()) != null) {
//convert line by line to BSON
DBObject bson = (DBObject) JSON.parse(JSONstr);
//insert BSONs to database
try {
newColl.insert(bson);
}
catch (MongoException e) {
//duplicate key
e.printStackTrace();
}
}
br.close();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
Est-il un moyen plus rapide? Peut-être, MongoDB paramètres peuvent influencer la vitesse d'insertion? (par exemple l'ajout de la clé : "_id" qui servira d'index, de sorte que MongoDB n'aurait pas à créer artificiellement des clés et donc de l'indice pour chaque document) ou de désactiver la création de l'index à l'insertion.
Merci.
source d'informationauteur user1264304 | 2013-10-28
Vous devez vous connecter pour publier un commentaire.
Je suis désolé, mais vous êtes tous la cueillette des mineurs des problèmes de performance au lieu de la base. La séparation de la logique à partir de la lecture du fichier et l'insertion est un petit gain. De charger le fichier en mode binaire (via MMAP) est un petit gain. À l'aide de mongo est des insertions est un gros gain, mais toujours pas de dés.
L'ensemble du goulot d'étranglement des performances est le BFILS bfils = JSON.parse(ligne). Ou en d'autres termes, le problème avec la Java des pilotes, c'est qu'ils ont besoin d'une conversion de json à bfils, et ce code semble être affreusement lent ou mal mises en œuvre. Plein JSON (encoder+décoder) via JSON simple ou spécialement via JSON-smart est 100 fois plus rapide que le JSON.parse() de la commande.
Je sais Débordement de Pile est de me dire juste au-dessus de cette boîte que je devrais répondre à la réponse, dont je ne suis pas, mais soyez assurés que je suis toujours à la recherche d'une réponse pour ce problème. Je ne peux pas croire que tous les discours sur les Mongo du rendement et puis cet exemple simple de code échoue lamentablement.
J'ai fait de l'importation d'un multi-ligne du fichier json avec ~250 millions de dossiers. Je viens de l'utiliser mongoimport < data.txt et il a fallu 10 heures. Par rapport à votre 10M vs 3 heures, je pense que c'est beaucoup plus rapide.
Aussi de mon expérience de l'écriture de votre propre multi-thread analyseur serait d'accélérer les choses radicalement. La procédure est simple:
Un rappel:
quand vous voulez de la performance, ne pas utiliser le lecteur de flux ou en ligne à base de méthodes de lecture. Ils sont lents. Juste utiliser les binaires de la mémoire tampon et de la recherche de '\n' pour identifier une ligne, et (de préférence) faire en place de l'analyse dans le tampon sans la création d'une chaîne de caractères. Sinon, le garbage collector ne sera pas si heureux avec cela.
Vous pouvez analyser l'ensemble du fichier à la fois et l'insérer l'ensemble du json dans mongo document, d'Éviter des boucles multiples, Vous avez besoin de séparer la logique comme suit:
1)Analyser le fichier et de récupérer l'Objet json.
2)une Fois que l'analyse est terminée, enregistrez l'Objet json dans le Mongo Document.
J'ai un peu plus rapide (je suis aussi de l'insertion des millions à l'heure actuelle), insérer des collections au lieu de simples documents avec
http://api.mongodb.org/java/current/com/mongodb/DBCollection.html#insert(java.util.Liste)
Cela dit, ce n'est pas beaucoup plus rapide. Je suis sur le point d'expérimenter avec réglage d'autres WriteConcerns qu'on ne le pense (surtout sans accusé de réception) pour voir si je peux accélérer plus rapidement. Voir http://docs.mongodb.org/manual/core/write-concern/ pour info
Une autre façon d'améliorer les performances, est de créer des index en vrac après l'insertion. Cependant, c'est rarement une option, sauf pour l'un des emplois.
Excuses si c'est légèrement laineux sondage, j'en suis encore à tester des choses moi-même. Bonne question.
Utilisation des opérations en bloc insérer/upserts. Après
Mongo 2.6
vous pouvez le faire en Vrac Mises À Jour/Upserts. Exemple ci-dessous est mise à jour en bloc à l'aide dec#
pilote.Vous pouvez également supprimer tous les index (sauf pour le PK de l'index, bien sûr) et de les reconstruire après l'importation.
Vous pouvez utiliser un bloc d'insertion
Vous pouvez lire la documentation à mongo site web et vous pouvez également consulter ce exemple java sur StackOverflow