NimoShake (également connu sous le nom de DynamoShake) est un outil de synchronisation des données développé par Alibaba Cloud qui migre les bases de données Amazon DynamoDB vers ApsaraDB for MongoDB. Il prend en charge la migration complète, la migration incrémentielle ou les deux lors d'une seule exécution.
Fonctionnalités prises en charge
| Fonctionnalité | Prise en charge |
|---|---|
| Migration complète | Oui |
| Migration incrémentielle | Oui |
| Reprise après interruption (incrémentielle) | Oui |
| Reprise après interruption (complète) | Non |
| Migration des index (phase complète uniquement) | Oui |
| Migration du schéma uniquement | Oui |
| Filtrage des collections | Oui |
| Migration des index (phase incrémentielle) | Non |
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Une instance de jeu de réplicas ou une instance de cluster fragmenté ApsaraDB for MongoDB. Consultez Créer une instance de jeu de réplicas ou Créer une instance de cluster fragmenté.
L'AccessKey ID et l'AccessKey secret pour Amazon DynamoDB.
Un espace de stockage suffisant dans ApsaraDB for MongoDB pour contenir toutes les données de la base de données source DynamoDB. La capacité de stockage de destination doit être supérieure à celle de la source.
Fonctionnement
NimoShake exécute la migration complète et la migration incrémentielle sous forme de phases distinctes.
Migration complète
La migration complète se compose de deux parties : la migration des données suivie de la migration des index.

La migration des données utilise trois types de threads dans un pipeline :

| Thread | Description |
|---|---|
| Fetcher | Appelle le pilote de conversion de protocole d'Amazon pour récupérer par lots les données de la table source et les placer dans des files d'attente. Un seul thread fetcher s'exécute à la fois. |
| Parser | Lit les données des files d'attente, les convertit au format BSON, puis les transmet aux exécuteurs. Par défaut : 2 threads. Contrôlé par full.document.parser. |
| Executor | Extrait les données des files d'attente, agrège jusqu'à 16 Mo ou 1 024 entrées, et écrit dans la destination. Par défaut : 4 threads. Contrôlé par full.document.concurrency. |
La migration des index s'exécute une fois la migration des données terminée et crée les index suivants :
-
Index générés automatiquement :
Si la table source possède une clé de partition et une clé de tri : un index composé unique sur les deux clés, ainsi qu'un index haché sur la clé de partition.
Si la table source ne possède qu'une clé de partition : un index haché et un index unique sur la clé de partition.
Index créés par l'utilisateur : Un index haché basé sur la clé primaire est créé pour chaque index défini par l'utilisateur.
Migration incrémentielle
La migration incrémentielle capture les modifications en cours depuis la source et les écrit dans ApsaraDB for MongoDB. Elle ne migre pas les index créés pendant la phase incrémentielle.

| Thread | Description |
|---|---|
| Fetcher | Surveille les modifications des fragments dans le flux. |
| Manager | Gère la notification des messages et crée un Dispatcher pour chaque fragment. |
| Dispatcher | Récupère les données incrémentielles de la source, en reprenant à partir du dernier point de contrôle lorsque la reprise après interruption est active. |
| Batcher | Analyse, regroupe et agrège les données incrémentielles provenant des threads Dispatcher. |
| Executor | Écrit les données agrégées dans l'instance ApsaraDB for MongoDB de destination et met à jour le point de contrôle. |
Reprise après interruption et points de contrôle
La migration incrémentielle prend en charge la reprise après interruption grâce aux points de contrôle. Si une connexion est perdue puis rétablie rapidement, la migration reprend à partir du dernier point de contrôle. Une déconnexion prolongée ou la perte du point de contrôle peut déclencher à nouveau une migration complète.
Par défaut, les points de contrôle sont stockés dans la base de données ApsaraDB for MongoDB de destination, dans une base de données nommée nimo-shake-checkpoint. Chaque collection possède sa propre table de point de contrôle, et une status_table indique si la synchronisation actuelle est une tâche complète ou incrémentielle.
La migration complète ne prend pas en charge la reprise après interruption. Si une migration complète est interrompue, elle redémarre depuis le début.
Migrer DynamoDB vers ApsaraDB for MongoDB
Les étapes suivantes utilisent Ubuntu comme exemple.
Étape 1 : Télécharger NimoShake
wget https://github.com/alibaba/NimoShake/releases/download/release-v1.0.14-20250704/nimo-shake-v1.0.14.tar.gz
Téléchargez la dernière version depuis la page des versions de NimoShake .
Étape 2 : Extraire le package
tar zxvf nimo-shake-v1.0.14.tar.gz
Étape 3 : Accéder au répertoire
cd nimo-shake-v1.0.14
Étape 4 : Configurer NimoShake
Ouvrez le fichier de configuration :
vi nimo-shake.conf
Les tableaux ci-dessous décrivent tous les paramètres de configuration, regroupés par catégorie. Commencez par les paramètres obligatoires, puis ajustez les paramètres facultatifs selon vos besoins.
Paramètres requis
| Paramètre | Description | Exemple |
|---|---|---|
source.access_key_id |
L'AccessKey ID pour la base de données Amazon DynamoDB. | source.access_key_id = AKIAIOSFODNN7EXAMPLE |
source.secret_access_key |
L'AccessKey secret pour la base de données Amazon DynamoDB. | source.secret_access_key = wJalrXUtnFEMI/K7MDENG |
source.region |
La région AWS de la base de données DynamoDB. Facultatif si la région est détectée automatiquement ou non applicable. | source.region = us-east-2 |
target.type |
Le type de la base de données de destination. Définissez sur mongodb pour ApsaraDB for MongoDB. Définissez sur aliyun_dynamo_proxy pour une instance ApsaraDB for MongoDB compatible avec DynamoDB.Pour plus d'adresses MongoDB, consultez Connexion à une instance de jeu de réplicas ou Connexion à une instance de cluster fragmenté. |
target.type = mongodb |
target.address |
La chaîne de connexion de la base de données de destination. Consultez Connexion à une instance de jeu de réplicas ou Connexion à une instance de cluster fragmenté. | target.address = mongodb://username:password@s-*****-pub.mongodb.rds.aliyuncs.com:3717 |
target.mongodb.type |
Le type de l'instance ApsaraDB for MongoDB de destination. replica pour une instance de jeu de réplicas. sharding pour une instance de cluster fragmenté. |
target.mongodb.type = sharding |
sync_mode |
Le mode de migration. all : exécute la migration complète suivie de la migration incrémentielle. full : exécute uniquement la migration complète. Par défaut : all. Remarque
Seul |
sync_mode = all |
Paramètres généraux
| Paramètre | Par défaut | Requis | Description | Exemple |
|---|---|---|---|---|
id |
— | Facultatif | L'ID de la tâche de migration. Utilisé pour les fichiers PID, les noms de journaux, le nom de la base de données de point de contrôle et le nom de la base de données de destination. | id = nimo-shake |
log.file |
stdout | Facultatif | Le chemin du fichier journal. S'il n'est pas défini, les journaux sont affichés sur stdout. | log.file = nimo-shake.log |
log.level |
info |
Facultatif | Le niveau de journalisation. Valeurs valides : none, error, warn, info, debug. |
log.level = info |
log.buffer |
true |
Facultatif | Indique si la mise en mémoire tampon des journaux est activée. true : hautes performances, mais risque de perdre les dernières entrées de journal lors de la sortie. false : toutes les entrées de journal sont vidées, mais les performances peuvent diminuer. |
log.buffer = true |
system_profile |
— | Facultatif | Le port PPROF pour le débogage et l'affichage des informations sur les coroutines avec pile. | system_profile = 9330 |
full_sync.http_port |
— | Facultatif | Le port RESTful pour la phase de migration complète. Utilisez curl pour afficher les statistiques de surveillance. Consultez le wiki. |
full_sync.http_port = 9341 |
incr_sync.http_port |
— | Facultatif | Le port RESTful pour la phase de migration incrémentielle. Utilisez curl pour afficher les statistiques de surveillance. Consultez le wiki. |
incr_sync.http_port = 9340 |
Paramètres de connexion source
| Paramètre | Par défaut | Requis | Description | Exemple |
|---|---|---|---|---|
source.session_token |
— | Facultatif | Le jeton de session temporaire pour accéder à DynamoDB. Requis uniquement lors de l'utilisation d'identifiants temporaires. | source.session_token = AQoXnyc4lcK4w4... |
source.endpoint_url |
— | Facultatif | L'URL de l'endpoint, si la source est de type endpoint. **La définition de ce paramètre remplace tous les autres source.* paramètres.** |
source.endpoint_url = "http://192.168.0.1:1010" |
source.session.max_retries |
— | Facultatif | Le nombre maximal de tentatives après un échec de session. | source.session.max_retries = 3 |
source.session.timeout |
— | Facultatif | Le délai d'expiration de la session en millisecondes. Définissez sur 0 pour désactiver le délai d'expiration. |
source.session.timeout = 3000 |
Filtrage des collections
| Paramètre | Par défaut | Requis | Description | Exemple |
|---|---|---|---|---|
filter.collection.white |
— | Facultatif | Liste blanche des collections à migrer. Seules les collections répertoriées sont migrées. | filter.collection.white = c1;c2 |
filter.collection.black |
— | Facultatif | Liste noire des collections à exclure. Toutes les autres collections sont migrées. Ne peut pas être utilisé conjointement avec filter.collection.white. Si les deux sont définis, toutes les collections sont migrées. |
filter.collection.black = c1;c2 |
Paramètres de destination
| Paramètre | Par défaut | Requis | Description | Exemple |
|---|---|---|---|---|
target.db.exist |
Error | Facultatif | Comment gérer les collections existantes portant le même nom dans la destination. rename : renomme la collection existante en ajoutant un suffixe d'horodatage (par exemple, c1 devient c1.2019-07-01Z12:10:11). drop : supprime la collection existante. S'il n'est pas défini, la migration s'arrête avec une erreur si une collection de même nom existe. |
target.db.exist = drop |
sync_schema_only |
false |
Facultatif | Indique s'il faut migrer uniquement le schéma de la table sans les données. | sync_schema_only = false |
Performances de migration complète
| Paramètre | Par défaut | Requis | Description | Exemple |
|---|---|---|---|---|
full.concurrency |
4 |
Facultatif | Le nombre maximal de collections migrées simultanément. | full.concurrency = 4 |
full.read.concurrency |
1 |
Facultatif | Le nombre de threads concurrents lisant à partir d'une seule table source. Correspond au paramètre TotalSegments de l'API Scan de DynamoDB. |
full.read.concurrency = 1 |
full.document.concurrency |
4 |
Facultatif | Le nombre de threads d'écriture concurrents par table. | full.document.concurrency = 4 |
full.document.write.batch |
— | Facultatif | Le nombre d'entrées agrégées par écriture. Lorsque la destination est une base de données compatible avec DynamoDB, la valeur maximale est 25. | full.document.write.batch = 25 |
full.document.parser |
2 |
Facultatif | Le nombre de threads d'analyse concurrents pour convertir les données DynamoDB vers le protocole de destination. | full.document.parser = 2 |
full.enable_index.user |
true |
Facultatif | Indique s'il faut migrer les index définis par l'utilisateur. | full.enable_index.user = true |
full.executor.insert_on_dup_update |
true |
Facultatif | Indique s'il faut convertir une commande INSERT en UPDATE lorsqu'une clé en double existe dans la destination. |
full.executor.insert_on_dup_update = true |
qps.full |
1000 |
Facultatif | Le nombre maximal d'appels de commande Scan par seconde pendant la migration complète. |
qps.full = 1000 |
qps.full.batch_num |
128 |
Facultatif | Le nombre d'entrées de données extraites par seconde pendant la migration complète. | qps.full.batch_num = 128 |
full.read.filter_expression |
— | Facultatif | Une expression de filtre DynamoDB pour la migration complète. Les variables commencent par deux-points, par exemple :begin et :end. Spécifiez les valeurs des variables dans full.read.filter_attributevalues. |
full.read.filter_expression = create_time > :begin AND create_time < :end |
full.read.filter_attributevalues |
— | Facultatif | Les valeurs des variables dans full.read.filter_expression. N représente Number (nombre), S représente String (chaîne). |
full.read.filter_attributevalues = beginN1646724207280~~~endN1646724207283 |
Performances de migration incrémentielle
Ignorez cette section si vous exécutez uniquement la migration complète ( sync_mode = full ).
| Paramètre | Par défaut | Requis | Description | Exemple |
|---|---|---|---|---|
incr_sync_parallel |
false |
Facultatif | Indique s'il faut activer la migration incrémentielle parallèle. true : utilise plus de mémoire. false : mode standard. |
incr_sync_parallel = false |
increase.concurrency |
16 |
Facultatif | Le nombre maximal de fragments capturés simultanément. | increase.concurrency = 16 |
increase.executor.insert_on_dup_update |
true |
Facultatif | Indique s'il faut convertir une commande INSERT en UPDATE lorsque les mêmes clés existent dans la destination. |
increase.executor.insert_on_dup_update = true |
increase.executor.upsert |
true |
Facultatif | Indique s'il faut convertir une commande UPDATE en UPSERT lorsqu'aucune clé correspondante n'existe dans la destination. Une commande UPSERT met à jour l'enregistrement si la clé existe, ou l'insère si elle n'existe pas. |
increase.executor.upsert = true |
qps.incr |
1000 |
Facultatif | Le nombre maximal d'appels de commande GetRecords par seconde pendant la migration incrémentielle. |
qps.incr = 1000 |
qps.incr.batch_num |
128 |
Facultatif | Le nombre d'entrées de données extraites par seconde pendant la migration incrémentielle. | qps.incr.batch_num = 128 |
Paramètres de point de contrôle
Ignorez cette section si vous exécutez uniquement la migration complète ( sync_mode = full ).
| Paramètre | Par défaut | Requis | Description | Exemple |
|---|---|---|---|---|
checkpoint.type |
— | Facultatif | Le type de stockage pour les données de point de contrôle. mongodb : stocke les points de contrôle dans une base de données ApsaraDB for MongoDB (disponible uniquement lorsque target.type est mongodb). file : stocke les points de contrôle sur la machine locale. |
checkpoint.type = mongodb |
checkpoint.address |
Destination DB | Facultatif | L'adresse pour stocker les données de point de contrôle. Si checkpoint.type est mongodb, entrez la chaîne de connexion. S'il n'est pas défini, les points de contrôle sont stockés dans la base de données de destination. Si checkpoint.type est file, entrez un chemin relatif. S'il n'est pas défini, la valeur par défaut est le dossier checkpoint relatif à l'exécutable NimoShake. |
checkpoint.address = mongodb://username:password@s-*****-pub.mongodb.rds.aliyuncs.com:3717 |
checkpoint.db |
<id>-checkpoint |
Facultatif | Le nom de la base de données pour le stockage des points de contrôle. Par défaut <id>-checkpoint, par exemple nimo-shake-checkpoint. |
checkpoint.db = nimo-shake-checkpoint |
Paramètres avancés
| Paramètre | Par défaut | Requis | Description | Exemple |
|---|---|---|---|---|
convert._id |
— | Facultatif | Un préfixe ajouté au champ _id de DynamoDB pour éviter les conflits avec le champ _id de MongoDB. |
convert._id = pre |
Étape 5 : Démarrer la migration
./nimo-shake.linux -conf=nimo-shake.conf
Lorsque la migration complète est terminée, la sortie affiche :
full sync done!
Si la migration s'arrête en raison d'une erreur, NimoShake affiche le message d'erreur et quitte. Consultez le fichier journal ou la sortie stdout pour diagnostiquer le problème.
Notes d'utilisation
Exécutez pendant les heures creuses. La migration complète consomme des ressources à la fois sur la base de données source DynamoDB et sur l'instance ApsaraDB for MongoDB de destination. Un trafic élevé ou des spécifications de serveur insuffisantes peuvent augmenter la charge de la base de données. Planifiez les migrations pendant les heures creuses pour minimiser l'impact.
Surveillez continuellement la migration incrémentielle. Si la migration incrémentielle est interrompue pendant une période prolongée ou si le point de contrôle est perdu, une migration complète peut être nécessaire pour resynchroniser toutes les données.
La migration incrémentielle ne synchronise pas les index. Les index créés ou modifiés pendant la phase incrémentielle ne sont pas migrés. Gérez manuellement les modifications d'index sur la destination si nécessaire.
Conflits de noms de collections. Si une collection portant le même nom existe déjà dans la destination, configurez
target.db.existsurrenameoudrop. Sans ce paramètre, la migration s'arrête avec une erreur.