11
votes

Comment gérer gracieusement des milliers de ratés de quartz?

Nous avons une application qui doit

  1. Retraite tous les soirs de grandes quantités de données et

  2. Retraite de grandes quantités de données à la demande.

    Dans ces deux cas, environ 10 000 emplois de quartz se sont engendrés, puis exécutent. Dans le cas de la nuit, nous avons un quartz Cron JOB qui espionne les 10 000 emplois qui effectuent chacun individuellement le travail de traitement des données.

    La question que nous avons est que nous courions avec environ 30 threads, donc naturellement, les emplois à quartz se moquent et continuent de se rendre à la campagne jusqu'à ce que tout soit traité. Le traitement peut prendre jusqu'à 6 heures. Chacun de ces 10 000 emplois concerne un objet de domaine spécifique pouvant traiter en parallèle et totalement indépendant. Chacun des 10 000 emplois peut prendre une durée variable (d'une demi-seconde à une minute).

    Ma question est la suivante:

    1. Y a-t-il une meilleure façon de le faire?

    2. Sinon, quelle est la meilleure façon pour nous de planifier / configurer nos emplois de quartz afin de passer une quantité minimale de temps passée et de traiter avec des ratés?

      Une note sur ou architecture: nous exécutons deux grappes avec trois nœuds chacun. La version de quartz est un peu ancienne (2.0.1) et la clustering est activée dans le fichier quartz.properties.


3 commentaires

Il n'y a pas de moyen de distribuer une charge de travail uniformément au cours de la journée? (E.G files d'attente)


Pour la nuit, nous pouvons le faire, mais pour la demande, il doit être exécuté le plus rapidement possible. Une de mes pensées était de résumer le nombre d'emplois de quartz à créer et de prendre le temps d'exécution moyen d'un seul thread, puis planifiez au hasard les travaux de quartz en conséquence, en comptant également le nombre de threads. Cela aiderait à atténuer légèrement les ratés, mais l'heure d'exécution d'un seul thread est trop variable et suppose toujours que le pire scénario prendrait trop de temps en cas de traitement sur demande.


Je pense que l'utilisation de quartz pour ce type de scénario est fausse, car tous les travaux que vous appartenez doivent exécuter immédiatement et non à une heure précise. Comme d'autres réponses suggèrent d'utiliser des files d'attente et un service exécuteur aurait le plus de sens ici.


4 Réponses :


2
votes

Le meilleur moyen est d'utiliser un groupe d'instances de quartz. Cela partagera les travaux entre de nombreux nœuds de cluster: http://quartz-scheder.org/documentation/quartz-2.x / Configuration / ConfigJDBCJobStoreclustering


1 commentaires

C'est en fait pas une bonne idée puisque Quartz devra faire beaucoup de retours ronds à la JDBCSTORE (= Base de données). Et comme l'option OP dans une édition - l'option de cluster est déjà utilisée.



4
votes

Je ferais cela en utilisant une file d'attente (rabbbitmq / activemq). Le travail cron (ou quel que soit votre déclencheur à la demande) remplit la file d'attente avec des messages représentant les 10 000 instructions de travail (c'est-à-dire l'instruction de retraitement des données pour un objet de domaine donné).

sur chacun de vos nœuds, vous disposez d'un bassin de exécuteurs qui tire de la file d'attente et effectuez l'instruction de travail. Cette solution signifie que chaque exécuteur est conservé aussi bien que possible, alors qu'il existe toujours des éléments de travail sur la file d'attente, ce qui signifie que le traitement global est accompli le plus rapidement possible.


0 commentaires

8
votes

Dans ces deux cas, environ 10 000 emplois de quartz se sont engendrés

pas besoin d'accéder à de nouveaux travaux de quartz. quartz est un planificateur - pas un gestionnaire de tâches.

dans la soirée de retraite - Vous n'avez besoin que de ce un quartz Code> Cron Job Pour invoquer un service responsable de la gestion et de la gestion des 10 000 tâches. Dans le scénario "à la demande", Quartz ne devrait pas être impliqué du tout . Il suffit d'invoquer ce service directement.

Comment le service gère-t-il 10 000 tâches?

typiquement, lorsque un seul JVM est disponible, vous n'utilisez que quelques-unes exécutorservice . Ici, puisque vous avez 6 nœuds sous vos doigts, vous pouvez facilement utiliser hazelcast . Hazelcast est une bibliothèque Java qui vous permet de regrouper vos nœuds, de partager des ressources efficacement les unes avec les autres. Hazelcast possède une solution simple distribuant votre exécutantservice , qui s'appelle Service exécutif distribué . C'est aussi simple que de créer un Hazelcast exécutorservice et Soumettre la tâche sur tous les membres . Voici un exemple de La documentation pour invoquer sur un seul membre: < / p> xxx


0 commentaires

0
votes

J'utiliserais un travail de quartz planifié pour initier les tâches 10K, mais elle le fait en ajoutant des détails de la tâche à une file d'attente JMS (10k messages). Cette file d'attente est surveillée par un fève à un message (Java-ee EJB MDB). Le MDB peut fonctionner simultanément sur plusieurs nœuds de votre cluster et chaque nœud peut exécuter plusieurs instances ... Ne réinventez pas la roue pour la charge de travail distribuée: Laissez Java-ee le faire.


0 commentaires