Générer des ID unique en Java, à l'étiquette des groupes d'entrées dans un journal
Il y a plusieurs posts sur DONC sur ce sujet. Chacun de ces parler d'une approche spécifique de sorte voulais juste prendre une comparaison dans une question.
À l'aide de new Date() comme identifiant unique
Générer un identificateur global unique en Java
Je suis en train d'implémenter une fonctionnalité où nous sommes en mesure d'identifier certains événements dans le fichier journal. Ces événements doivent être associées à un identifiant unique.
Je suis en train d'essayer de trouver une stratégie pour cette unique ID de génération.
L'ID est d'avoir 2 parties :
des informations statiques + dynamiques de l'information
Les journaux peuvent être recherchés pour le motif lors du débogage des événements est nécessaire.
J'ai trois façons :
- statique info + Joda Date heure("abc"+2014-01-30T12:36:12.703)
- statique info + Atomique Entier
- statique info + UUID
Pour la portée de cette question, plusieurs Jvm n'est pas une considération.
J'ai besoin de générer des Identifiants uniques d'une façon efficace, sur un JVM. Aussi, je ne vais pas être en mesure d'utiliser une base de données dépendante de la solution.
Laquelle des 3 stratégies mentionnées ci-dessus fonctionne le mieux ?
- Si ce n'est celui de la ci-dessus, toute autre stratégie ?
- Est le Joda du temps en fonction de la stratégie robuste ? La JVM est unique mais il y aura d'utilisateurs simultanés de sorte qu'il peut être concomitante des événements.
- En conjonction avec l'un des/d'autres stratégies, Dois-je faire de ma méthode thread-safe /synchronisées ?
- Définir les œuvres de meilleur".
- "qui fonctionne le mieux" : j'ai besoin de générer des Identifiants uniques d'une façon efficace, sur un JVM
- Jetez un oeil à UUID.randomUUID().
- Merci, mais comment cela se compare avec la Joda time?
- C'est pourquoi j'ai laissé ce qu'un commentaire, car il ne répond pas entièrement à votre question. Juste un conseil.
- UUID.randomUUID() est une méthode synchronisée et ne fonctionne pas correctement sous haute lice. La création de Joda objets pour chaque identificateur apparaît plutôt inutiles aussi. J'avais utilisation du Système.currentTimeMillis() ou nanoTime() + atomique compteur.
- Dites que vous voulez lier ensemble plusieurs entrées dans un journal? Les entrées peuvent être entrelacées avec d'autres sans rapport avec les entrées, de sorte que vous voulez être en mesure de requête uniquement pour les entrées connexes – c'est que votre question?
- Avez-vous des numéros de citer? Moderne Jvm, une méthode synchronisée n'est pas cher. Il est difficile d'imaginer que, dans le contexte de l'enregistrement de l'OP serait de générer suffisamment de Uuid de faire tout impact sur les performances du monde réel. Mon test: Une boucle d'un million d'appels à
java.util.UUID.randomUUID()
dans Java 8 bêta 127 de Netbeans 7.4 cours d'exécution à l'intérieur d'une Parallels 9 machine virtuelle sous Mountain Lion sur un Mac mini (Intel i7) l'exécution de Mavericks. Résultats: 2 millisecondes par UUID. Accordée, qui est sans prétention, mais néanmoins, je dirais que votre préoccupation est de "l'optimisation prématurée". - Merci pour vos contributions. Pas sûr de ce que "lier ensemble" signifie. Pour simplifier : Un événement, générer un & journal d'un id liée à cet évènement, de le rechercher à l'aide de l'identifiant généré. Espérons qu'il soit clair
- Si vous avez une seule entrée que vous devez rechercher dans votre journal, claque un UUID sur l'entrée et vous avez terminé. Mais votre question me semble être plus que cela. Voulez-vous dire quelque chose comme Susan (ou Thread 'A') est en cours d'exécution du code qui permet de faire plusieurs entrées de journal, et Bob (ou le Fil "B") est en cours d'exécution de ce même code, et étant donné que les entrées de journal regarder de prêter à confusion, comme vous voulez être en mesure de trouver la collection de Susan entrées à partir d'une seule exécution de code tout en ignorant Bob entrées?
- Susan et Bob, les deux sont simultanément l'accès à l'application. Dans le cadre de leur travail, les événements ont été soulevées et connecté. J'ai besoin d'être en mesure de distinguer les événements qui sont liés à Susan/Bob . Et donc j'ai un mécanisme en place pour le faire, juste besoin de s'assurer que l'enregistrement de la partie les utilisations distinctes id. UUID semble correspondre au projet de loi.
- Concernant mon commentaire ci-dessus sur l'évaluation de la vitesse de génération des Uuid mentionné ci-dessus, reportez-vous à cette autre réponse que la mienne pour plus d'informations sur ce test ainsi qu'une extension du test de contention où 3 fils tout à la fois de générer des millions d'Uuid. Conclusion: la Discorde ne fait pas de monde réel impact sur les performances.
- Je vais regarder le lien. Aussi, je serais certainement en valeur vos entrées sur mon commentaire à la réponse de Msf
- Eh bien, si tel est le cas, alors la question est "l'optimisation prématurée". Nous créons aussi des Id de corrélation pour la journalisation. Cela ne signifie pas que tous les ID seront consignées. Nous de traiter simultanément >10'000 événements par seconde et la randomUUID() a été un goulot d'étranglement pour nous (2ms est-âge, vraiment). Découvrez ce article et d'autres LMAX/perturbateur articles connexes de trouver des chiffres sur le coût de verrouillage, avec et sans prétention.
- Bon, maintenant, je vois votre point de vue. Sur une échelle de 10 000 événements par seconde, ces préoccupations peuvent être justifiée. C'est au-delà de l'expérience de moi et de mes collègues (en interne départements d'une entreprise ou de niche de sites web).
Vous devez vous connecter pour publier un commentaire.
J'ai eu le même besoin que toi, distinguer un fil d'entrées connexes entrelacé avec d'autres indépendants des entrées dans un journal. J'ai essayé tous les trois de vos suggestions d'approches. Mon expérience a été dans 4D pas Java, mais similaire.
Date-Heure
Dans mon cas, j'ai été en utilisant une date de valeur en temps résolu à l'ensemble de secondes. C'est tout simplement trop grande granularité. J'ai facilement eu de collisions où plusieurs événements ont commencé dans la même seconde. Merde ces rapide des ordinateurs!
Dans votre cas, soit avec le logiciel java.util.Date ou Joda-Time (fortement recommandé pour d'autres fins), à la fois résoudre à quelques millisecondes. Un millième de seconde, c'est long dans les ordinateurs modernes, donc je ne le recommande pas.
Dans Java 8, la nouvelle java.temps.* package (inspiré par Joda-Temps, défini par JSR 310) résoudre à nanosecondes. Cela peut sembler être une meilleure identifiant, mais non. Pour une chose, physique de votre ordinateur maintien de l'heure de l'horloge peut pas soutenir une telle résolution fine. Un autre est que les ordinateurs toujours plus vite. Enfin, l'horloge de l'ordinateur peut être remis à zéro, en effet, il est réinitialiser souvent que les horloges des ordinateurs dérive un peu. De nouveaux Systèmes d'exploitation réinitialiser les horloges par vérifier fréquemment avec un serveur de temps localement ou sur les Internets.
Aussi, les journaux ont déjà un horodatage, de sorte que nous ne sommes pas d'avoir un quelconque avantage supplémentaire en utilisant une date-heure que notre identificateur. En effet, avoir un deuxième date-heure dans l'entrée de journal peut effectivement causer de la confusion.
Numéro De Série
Par "Atomique Entier", je suppose que vous voulez dire un numéro de série de l'incrémentation de plus en plus.
Cela semble exagéré pour votre but.
Donc cette approche ajoute le risque sans l'ajout d'aucun avantage particulier.
UUID
Bingo! Juste ce dont vous avez besoin.
Un UUID est facilement généré, à l'aide du logiciel java.util.L'UUID de la classe de capacité à générer de la Version 3 ou 4 Uuid, ou à l'aide d'une bibliothèque tierce, ou de l'accès à la ligne de commande du
uuidgen
outil.Pour un volume très élevé, [Version 1] UUID (MAC + date-heure + nombre aléatoire) serait un plus. Pour l'enregistrement, un La Version 4 UUID (aléatoire) est tout à fait acceptable.
Avoir une collision n'est pas une préoccupation réaliste. Surtout pour le nombre limité de valeurs que vous être en train de générer des logs. Je suis étonné par les gens qui, à défaut de comprendre les chiffres, dire qu'ils ne pourraient jamais remplacer une séquence avec un UUID. Encore une fois pressé, chaque programmeur et sysadmin je sais qu'elle a subi des échecs avec au moins une séquence.
Pas de préoccupations au sujet de thread-safety. Pas de préoccupations au sujet de la querelle (voir mes résultats de test sur une autre réponse de la mine).
Un autre avantage d'un UUID est qu'à son habitude hexadécimal représentation, tels que:
...est facilement reconnaissable. Lorsqu'ils sont reconnus, le lecteur sait immédiatement que la chaîne est destinée à être un identifiant unique. Donc, c'est la présence dans votre journal est l'auto-documentation.
J'ai trouvé Uuid à la Ruban adhésif de l'informatique. Je continue de trouver de nouvelles utilisations pour eux.
Donc, au début du code en question, de générer un UUID et puis l'incorporer dans chacune des entrées de journal.
Alors que la chaîne hexadécimale de la représentation d'un UUID est dur à lire et à écrire, dans la pratique, vous avez besoin seulement de numériser quelques-uns des chiffres au début ou à la fin. Ou utiliser le copier-coller avec la recherche et les fonctions de filtre en nos temps modernes, outils de la console.
Quelques petits faits
MDC Mappée dans un Contexte Diagnostique
Je n'ai pas encore utilisé MDC, mais que vous voulez le montrer...
L'abattage des cadres en ajoutant la prise en charge de cette idée d'étiquetage liées à des entrées de journal. Un tel soutien est appelé Mappé Contexte Diagnostique (MDC). Le MDC gère de l'information contextuelle sur un par thread.
Une rapide introduction de l'article est Log4j MDC (Mappé Contexte Diagnostique) : Quoi et Pourquoi .
Le meilleur de la journalisation de la façade, SLF4J, offre un multiécran. La meilleure mise en œuvre de cette façade, Logback, a un chapitre documente son multiécran.
Ordinateurs sont rapides, en utilisant le temps de tentative pour créer une valeur unique est voué à l'échec.
Au lieu d'utiliser un UUID.
À partir de la JSE 6.0 UUID API page
"[UUID est] une classe qui représente Un immuable identificateur unique universel (UUID)."
Voici un code:
J'ai écrit un service simple qui peut générer des semi-unique non-séquentielle 64 bits des numéros longs. Il peut être déployé sur plusieurs machines pour la redondance et l'évolutivité. C'utilisation ZeroMQ pour la messagerie. Pour plus d'informations sur la façon dont il fonctionne regarder github page: zUID