Récemment, les deux applications ont été transformées et une série de problèmes s'est produite au cours du processus de lancement (dont une partie a été causée par le malentendu d'objectif))
Comprenons d'abord l'objectif:
Horodatage
Les 4 premiers chiffres sont un horodat Unix, une catégorie INT. Nous extraissons les 4 premiers chiffres de l'objectid dans l'exemple ci-dessus "4DF2DCEC", puis les installons en hexadécimal à décimal: "1307761900". Ce numéro est un horodatage. Afin de rendre l'effet plus évident, nous convertissons cet horodatage au format temporel auquel nous sommes habitués (exactement en secondes)
$ Date -d '1970-01-01 UTC 1307761900 SEC' -U
Samedi 11 juin 2011 03:11:40 UTC
Les 4 premiers octets cachent en fait l'heure de la création de documents, et l'horodatage est à l'avant du caractère, ce qui signifie que l'objectif sera à peu près trié par insertion, qui joue un grand rôle dans certains aspects, comme l'amélioration de l'efficacité de recherche comme un index, etc. Un autre avantage de l'objet. Cela répond également à la réalité que lorsque nous créons plusieurs objets de manière rapide et continue, nous constaterons que les premiers chiffres trouvent rarement des changements, car ils utilisent l'heure actuelle. De nombreux utilisateurs craignent de synchroniser le temps du serveur. En fait, la véritable valeur de cet horodatage n'est pas importante, tant qu'elle augmente constamment.
Machine
Les trois octets suivants sont 2CDCD2. Ces trois octets sont les identificateurs uniques de l'hôte où ils se trouvent, et sont généralement la valeur de hachage du nom de l'hôte de la machine. Cela garantit que différents hôtes génèrent différentes valeurs de hachage machine et garantissent qu'il n'y a pas de conflit dans la distribution. C'est pourquoi les chaînes dans l'objectif généré par la même machine sont exactement les mêmes.
piquer
La machine ci-dessus est de s'assurer que les objets générés sur différentes machines ne sont pas en conflit, tandis que le PID consiste à générer des objets qui ne sont pas en conflit dans différents processus MongoDB sur la même machine. Les deux bits suivants de 0936 sont les identificateurs de processus qui génèrent des objets.
Incrément
Les neuf premiers octets garantissent que les objets générés par différentes machines et processus en une seconde ne sont pas en conflit. Les trois octets suivants A8B817 sont un compteur automatiquement augmenté pour garantir que les objets générés dans la même seconde ne trouvent pas de conflits, ce qui permet de 256 à 3e puissance égale à l'unicité des enregistrements 16777216.
Unicité objectif
Vous pouvez penser que dans une certaine mesure, il peut être garanti d'être unique, que ce soit sur le client ou sur le serveur.
Idé conception 1. L'ordre de document est-il conforme à l'ordre d'insertion?
Situation filetée unique
L'horodatage, la machine, le PID et l'inc dans ObjectId peuvent être garantis pour être uniques car sur la même machine et le même processus.
Il y a un problème ici, les opérations MongoDB sont multipliées. A, B, C ... Lorsque plusieurs threads effectuent des opérations en magasin, il n'est pas garanti qui peut être avant l'autre, il sera donc en panne.
Situation multithread, multi-machine ou multi-processus
Regardons le mâché et le pid dans ObjectId qui ne peut être garanti pour être unique. Ensuite, les données seront encore plus hors service.
Solution:
Étant donné que les données de la collection ne sont pas ordonnées (y compris la collecte plafonnée), le moyen le plus simple est de trier l'objectif.
Il y a deux façons de trier,
1. Déclaration de requête MongoDB
jQuery Query = new query (); if (id! = null) {jQuery.Addcriteria (critères.where ("_ id"). gt (id)); } jQuery.with (new sort (tri.direction.asc, "_id"));2.java.util.priorityqueue
Comparator <DBObObject> Comparator = new Comparator <DBObject> () {@Override public int compare (dbObject O1, dbObject o2) {return ((objectId) o1.get ("_ id")). Compareto ((ObjectId) o2.get ("_ id")); }}; PriorityQueue <dbObject> file d'attente = new priorityQueue <dbObject> (200, comparateur);Idé conception 2: Lorsque plusieurs clients ont une concurrence élevée, la commande peut-elle être garantie (après le tri)?
Si vous vous assurez toujours que l'écriture est beaucoup plus grande que la lecture (plus d'une seconde intervalle), cela ne se produira jamais hors service.
Jetons un coup d'œil à l'exemple suivant
Voir maintenant le chiffre, retirez les données deux fois
d'abord
4DF2DCEC AAAA FFFF 36A8B813
4DF2DCEC AAAA EEEE 36A8B813
4DF2DCEC BBBB 1111 36A8B814
La deuxième fois
4DF2DCEC BBBB 1111 36A8B813
4DF2DCEC AAAA FFFF 36A8B814
4DF2DCEC AAAA EEEE 36A8B814
Maintenant, si vous prenez la première valeur maximale (4DF2DCEC BBBB 1111 36A8B814) pour faire le résultat de la requête suivante, il sera manqué
Les trois éléments de la deuxième fois, car (4DF2DCEC BBBB 1111 36A8B814) sont supérieurs à tous les enregistrements pris pour la deuxième fois.
Cela entraînera une perte de données.
Solution:
Étant donné que l'obstacle d'objectid est coupé en secondes, les quatre premiers chiffres du comptoir sont les numéros de machine et de processus.
1. Processus enregistre avant un certain intervalle de temps (plus d'une seconde), de sorte que même si les numéros de machine et de processus provoquent un trouble, il n'y aura pas de trouble avant l'intervalle.
2. L'insertion d'un seul point, l'opération d'insertion qui a été à l'origine distribuée à plusieurs points, est désormais interrogée d'un point pour s'assurer que la machine et le numéro de processus sont les mêmes, et l'opérateur de contre-opérateur est utilisé pour rendre les enregistrements ordonnés.
Ici, nous avons utilisé la première méthode.
Misonctant 3. Ne définissez pas dbObject_id à l'aide de MongoDB pour définir ObjectId?
Pendant l'opération d'insertion MongoDB, lorsque le nouveau dbbasicObject (), tout le monde voit que _id n'est pas rempli, à moins que _id ne soit réglé manuellement. Alors est-il configuré sur le serveur?
Jetons un coup d'œil au code de l'opération d'insertion:
Classe d'implémentation
Insert des écrivains publics (List <DBObject> List, com.mongodb.writeConcern Concern, Dbencoder Encoder) {if (Concern == null) {Throw New illégalArgumentException ("Write Concern ne peut pas être nul"); } return insert (list, true, inquiétude, encodeur); }Vous pouvez voir que vous devez ajouter, la valeur par défaut est d'ajouter
Insert des écrivains protégés (Liste <dbObject> List, Boolean devrait appliquer, com.mongodb.writeConcern Concern, dbencoder Encoder) {if (Encoder == null) Encoder = defaultDBencoder.Factory.Create (); if (willTrace ()) {for (dbObject o: list) {trace ("Save:" + _fullNamespace + "" + json.serialize (o)); }} if (devraientapply) {for (dbObject o: list) {appliquer (o); _CheckObject (o, false, false); Objet id = o.get ("_ id"); if (id instanceof ObjectId) {((objectId) id) .notNew (); }}} WriterSult Last = null; int cur = 0; int maxsize = _mongo.getMaxBSonObjectSize (); while (cur <list.size ()) {outMessage om = outMessage.insert (this, Encoder, Concern); for (; cur <list.size (); cur ++) {dbObject o = list.get (cur); om.putObject (o); // limite pour l'insert par lots est 4 x maxbson sur le serveur, utilisez 2 x pour être sûr if (om.size ()> 2 * maxSize) {cur ++; casser; }} dernier = _Connector.say (_db, om, préoccupation); } return dernier; }Ajouter automatiquement les opérations objetId
/ ** * appelle {@link dbCollection # appliquer (com.mongodb.dbObject, boolean)} avec assureId = true * @param o <code> dbObject </code> auquel pour ajouter des champs * @return l'objet de paramètre modifié * / Objet public appliquer (dbobject o) {return appliquer (o, o, true); } / ** * Appels {@Link dbCollection # Doapply (com.mongodb.dbObject)}, ajoutant éventuellement un champ _ID automatique * @param jo objet pour ajouter des champs à * @param assurez-vous d'ajouter un <code> _id </ code> Field * @return l'objet modifié <code> id = Jo.get ("_id"); if (assureId && id == null) {id = objectId.get (); jo.put ("_id", id); } doApply (Jo); Retour ID; }Comme vous pouvez le voir, ObjectId sera automatiquement ajouté au package MongoDB Driver.
La méthode de sauvegarde
Public WriterSult Save (dbObject Jo, writeConcern Concern) {if (checkReadonly (true)) renvoie null; _CheckObject (Jo, false, false); Object id = jo.get ("_id"); if (id == null || (id instanceof ObjectId && ((objectId) id) .isnew ())) {if (id! = null && id instanceOf ObjectId) ((objectId) id) .NotNew (); if (préoccupation == null) Retour insert (jo); Else Return Insert (Jo, Concern); } DbObject q = new BasicDbObject (); q.put ("_id", id); if (Concern == null) return update (q, jo, true, false); else return update (q, jo, true, false, préoccupation); }Pour résumer, par défaut, ObjectId est généré par le client et non par le serveur sans définir.
Misonctant 4. peut-on trouver que laModify peut vraiment obtenir des variables d'automobile?
DbObject Update = new BasicDBObject ("$ inc", new BasicDBObject ("Counter", 1)); DbObject query = new BasicDBObject ("_ id", key); DbObject result = getMongotemplate (). GetCollection (collectionName) .FindAndModify (query, update); if (result == null) {dbObject doc = new BasicDbObject (); doc.put ("compteur", 1l); doc.put ("_ id", key); // insérer (CollectionName, Doc); getMongotemplate (). Save (doc, collectionName); retour 1L; } return (long) result.get ("compteur");L'obtention des variables de mise en œuvre automatique sera écrite à l'aide de cette méthode, mais nous le découvrirons après l'exécution.
FindAndModify Operation, Exécutez d'abord trouver puis exécuter Modifier, donc lorsque le résultat est nul, il doit être ajouté et renvoyé 0
Ce qui précède est les malentendus et une série de problèmes causés par ObjectId dans MongoDB que l'éditeur vous a présenté. J'espère que cela vous sera utile. Si vous avez des questions, veuillez me laisser un message et l'éditeur vous répondra à temps. Merci beaucoup pour votre soutien au site Web Wulin.com!