Le mode distribué exécute chaque itération d'un état Map sous forme d'exécution de sous-flux de travail indépendante, permettant un traitement parallèle à haute concurrence adapté au big data et au calcul parallèle.
Utilisez le mode distribué lorsqu'un seul état Map ne peut pas traiter votre charge de travail de manière séquentielle. Le mode distribué répartit la charge sur plusieurs exécutions de sous-flux de travail concurrentes — chacune avec son propre cycle de vie — et peut traiter en parallèle des données provenant d'une entrée intégrée ou de compartiments Object Storage Service (OSS).
Concepts clés
| Terme | Définition |
|---|---|
| Mode distribué | Mode de traitement des états Map qui traite simultanément de grandes quantités de données via des exécutions de sous-flux de travail. Les objets contenus dans les compartiments OSS peuvent servir de source de données. |
| Exécution de sous-flux de travail | Une seule itération d'un état Map distribué. La définition provient du champ Processor, et chaque sous-flux reçoit un élément (ou un lot) en entrée. Les sous-flux de travail peuvent s'exécuter en mode standard ou en mode express. Pour plus d'informations, consultez Mode standard et mode express. |
| Politique de tolérance aux pannes | Par défaut, si une exécution de sous-flux de travail échoue, l'état Map se termine par un échec. Pour les états Map contenant plusieurs éléments, vous pouvez configurer des politiques de tolérance aux pannes afin que l'état Map continue à traiter les éléments restants même si certaines exécutions de sous-flux échouent. |
Fonctionnement
L'état Map reçoit une entrée et extrait un tableau d'éléments à l'aide de
ItemsPath(ou lit les éléments depuis une source de données OSS en utilisantItemReader).Si
ItemConstructorest configuré, chaque élément est transformé.Si
ItemBatcherest configuré, les éléments sont regroupés en lots.Chaque élément ou lot est transmis à une exécution de sous-flux de travail définie par
Processoret s'exécute selon le mode spécifié parProcessorConfig.Une fois toutes les exécutions de sous-flux terminées, l'état Map collecte les résultats dans un tableau JSON (ou les écrit dans OSS à l'aide de
ResultWriter).
Lorsque ItemsPath, ItemConstructor et ItemBatcher sont tous configurés, ils s'exécutent dans cet ordre : ItemsPath, puis ItemConstructor, puis ItemBatcher.
Exemple de base
Le flux de travail suivant définit un état Map distribué qui lit les éléments depuis $Input.Items et traite chaque élément via un état Pass en mode Express :
Type: StateMachine
Name: MyWorkflow
SpecVersion: v1
StartAt: Map
States:
- Type: Map
Name: Map
ProcessorConfig:
ExecutionMode: Express
ItemsPath: $Input.Items
Processor:
StartAt: Pass
States:
- Type: Pass
Name: Pass
End: true
End: true
Entrée du flux de travail :
{
"Items": [
{"key_1":"value_1"},
{"key_2":"value_2"},
{"key_3":"value_3"}
]
}
Cela crée trois exécutions de sous-flux de travail, chacune exécutant la définition suivante :
Type: StateMachine
Name: Map
SpecVersion: v1
StartAt: Pass
States:
- Type: Pass
Name: Pass
End: true
Entrées des sous-flux de travail :
// Sub-workflow 1
{"key_1":"value_1"}
// Sub-workflow 2
{"key_2":"value_2"}
// Sub-workflow 3
{"key_3":"value_3"}
Une fois tous les sous-flux terminés, la sortie de l'état Map est un tableau JSON regroupant les sorties de tous les sous-flux :
{
"Items": [
{
"key_1": "value_1"
},
{
"key_2": "value_2"
},
{
"key_3": "value_3"
}
]
}
Référence des champs
Tous les champs disponibles dans un état Map en mode distribué :
| Champ | Type | Obligatoire | Description | Exemple |
|---|---|---|---|---|
| Name | string | Oui | Nom de l'état. | my-state-name |
| Description | string | Non | Description de l'état. | describe it here |
| Type | string | Oui | Type de l'état. | Map |
| InputConstructor | map[string]any | Non | Constructeur d'entrée. | Voir Entrées et sorties. |
| ItemsPath | string | Oui | Expression permettant d'extraire un tableau depuis l'entrée. | Voir ItemsPath. |
| ItemBatcher | ItemBatcher | Non | Regroupe plusieurs éléments en un lot servant d'entrée au sous-flux de travail. | Voir ItemBatcher. |
| ItemReader | ItemReader | Non | Lit les données depuis des compartiments OSS. | Voir ItemReader. |
| ItemConstructor | ItemConstructor | Non | Transforme les éléments en utilisant $Item pour référencer les valeurs d'entrée d'origine. |
Voir ItemConstructor. |
| ResultWriter | ResultWriter | Non | Écrit les résultats des sous-flux de travail dans un compartiment OSS spécifié. | Voir ResultWriter. |
| MaxConcuccency | int | Non | Nombre maximal d'exécutions de sous-flux de travail simultanées. | 40 |
| MaxItems | MaxItems | Non | Nombre maximal d'éléments traités par l'état Map. | Voir MaxItems. |
| ToleratedFailurePercentage | ToleratedFailurePercentage | Non | Pourcentage d'échecs de sous-flux de travail tolérés. | Voir ToleratedFailurePercentage. |
| ToleratedFailureCount | ToleratedFailureCount | Non | Nombre d'échecs de sous-flux de travail tolérés. | Voir ToleratedFailureCount. |
| Processor | Processor | Oui | Processeur Map définissant le sous-flux de travail. | Voir Processor. |
| ProcessorConfig | ProcessorConfig | Oui | Configuration du processeur. | Voir ProcessorConfig. |
| OutputConstructor | map[string]any | Non | Constructeur de sortie. | Voir OutputConstructor. |
| Next | string | Non | État suivant à exécuter une fois cet état terminé. Laissez vide si End est true. | my-next-state |
| End | bool | Non | Indique si cet état est l'état terminal de la portée actuelle. | true |
| Retry | Retry | Non | Politique de nouvelle tentative en cas d'erreur. | Voir Gestion des erreurs. |
| Catch | Catch | Non | Politique de capture d'erreurs. | Voir Gestion des erreurs. |
Détails des champs
ItemsPath
Extrait un tableau depuis l'entrée de l'état Map. Chaque élément du tableau devient l'entrée d'une exécution de sous-flux de travail. Référenciez les données avec les variables $Context ou $Input :
$Input.FieldA
Processor
Définit le sous-flux de travail qui traite chaque élément ou lot.
| Champ | Type | Obligatoire | Description | Exemple |
|---|---|---|---|---|
| States | array | Oui | États composant le sous-flux de travail. | Voir l'exemple ci-dessous. |
| StartAt | string | Oui | Premier état à exécuter. | my start task |
Processor:
StartAt: Pass1
States:
- Type: Pass
Name: Pass1
End: true
ProcessorConfig
Spécifie le mode d'exécution des sous-flux de travail.
| Champ | Type | Obligatoire | Description | Exemple |
|---|---|---|---|---|
| ExecutionMode | string | Oui | Mode d'exécution des sous-flux de travail. | Express |
ItemReader
Lit les données d'entrée depuis des compartiments OSS, ce qui permet de gérer des entrées de taille plus importante.
| Champ | Type | Obligatoire | Description | Exemple |
|---|---|---|---|---|
| SourceType | string | Oui | Type de source de données. Valeurs valides : OSS_CSV, OSS_JSON_LIST, OSS_OBJECTS, OSS_INVENTORY_FILES. |
OSS_CSV |
| SourceParameters | SourceParameters | Non | Paramètres de localisation de la source de données. | Voir SourceParameters. |
| ReaderConfig | ReaderConfig | Non | Configuration du lecteur. | Voir ReaderConfig. |
SourceParameters
| Champ | Type | Obligatoire | Description | Exemple |
|---|---|---|---|---|
| Bucket | string | Non | Nom du compartiment OSS. | example-bucket |
| ObjectName | string | Non | Nom de l'objet. | object_name_1 |
| Prefix | string | Non | Filtre de préfixe de nom d'objet. Si laissé vide, tous les objets correspondants sont renvoyés. | example-prefix |
ReaderConfig
| Champ | Type | Obligatoire | Description | Exemple |
|---|---|---|---|---|
| CSVHeaders | []string | Non | En-têtes de colonne de la première ligne du fichier CSV. | ColA,ColB,ColC |
Lire des fichiers CSV depuis OSS
Lisez les données depuis un fichier CSV stocké dans un compartiment OSS. Dans cet exemple, example-object.csv est stocké dans example-bucket :
Type: StateMachine
Name: MyWorkflow
SpecVersion: v1
StartAt: Map
States:
- Type: Map
Name: Map
ProcessorConfig:
ExecutionMode: Express
Processor:
StartAt: Pass
States:
- Type: Pass
Name: Pass
End: true
ItemReader:
SourceType: OSS_CSV
SourceParameters:
Bucket: example-bucket
ObjectName: example-object.csv
End: true
Contenu du fichier CSV :
ColA,ColB,ColC
col_a_1,col_b_1,col_c_1
Chaque ligne devient l'entrée du sous-flux de travail :
{
"ColA": "col_a_1",
"ColB": "col_b_1",
"ColC": "col_c_1"
}
Lire des tableaux JSON depuis OSS
Le fichier JSON doit contenir un tableau JSON.
Lisez un tableau JSON depuis example-object.json dans example-bucket :
Type: StateMachine
Name: MyWorkflow
SpecVersion: v1
StartAt: Map
States:
- Type: Map
Name: Map
ProcessorConfig:
ExecutionMode: Express
Processor:
StartAt: Pass
States:
- Type: Pass
Name: Pass
End: true
ItemReader:
SourceType: OSS_JSON_LIST
SourceParameters:
Bucket: example-bucket
ObjectName: example-object.json
End: true
Contenu du fichier JSON :
[
{
"key_1": "value_1"
}
]
Chaque élément devient l'entrée du sous-flux de travail :
{
"key_1": "value_1"
}
Lire des objets depuis OSS
Listez les objets possédant un préfixe spécifique et transmettez leurs métadonnées en tant qu'entrée du sous-flux de travail. Cet exemple lit les objets dont le préfixe est example-prefix depuis example-bucket :
Type: StateMachine
Name: MyWorkflow
SpecVersion: v1
StartAt: Map
States:
- Type: Map
Name: Map
ProcessorConfig:
ExecutionMode: Express
Processor:
StartAt: Pass
States:
- Type: Pass
Name: Pass
End: true
ItemReader:
SourceType: OSS_OBJECTS
SourceParameters:
Bucket: example-bucket
Prefix: example-prefix
End: true
Compte tenu de cette structure de compartiment :
example-bucket
└── example-prefix/object_1
Les métadonnées de chaque objet deviennent l'entrée du sous-flux de travail :
{
"XMLName": {
"Space": "",
"Local": "Contents"
},
"Key": "example-prefix/object_1",
"Type": "Normal",
"Size": 268435,
"ETag": "\"50B06D6680D86F04138HSN612EF5DEC6\"",
"Owner": {
"XMLName": {
"Space": "",
"Local": ""
},
"ID": "",
"DisplayName": ""
},
"LastModified": "2024-01-01T01:01:01Z",
"StorageClass": "Standard",
"RestoreInfo": ""
}
Lire des fichiers d'inventaire OSS
Lisez les éléments depuis un manifeste d'inventaire OSS. Cet exemple lit inventory/2024-01-01T01-01Z/manifest.json depuis example-bucket :
Type: StateMachine
Name: MyWorkflow
SpecVersion: v1
StartAt: Map
States:
- Type: Map
Name: Map
ProcessorConfig:
ExecutionMode: Express
Processor:
StartAt: Pass
States:
- Type: Pass
Name: Pass
End: true
ItemReader:
SourceType: OSS_INVENTORY_FILES
SourceParameters:
Bucket: example-bucket
ObjectName: inventory/2024-01-01T01-01Z/manifest.json
ItemConstructor:
Key.$: $Item.Key
End: true
Contenu du fichier d'inventaire :
"example-bucket","object_name_1"
"example-bucket","object_name_2"
Entrée du premier sous-flux de travail :
{
"Bucket": "example-bucket",
"Key": "object_name_1"
}
ItemBatcher
Regroupe plusieurs éléments en lots. Chaque lot devient l'entrée d'une unique exécution de sous-flux de travail.
| Champ | Type | Obligatoire | Description | Exemple |
|---|---|---|---|---|
| MaxItemsPerBatch | int | Non | Nombre maximal d'éléments par lot. | Voir exemple. |
| MaxInputBytesPerBatch | int | Non | Taille maximale en octets par lot. Unité : octet. | Voir exemple. |
| BatchInput | map[string]any | Non | Données supplémentaires à inclure dans l'entrée de chaque lot. | Voir exemple. |
Regrouper par nombre d'éléments
Définissez MaxItemsPerBatch pour contrôler le nombre d'éléments inclus dans chaque lot :
Type: StateMachine
Name: MyWorkflow
SpecVersion: v1
StartAt: Map
States:
- Type: Map
Name: Map
ProcessorConfig:
ExecutionMode: Express
ItemsPath: $Input.Items
Processor:
StartAt: Pass
States:
- Type: Pass
Name: Pass
End: true
ItemBatcher:
MaxItemsPerBatch: 2
End: true
Entrée du flux de travail :
{
"Items": [
{"key_1":"value_1"},
{"key_2":"value_2"},
{"key_3":"value_3"},
{"key_4":"value_4"},
{"key_5":"value_5"}
]
}
Cela génère trois exécutions de sous-flux de travail :
// Sub-workflow 1
{
"Items": [
{"key_1":"value_1"},
{"key_2":"value_2"}
]
}
// Sub-workflow 2
{
"Items": [
{"key_1":"value_3"},
{"key_2":"value_4"}
]
}
// Sub-workflow 3
{
"Items": [
{"key_1":"value_5"}
]
}
Regrouper par taille en octets
Définissez MaxInputBytesPerBatch pour limiter la taille de chaque lot en octets.
ItemBatcher ajoute des clés de métadonnées à chaque lot. La taille totale du lot inclut ces clés supplémentaires.
L'unité de
MaxInputBytesPerBatchest l'octet.
Type: StateMachine
Name: MyWorkflow
SpecVersion: v1
StartAt: Map
States:
- Type: Map
Name: Map
ProcessorConfig:
ExecutionMode: Express
ItemsPath: $Input.Items
Processor:
StartAt: Pass
States:
- Type: Pass
Name: Pass
End: true
ItemBatcher:
MaxInputBytesPerBatch: 50
End: true
Entrée du flux de travail :
{
"Items":[
{"Key":1},
{"key":2},
{"Key":3},
{"Key":4},
{"Key":5}
]
}
Cela génère trois exécutions de sous-flux de travail :
// Sub-workflow 1
{
"Items":[
{"Key":1},
{"key":2}
]
}
// Sub-workflow 2
{
"Items":[
{"Key":3},
{"key":4}
]
}
// Sub-workflow 3
{
"Items":[
{"Key":5}
]
}
Ajouter des données partagées aux lots
Utilisez BatchInput pour inclure des données supplémentaires issues de l'entrée du flux de travail dans chaque lot :
Type: StateMachine
Name: MyWorkflow
SpecVersion: v1
StartAt: Map
States:
- Type: Map
Name: Map
ProcessorConfig:
ExecutionMode: Express
ItemsPath: $Input.Items
Processor:
StartAt: Pass
States:
- Type: Pass
Name: Pass
End: true
ItemBatcher:
MaxInputBytesPerBatch: 70
BatchInput:
InputKey.$: $Input.Key
End: true
Entrée du flux de travail :
{
"Key":"value",
"Items":[
{"Key":1},
{"key":2},
{"Key":3},
{"Key":4},
{"Key":5}
]
}
Chaque sous-flux de travail reçoit à la fois les données BatchInput et les éléments regroupés :
// Sub-workflow 1
{
"BatchInput":{
"InputKey":"value"
},
"Items":[
{"Key":1},
{"key":2}
]
}
// Sub-workflow 2
{
"BatchInput":{
"InputKey":"value"
},
"Items":[
{"Key":3},
{"key":4}
]
}
// Sub-workflow 3
{
"BatchInput":{
"InputKey":"value"
},
"Items":[
{"Key":5}
]
}
ItemConstructor
Transforme chaque élément avant qu'il ne soit transmis à une exécution de sous-flux de travail. Utilisez $Item pour référencer l'élément d'origine et $Input pour référencer l'entrée du flux de travail :
Type: StateMachine
Name: MyWorkflow
SpecVersion: v1
StartAt: Map
States:
- Type: Map
Name: Map
ProcessorConfig:
ExecutionMode: Express
ItemsPath: $Input.Items
Processor:
StartAt: Pass
States:
- Type: Pass
Name: Pass
End: true
ItemBatcher:
MaxInputBytesPerBatch: 200
BatchInput:
InputKey.$: $Input.Key
ItemConstructor:
ConstructedKey.$: $Item.Key
InputKey.$: $Input.Key
End: true
Entrée du flux de travail :
{
"Key":"value",
"Items":[
{"Key":1},
{"Key":2},
{"Key":3},
{"Key":4},
{"Key":5}
]
}
Chaque élément est transformé par ItemConstructor avant le regroupement :
// Sub-workflow 1
{
"BatchInput": {
"InputKey": "value"
},
"Items": [
{
"InputKey": "value",
"ConstructedKey": 1
},
{
"InputKey": "value",
"ConstructedKey": 2
},
{
"InputKey": "value",
"ConstructedKey": 3
}
]
}
// Sub-workflow 2
{
"BatchInput": {
"InputKey": "value"
},
"Items": [
{
"InputKey": "value",
"ConstructedKey": 4
},
{
"InputKey": "value",
"ConstructedKey": 5
}
]
}
ResultWriter
Écrit les résultats des sous-flux de travail dans un compartiment OSS. Configurez ResultWriter lorsque la sortie combinée de toutes les exécutions de sous-flux risque de dépasser la limite de taille de sortie de l'état.
| Champ | Type | Obligatoire | Description | Exemple |
|---|---|---|---|---|
| Parameters | Parameters | Oui | Destination OSS pour les résultats. | Voir ci-dessous. |
Parameters
| Champ | Type | Obligatoire | Description | Exemple |
|---|---|---|---|---|
| Bucket | string | Oui | Compartiment OSS de destination. | example-bucket |
| Prefix | string | Oui | Préfixe de nom d'objet pour les fichiers de résultats. | example-prefix/ |
Les entrées et sorties des états ont des limites de taille. Pour les états Map comportant de nombreux éléments, la sortie combinée peut dépasser cette limite. Configurez ResultWriter pour stocker les résultats dans OSS à la place.
L'exemple suivant combine ResultWriter avec la tolérance aux pannes. L'état Map tolère jusqu'à 30 % d'échecs et écrit tous les résultats (succès et échecs) dans OSS :
Type: StateMachine
Name: MyWorkflow
SpecVersion: v1
StartAt: Map
States:
- Type: Map
Name: Map
ProcessorConfig:
ExecutionMode: Express
ItemsPath: $Input.Items
ItemConstructor:
Key.$: $Item.Key
FailedValue.$: $Input.FailedValue
ToleratedFailurePercentage: 30
Processor:
StartAt: Choice
States:
- Type: Choice
Name: Choice
Branches:
- Condition: $Input.Key > $Input.FailedValue
Next: Fail
Default: Succeed
- Type: Succeed
Name: Succeed
End: true
- Type: Fail
Name: Fail
Code: MockError
End: true
ResultWriter:
Parameters:
Bucket: example-bucket
Prefix: example-prefix/
End: true
Entrée du flux de travail :
{
"FailedValue": 4,
"Items": [
{"Key": 1},
{"Key": 2},
{"Key": 3},
{"Key": 4},
{"Key": 5}
]
}
Structure des fichiers de résultats
ResultWriter produit trois types de fichiers à l'emplacement OSS spécifié :
manifest.json (example-prefix/map-run-name/manifest.json) :
{
"DestinationBucket": "example-bucket",
"MapRunName": "map-run-name",
"ResultFiles": {
"FAILED": [
{
"ObjectName": "example-prefix/map-run-name/FAILED_0.json",
"Size": 262
}
],
"SUCCEED": [
{
"ObjectName": "example-prefix/map-run-name/SUCCEED_0.json",
"Size": 1057
}
]
}
}
FAILED_0.json (example-prefix/map-run-name/FAILED_0.json) :
[
{
"ExecutionName": "execution-name-5",
"FlowName": "example",
"Input": "{\"FailedValue\":4,\"Key\":5}",
"Output": "{\"ErrorCode\":\"MockError\"}",
"Status": "Failed",
"StartedTime": "rfc3339-format-time-string",
"StoppedTime": "rfc3339-format-time-string"
}
]
SUCCEED_0.json (example-prefix/map-run-name/SUCCEED_0.json) :
[
{
"ExecutionName": "execution-name-1",
"FlowName": "example",
"Input": "{\"FailedValue\":4,\"Key\":1}",
"Output": "{\"FailedValue\":4,\"Key\":1}",
"Status": "Succeeded",
"StartedTime": "rfc3339-format-time-string",
"StoppedTime": "rfc3339-format-time-string"
},
{
"ExecutionName": "execution-name-2",
"FlowName": "example",
"Input": "{\"FailedValue\":4,\"Key\":2}",
"Output": "{\"FailedValue\":4,\"Key\":2}",
"Status": "Succeeded",
"StartedTime": "rfc3339-format-time-string",
"StoppedTime": "rfc3339-format-time-string"
},
{
"ExecutionName": "execution-name-3",
"FlowName": "example",
"Input": "{\"FailedValue\":4,\"Key\":3}",
"Output": "{\"FailedValue\":4,\"Key\":3}",
"Status": "Succeeded",
"StartedTime": "rfc3339-format-time-string",
"StoppedTime": "rfc3339-format-time-string"
},
{
"ExecutionName": "execution-name-4",
"FlowName": "example",
"Input": "{\"FailedValue\":4,\"Key\":4}",
"Output": "{\"FailedValue\":4,\"Key\":4}",
"Status": "Succeeded",
"StartedTime": "rfc3339-format-time-string",
"StoppedTime": "rfc3339-format-time-string"
}
]
MaxItems
Limite le nombre d'éléments traités par l'état Map. Si la source de données contient plus d'éléments que la valeur de MaxItems, seuls les premiers éléments jusqu'à MaxItems sont traités.
Par exemple, si un compartiment OSS contient 10 000 objets et que MaxItems est défini sur 1 000, l'état Map ne traite que 1 000 objets.
MaxConcurrency
Limite le nombre d'exécutions de sous-flux de travail s'exécutant simultanément. Par exemple, si l'état Map traite 10 000 éléments et que MaxConcurrency est défini sur 100, au maximum 100 sous-flux s'exécutent en même temps.
ToleratedFailurePercentage
Définit le pourcentage d'exécutions de sous-flux pouvant échouer avant que l'état Map lui-même n'échoue. Par exemple, avec 10 000 éléments et ToleratedFailurePercentage défini sur 10, l'état Map tolère jusqu'à 1 000 échecs.
ToleratedFailureCount
Définit le nombre d'exécutions de sous-flux pouvant échouer avant que l'état Map lui-même n'échoue. Par exemple, avec 10 000 éléments et ToleratedFailureCount défini sur 10, l'état Map tolère jusqu'à 10 échecs.
Limites de quota
Le tableau suivant répertorie les limites de quota par défaut pour le mode distribué. Pour demander un quota supérieur, soumettre un ticket.
| Nom du quota | Description | Valeur par défaut |
|---|---|---|
| MaxOpenMapRun | Nombre maximal d'états Map distribués exécutés simultanément par compte et par région | 10 |
| MaxConcurrency | Nombre maximal d'exécutions de sous-flux concurrentes par MapRun | 300 |
| MaxItems | Nombre maximal d'éléments par MapRun | 10 000 |
Autorisations requises
L'exécution d'états Map en mode distribué nécessite les autorisations OSS suivantes. Accordez ces actions dans une politique de rôle. Pour plus d'informations, consultez Créer une politique.
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"oss:HeadObject",
"oss:GetObjectMeta",
"oss:GetObject",
"oss:PutObject",
"oss:ListObjectsV2",
"oss:ListObjects",
"oss:InitiateMultipartUpload",
"oss:UploadPart",
"oss:CompleteMultipartUpload",
"oss:AbortMultipartUpload",
"oss:ListMultipartUploads",
"oss:ListParts"
],
"Resource": "*"
}
]
}