Traitement parallèle MapReduce
Principe
MapReduce découpe un traitement long en petites tâches indépendantes. Dodock exécute ces tâches en arrière-plan, plusieurs à la fois, puis combine leurs résultats en un résultat final. Cette fonction existe dans la version next de Dodock.
Un traitement MapReduce a trois éléments :
- Les données : une liste d'éléments indépendants, par exemple des noms de documents.
- La fonction de map : traite un élément et renvoie un résultat partiel.
- La fonction de reduce : ajoute un résultat partiel au résultat final.
Dodock crée un document MapReduce Job pour le traitement et un document MapReduce Task par élément de la liste.
Lancer un traitement
from frappe.utils.background_jobs import mapreduce
mapreduce(
map_method,
reduce_method,
callback_method,
data,
document_type,
document_name,
job_name,
)
| Paramètre | Rôle |
|---|---|
map_method | Chemin pointé de la fonction de map, par exemple mon_app.calculs.map_ligne |
reduce_method | Chemin pointé de la fonction de reduce |
callback_method | Chemin pointé de la fonction appelée à la fin, ou None |
data | Liste Python des éléments à traiter. Elle ne peut pas être vide |
document_type, document_name | Document lié au traitement, ou None. Dodock les passe au callback |
job_name | Nom libre du traitement |
Tous les paramètres sont obligatoires. Passez None pour ceux que vous n'utilisez pas.
La fonction crée et valide le document MapReduce Job, puis le renvoie. Les tâches partent en arrière-plan : la fonction ne renvoie pas le résultat.
Écrire les fonctions
- La fonction de map reçoit un élément de la liste. Elle renvoie un résultat partiel sérialisable en JSON.
- La fonction de reduce reçoit le résultat final en cours, puis le résultat partiel. Elle renvoie le nouveau résultat final. Au premier appel, le résultat final vaut
None. - Le callback reçoit le résultat final. Si
document_typeetdocument_namesont renseignés, il les reçoit aussi.
Exemple : somme d'une liste de nombres
# mon_app/calculs.py
import frappe
from frappe.utils.background_jobs import mapreduce
def map_nombre(item):
return item
def reduce_somme(final, partiel):
return (final or 0) + partiel
def fin_somme(resultat):
frappe.logger().info(f"Somme calculée : {resultat}")
def lancer():
return mapreduce(
"mon_app.calculs.map_nombre",
"mon_app.calculs.reduce_somme",
"mon_app.calculs.fin_somme",
[2, 6, 1, 87],
None,
None,
"Somme de test",
)
À la fin, le champ result du MapReduce Job contient 96.
Suivre l'exécution
Le formulaire du MapReduce Job affiche une barre de progression : la part des tâches terminées. Chaque MapReduce Task a un statut :
| Statut | Signification |
|---|---|
En file d'attente (Queued) | La tâche attend un worker |
En cours (Running) | Un worker exécute la tâche |
En pause (Paused) | Le traitement est suspendu |
Terminé (Completed) | La tâche est finie et son résultat est ajouté |
Annulé (Canceled) | Le MapReduce Job a été annulé |
Dodock lance d'abord 4 tâches, puis une nouvelle tâche à chaque tâche terminée.
Suspendre, reprendre, relancer
Le formulaire d'un MapReduce Job validé et pas encore fini propose ces boutons :
- Pause : passe les tâches en file d'attente au statut
Paused. - Resume : remet les tâches en pause en file d'attente.
- Actions > Forcer la réessayer : remet en file d'attente les tâches au statut
Running, par exemple après un redémarrage du serveur.
Annuler le MapReduce Job passe les tâches en attente ou en pause au statut Canceled. Dodock supprime les MapReduce Job de plus de 30 jours avec le nettoyage des journaux.
Exemples d'usage
| Cas d'usage | Map | Reduce |
|---|---|---|
| Génération de PDF en masse | Génère le PDF d'une facture et renvoie le nom du fichier | Ajoute le nom à une liste |
| Nettoyage de données | Renvoie les doublons d'une période | Fusionne les listes |
| Contrôle d'un import | Contrôle une ligne et renvoie {"ok": 1} ou {"erreur": 1} | Additionne les compteurs |