Jobs cycliques déportés

Problème

Une équipe applicative souhaite mettre en place un traitement cyclique avec une fréquence d’une minute. Ce type de demande se révèle complexe dans la mesure où elle ne s’inscrit pas dans le cadre de l’ordonnancement, c’est à dire le lancement du traitement en fonction de certains conditions et dépendances mais plutôt dans celui du traitement en boucle, habituellement géré par des des processus dédiés.

Cette différence entre planification et boucle est au coeur du problème car un traitement cyclique respecte, par définition, un cycle, dont l’action se renouvellera à une certaine fréquence.

Qu’est ce qu’un lancement à la minute ?

La vision de l’équipe applicative est celle du cycle de 1 minute, elle s’attend donc à 60 lancements par heure et construira son contrat de qualité de services sur cette base.

Une autre vision, plus simple et généralement admise, est la boucle avec un sleep de 60 secondes. Dans ce cas, on a un intervalle d’une minute entre 2 exécutions. Ces deux points de vue démontre qu’il est impératif d’être clair sur la définition du besoin et la façon de le prendre en charge par la production.

Qu’est ce qu’un job cyclique sur Autosys ?

La vision de l’exploitant Autosys est tout autre, en effet l’outil permet de planifier des traitements, dans cet exemple il s’agira de planifier un traitement toutes les minutes eb partant d’une heure pleine. Pour cela on indique 3 paramètres :
- start_times : les heures de départ
- start_mins : les minutes de départ pour chacune des heures (dans notre cas : 0,1,2,3..59)

et éventuellement
- run_window : plage horaire delancement
- max_run_alarm : alerter le pilotage si le traitement est trop long, bloquant ainsi les cycles suivants
- term_run_time : arret du traitement au bout d’un certain temps pour respecter les cycles

Fonctionnellement, on ne définit donc pas un cycle, mais seulement des heures de lancement. Chaque nouvelle heure est calculée à la fin de l’exécution. Si le temps de traitement est de moins d’une minute, Autosys doit pouvoir calculer le prochain lancement dans la minute suivante :

Que se passe t-il si le temps d’exécution est supérieur au cycle ?

Si le traitement dure un peu plus d’une minute, il sera lancé avec un cycle de retard et ne sera donc capable de ne lancer que 30 traitements par heure, ne respectant ainsi que 50% du contrat de services.

Un autre élément à prendre en compte est le temps de calcul des planifications qui peut prendre entre quelques secondes et plusieurs minutes.

Ce temps peut être du à différents paramètres :
- A l’architecture, par exemple le mode haute disponibilité pour les bases de données, dans ce cas la double écriture des évènements consomme du temps de calcul
- A l’utilisation, par exemple le nombre de lancements dans une même minute, généralement les traitements sont lancés à heure fixe, ce pic de lancement entraine des délais de calculs et donc de soumission plus important

Quel est l’impact en terme d’administration ?

Du point de vue de l’administrateur Autosys, deux élements importants doivent être pris en compte : le nombre d’évènements engendrés et les plages de maintenance.

Pour chaque lancement, Autosys génère les évènements suivants :
- STARTJOB pour indiquer l’heure de lancement
- STARTING lorsque le traitement est soumis
- RUNNING lorsqu’il est réellement exécuté
- SUCCESS/FAILURE/TERMINATED suivant respectivement la bonne fin, l’erreur ou le kill du traitement Eventuellement, et en fonction du paramétrage et de l’exécution :
- CHK_MAX_ALARM
- CHK_RUN_WINDOW
- ALARM

C’est un minimum de 4 évènements à traiter pour chacun des lancements, ce nombre pouvant être plus important suivant la mise en place. Un seul traitement cyclique à 1 minute consomme l’équivalent de 1440 traitements quotidiens, soit une petite production.

L’autre problème est l’obligation de disposer de plages de maintenance afin d’exécuter les actions d’administration courantes ou exceptionnelle que ce soit sur l’outil et ses composants (base de données, serveurs, système d’exploitation...). Le mode haute disponibilité permet de basculer sur une machine secondaire en cas de problème sur le serveur principal, mais ce mode ne doit être réservé qu’aux problèmes car même si cette bascule est effectuée avant l’opération, il faudra un arrêt de production pour remettre en place la haute disponibilité.

Ce temps doit être assez long pour effectuer les opérations suivantes :
- arrêt du serveur autosys
- synchronisation de la base de secours et de la base principale
- relance en mode haute disponibilité

Ces opérations peuvent être optimisées suivant la base de données et automatisées pour réduire le temps d’indisponibilité, on peut l’estimer à une dizaine de minutes pour des équipes maitrisant très bien le processus.

Tout arrêt de production nécessitant ensuite un minimum de vérification, il est conseillé de réserver une heure à ce type d’opération.

Quel est le temps minimal pour une reprise après incident ?

Précisons les actions à réaliser pour comprendre le temps d’arrêt.

La première opération à effectuer est de comparer les statuts des traitements dans la base de données avec ce qui est effectif sur les agents, cette opération se fait à travers le chase qui est un exécutable dont l’un des rôles est de vérifier la présence des PID de l’agent et du traitement sur les machines.

La synchronisation des bases de données ne garantit pas qu’il n’y aura pas de pertes d’évènements pendant l’opération, en effet pendant la durée de cette opération les traitements en exécution vont renvoyer leur statut à la base de données secondaire, or celle ci sera en train de copier ces évènements.

Déléguer une partie des cycles

Lorsque le traitement est critique et qu’il doit respecter la fréquence sans aucune interruption, il est obligatoire de déléguer une partie des cycles directement sur l’agent et ne conserver sur l’ordonnanceur que les lancements de périodes plus importantes. Suivant la qualité de services désirée et les contraintes de la production, on peut définir ces différents cycles comme suit :
- des cycles d’au moins une heure pour la partie ordonnanceur afin de bénéficier d’une plage d’intervention suffisant pour la maintenance courante. Si on considère que cette période est trop courte, on peut tout à fait l’augmenter, par exemple en estimant que 4heures est le temps minimal pour un patch de serveur ou une mise à jour logicielle (autosys ou base de données).
- des sous-cycles gérés directement dans une boucle de l’agent distant permettant de relancer périodiquement la commande mais devant rendre la main régulièrement à l’ordonnanceur. On notera que la fréquence peut alors être inférieure à la minute.

Comment continuer à suivre les exécutions ?

Pour satisfaire le contrat de service, il est impératif qu’Autosys puisse suivre l’exécution du traitement en surveillant le processus distant. L’une des méthodes est de lancer un chase régulièrement afin de vérifier la présence du traitement cyclique mais cette solution est peu efficace lorsque le chase doit tester de nombreux traitements.

Autosys propose une autre solution plus élégante et surtout moins coûteuse en ressources serveur car directement réalisée au niveau de l’agent : le heartbeat.

Ce mécanisme consiste à envoyer un kill -USR2 sur le PID de l’agent, cela a pour effet de mettre à jour la date du dernier « battement de coeur » de l’agent dans la base de données Autosys et d’avoir ainsi l’assurance que le traitement est toujours en cours.

Les heartbeats sont affichés dans le détail des jobs par un autorep :

autorep -J JOB -d
...
[HEARTBEAT]     04/02/2009  01:35:56   1  PD  04/02/2009 01:35:58
MACHINE_DISTANTE
...

Comment configurer Autosys pour prendre en compte les heartbeats ?

Si vous souhaitez intégrer ce type de job sur votre ordonnanceur, il est préférable de configurer Autosys pour prendre en charge l’évènement heartbeat, cette configuration n’est pas le sujet de l’article, je l’indique donc succinctement :

- Au niveau de la configuration du serveur, il faut indiquer le nombre la fréquence en minutes entre 2 vérifications par le serveur, par exemple, pour une vérifications toutes les 5 minutes :

# Check job heartbeat every 5 minutes.
Check_Heartbeat=5

- Au niveau du job, on indique le délai maximum du heartbeat renvoyé par l’agent. A ajouter dans le jil (en minutes) : heartbeat_interval: 2

- Au niveau du script, il est nécessaire d’envoyer les informations régulièrement à l’agent par le kill indiqué précédemment. On peut envoyer un kill toutes les minutes dans une boucle, ce type d’évènements n’est pas trop consommateur au niveau de la base de données car il ne demande pas de traitement par trigger mais seulement par le polling indiqué par le check_heartbeat.

Le fonctionnement à troix niveaux est le suivant :
- le job envoi un kill toutes les minutes à l’agent
- l’agent inscrit la date et l’heure du heartbeat dans la base de données
- le serveur vérifie toutes les 5 minutes (check_heartbeat) le dernier heartbeat pour les jobs ayant indiqué le heartbeat_interval dans leur définition
- si le nombre de minutes entre l’heure courante et le dernier heartbeat est supérieur à la valeur du heartbeat_interval, le serveur envoi une alarme.

Exemple de script

Un exmple de script générique en perl.

#!/usr/bin/perl

$freq = 60;
$freq2 = 5;
$maxruntime = 30;
$heartbeat = 20;

# Début du cycle primaire
$start = time;
print timestamp('START',$start);

# Fin du cycle primaire
$end = $start + $freq;
print timestamp('END',$end);

# Prochain heartbeat
$beat = $start+$heartbeat;
print timestamp('BEAT',$beat);

$n = 0;
do {
    print "================\n";
    print timestamp('NOW',time);
    # Prochain depart
    $n++;
    $next = $start + $freq2*$n;

    print timestamp('NEXT',$next);

    # Heartbeat
    if ($t>$heart) {
          $kill = `kill -USR2 $!`;
          print "\t\tHeartbeat :\t$kill\n";

          # prochain heartbeat
          print timestamp('BEAT',$heartbeat);
          $heart = $t+$heartbeat;
    }

    $cmd = 'sleep '.int(rand($maxruntime));
    print "\t\trun number :\t$n\n";
    print "\t\tcommand :\t$cmd";
    $command = `$cmd`;
    print "\t$command\n";

    print "----------------\n";
    $t = time;
    print timestamp('NOW',$t);

    # Attente ?
    $wait = $next-$t;
    if ($wait>0) {
          print "\t\tWait :\t$waits\n";
          sleep $wait;
    }
    else {
          print "\t\tStart\n";
          # Recalage : on calcule si des cycles on ete rates
          $r = int(($t - $next)/$freq2);
          print "\t\tMissing run(s) :\t$r\n"
                if ($r>0);
          $n += $r;
    }

} while ($t<$end);
print "================\n";
print timestamp('END',$t);
print "\tDelay :\t".($t-$end)."s\n";

sub timestamp {
my($text,$time) = @_;

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time);
return sprintf("%s\t%02d:%02d:%02d\n",$text,$hour,$min,$sec);
}

Conclusion

Le principe des jobs cycliques déportés peut être appliquer à n’importe quel type d’ordonnanceur. Il est ensuite nécessaire de connaître les fonctionnalités de l’outil pour une meilleure intégration. Dans le cas d’Autosys, les options utilisées sont nécessaires pour compenser le fait que l’agent est en mode déconnecté.

Article

> Ordonnanceurs > Les incontournables > Autosys > Développement

Cet article est l’un des premiers de la série "Cas pratique", cette série concerne des sujets traités chez nos clients mais qui peuvent servir sur d’autres sites. Ils sont représentatifs des problématiques que l’on peut rencontrer en ordonnancement.

Le problème des jobs cycliques est un classique car même si ils sont minoritaires en terme de type de jobs, ils peuvent représenter un volume important en exécutions. Si la période entre 2 lancement est basse, de l’ordre d’une à quelques minutes, on se retrouve confronter à deux problèmes :
- Comment intervenir sur mon infrastructure sans stopper la production ?
- Comment ne pas dégrader les performances de mon ordonnanceur ?

Mise à jour :20 juin 2009
Visites : 3003
Auteur : E. Angenault
Site : Angenault.net

Liens commerciaux

Accès rapide

La série "Cas pratique" regroupe des articles sur les études et implémentations mises en place chez nos clients.

Open Source Scheduler en tant qu’agent distant
Cet article présente une architecture "agentless" avec un agent open source. Le terme d’agentless signifiant que l’agent n’est pas un agent de l’éditeur. La solution habituellement préconisée repose sur une commande distante (...)

Autosys

Anciennement Platinum, Autosys est l’ordonnanceur de CA (anciennement Computer Associates).