Migration vers des étendues et des collections dans Couchbase 7.0
Tout d’abord, je tiens à souligner un excellent blog écrit par Shivani Gupta, Comment migrer vers des étendues et des collections dans Couchbase 7.0, qui couvre en détail les méthodes non événementielles de migration de documents basés sur des compartiments vers des étendues et des collections dans Couchbase. Je vous encourage à lire également les multiples méthodes non événementielles abordées par Shivani.
Que vous soyez nouveau sur Couchbase ou un vétérinaire chevronné, vous avez probablement entendu parler des Scopes et des Collections. Si vous êtes prêt à les essayer, cet article vous aide à y arriver.
Les étendues et les collections sont une nouvelle fonctionnalité introduite dans Couchbase Server 7.0 qui vous permet d’organiser logiquement les données dans Couchbase. Pour en savoir plus, lisez cette introduction aux Portées et Collections.
Vous devez tirer parti des portées et des collections si vous souhaitez mapper votre SGBDR hérité à une base de données de documents ou si vous essayez de consolider des centaines de microservices et/ou de locataires dans un seul cluster Couchbase (entraînant un coût total de possession beaucoup plus faible).
Utilisation d’événements pour la migration des étendues et des collections
Dans cet article, je vais discuter d’une autre méthode hautes performances pour migrer d’une ancienne version de Couchbase vers Scopes et Collections dans Couchbase 7.0.
Vous n’avez besoin que du service de données (ou KV) et du service d’événements pour migrer des buckets aux collections. Dans un grand cluster Couchbase bien réglé, vous pouvez migrer plus d’un million de documents par seconde. Oui, pas de N1QL et aucun index nécessaire.
Dans les sections ci-dessous, je vais présenter une technique pour effectuer la migration via Eventing, puis terminer par une méthode entièrement automatisée pour effectuer de grandes migrations avec des dizaines de types de données via un simple Perl scénario.
Si vous ne vous souciez pas des détails, passez directement à « Automatisez tout cela via CustomConvertBucketToCollections.pl«
Prérequis : Apprendre le concours complet
Dans cet article, nous utiliserons la dernière version de Couchbase (7.0.2), mais les versions antérieures 7.0 fonctionnent également correctement. Si vous n’êtes pas familier avec Couchbase ou le service Eventing, veuillez parcourir les ressources suivantes, y compris au moins un exemple Eventing :
Fonction d’événement : ConvertBucketToCollections
L’événementiel vous permet d’écrire une logique métier pure. Le service Eventing prend en charge l’ensemble de l’infrastructure nécessaire pour gérer et faire évoluer votre fonction (horizontalement et verticalement) sur plusieurs nœuds de manière performante et fiable.
Toutes les fonctions Événementiel ont deux points d’entrée – OnUpdate(doc, meta)
et OnDelete(meta, options)
. Notez que nous ne sommes pas préoccupés par ce dernier point d’entrée dans cet exemple.
Lorsqu’un document change ou mute (insert, upsert, replace, etc.), une copie du document et certaines métadonnées sur le document sont transmises à un petit point d’entrée JavaScript OnUpdate(doc, meta)
.
Les fonctions d’événement peuvent être déployées avec deux limites de flux de déploiement différentes, soit « À partir de maintenant » ou « Tout ». Ce dernier permet d’accéder à chaque document courant dans un Bucket dans Couchbase 6.6 ou un Keyspace (Bucket/Scope/Collection) dans Couchbase 7.0.
Le scriptlet ConvertirBucketToCollections de la documentation principale sur Eventing montre comment utiliser Eventing pour transférer des données d’un compartiment source vers un compartiment de destination et diviser vos données en collections.
Étape 1 : Charger des exemples de données
Dans l’interface utilisateur de Couchbase, sélectionnez « Paramètres/Seaux d’échantillons ». Vérifier beer-sample
et cliquez sur le bouton « Charger les données d’échantillon ».
Étape 2 : Créez les espaces de touches nécessaires
Cet exemple nécessite trois buckets : « beer-sample » (c’est-à-dire votre magasin de documents à migrer), « rr100″ (c’est-à-dire un bloc-notes pour Eventing qui peut être partagé avec d’autres fonctions Eventing) et en vrac (le bucket pour créer votre collectes dans). Les buckets « rr100 » et « bulk » doivent avoir une taille minimale de 100 Mo.
Dans l’interface utilisateur de Couchbase, sélectionnez « Seaux » et cliquez sur le lien « AJOUTER UN SEAU » en haut à droite. Créez deux buckets d’une taille de 100 Mo, « rr100 » (pour le stockage Eventing ou le bloc-notes) et « bulk » (pour la cible de migration).
Dans le seau « rr100″ créer une étendue « événementiel« .
Dans la portée « rr100.événementiel » créer la collection « métadonnées« .
Dans le seau « masse » créer une étendue « Les données« .
Dans la portée « données.en.volume » créer les collections « Bière » et « Brasserie« .
À ce stade, vous devriez avoir trois (3) compartiments comme suit :
Avec les collections suivantes dans le « masse » baquet:
Et les collections suivantes dans le « rr100″ baquet:
Étape 3 : Créer la fonction d’événement
Dans l’interface utilisateur de Couchbase, sélectionnez « Concours complet » et appuyez sur le « AJOUTER UNE FONCTION » lien en haut à droite.
Les paramètres de la fonction Eventing sont les suivants :
Appuyez sur le bouton « sauvegarder » puis collez ce script dans le panneau de l’éditeur de fonctions :
function OnUpdate(doc, meta) {
if (doc.type === 'beer') {
if (DO_COPY) beer_col[meta.id] = doc;
if (DO_DELETE) {
if (!beer_col[meta.id]) { // safety check
log("skip delete copy not found type=" + doc.type + ", meta.id=" + meta.id);
} else {
delete src_col[meta.id];
}
}
}
if (doc.type === 'brewery') {
if (DO_COPY) brewery_col[meta.id] = doc;
if (DO_DELETE) {
if (!brewery_col[meta.id]) { // safety check
log("skip delete copy not found type=" + doc.type + ", meta.id=" + meta.id);
} else {
delete src_col[meta.id];
}
}
}
}
Votre éditeur de code devrait ressembler à ceci :
Appuyez sur le bouton « Enregistrer et retourner«
Ce que fait ConvertBucketToCollections
Les OnUpdate(doc, meta)
la logique traitera toutes les données dans le `beer-sample`._default._default keyspace et effectuera les opérations suivantes sur toutes les mutations passées (historiques) et nouvelles (futures).
- Premièrement, la propriété du type.doc est vérifié dans deux blocs de code presque identiques pour voir s’il correspond à l’un ou l’autre
beer
, oubrewery
. S’il y a une correspondance, continuez. - Une constante mondiale
DO_COPY
(fourni via les paramètres de fonctions via un alias de liaison constante) est vérifié pour voir si l’élément doit être copié. - Si
DO_COPY
est vrai, le document sera écrit dans la collection cible ou l’espace de clésbeer_col
oubrewery_col
(défini via les paramètres Functions via un alias Bucket Binding) en fonction du bloc de code qui correspond. - Une constante mondiale
DO_DELETE
(fourni via les paramètres de fonctions via un alias de liaison constante) est vérifié pour voir si l’élément doit être supprimé de l’espace de clés ou de la collection source (défini via les paramètres de fonctions via un alias de liaison de seau) - Si
DO_DELETE
est vrai, le document sera supprimé de la collection ou de l’espace de cléssrc_col
(défini via les paramètres Functions via un alias Bucket Binding).
Nous pourrions augmenter le nombre de nœuds de calcul de 1 au nombre de processeurs virtuels pour de meilleures performances, mais notre ensemble de données est trivial, nous laissons donc le nombre de nœuds de calcul à un (1). Remarque : le paramètre pour les travailleurs se trouve dans la section extensible Paramètres au milieu de la boîte de dialogue Paramètres de fonction.
Déploiement de la fonction d’événementiel
Il est maintenant temps de déployer la fonction Eventing. Nous avons examiné un peu le code et la conception du script de migration ConvertBucketToCollections, et il est maintenant temps de voir tout fonctionner ensemble.
À ce stade, nous avons une fonction en JavaScript, nous devons donc l’ajouter à notre cluster Couchbase et la déployer dans un état actif.
Appuyez sur le bouton « Déployer« .
Le service Eventing prend environ 18 secondes pour déployer votre fonction Eventing, auquel cas vous devriez immédiatement voir 7303 éléments traités. Étant donné que l’ensemble de données est statique, vous avez terminé car tous les éléments ont été traités.
Appuyez sur le bouton « Annuler le déploiement« .
Examen des données migrées
Maintenant que nous avons fini d’utiliser la fonction d’événement, nous pouvons inspecter les compartiments et les collections pour voir ce qui s’est passé. Dans l’interface utilisateur de Couchbase, sélectionnez « Seaux«
Sélectionnez maintenant « Périmètres et collections » pour le compartiment « masse », puis étendre la portée « Les données ».
Dans l’interface utilisateur de Couchbase, sélectionnez « Documents« , puis sélectionnez l’espace de touches « la.bière.de.données.en vrac » et vous verrez les documents migrés dans cette collection.
Dans l’interface utilisateur de Couchbase, sélectionnez « Documents« , puis sélectionnez l’espace de touches « vrac.data.brasserie » et vous verrez les documents migrés dans cette collection.
Améliorons la fonction d’événementiel
N’oubliez pas que l’événementiel peut enrichir les données à la volée, et si nous divisons vraiment un seau (vers Couchbase 6.x) en collections distinctes (vers Couchbase 7.0), nous n’avons plus besoin du Type de propriété. Modifions donc notre fonction pour transformer également nos données.
Par exemple, étant donné le document avec la clé « abhi_brewery » dans nos données source dans `beer-sample`._default._default :
{
"name": "Abhi Brewery",
"city": "",
"state": "",
"code": "",
"country": "India",
"phone": "",
"website": "",
"type": "brewery",
"updated": "2011-09-27 00:35:48",
"description": "",
"address": []
}
nous avons supprimé "type": "brewery"
:
{
"name": "Abhi Brewery",
"city": "",
"state": "",
"code": "",
"country": "India",
"phone": "",
"website": "",
"updated": "2011-09-27 00:35:48",
"description": "",
"address": []
}
Voici la modification de notre fonction d’événement :
function OnUpdate(doc, meta) {
if (!doc.type) return;
var type = doc.type;
if (DROP_TYPE) delete doc.type;
if (type === 'beer') {
if (DO_COPY) beer_col[meta.id] = doc;
if (DO_DELETE) {
if (!beer_col[meta.id]) { // safety check
log("skip delete copy not found type=" + doc.type + ", meta.id=" + meta.id);
} else {
delete src_col[meta.id];
}
}
}
if (type === 'brewery') {
if (DO_COPY) brewery_col[meta.id] = doc;
if (DO_DELETE) {
if (!brewery_col[meta.id]) { // safety check
log("skip delete copy not found type=" + doc.type + ", meta.id=" + meta.id);
} else {
delete src_col[meta.id];
}
}
}
}
Et puisque nous ajoutons une nouvelle constante globale DROP_TYPE
, nous modifions également les paramètres comme suit :
Cela fonctionne, mais que se passe-t-il si j’ai beaucoup de types ?
L’événementiel peut faire des migrations, mais cela semble être un peu de travail pour mettre les choses en place.
Si vous avez 80 types différents, l’utilisation de cette technique représenterait une quantité incroyable d’efforts sujets aux erreurs (à la fois en créant la fonction Eventing et en créant les espaces de clés nécessaires). Si j’avais 80 types à migrer et à diviser, je ne voudrais pas faire tout le travail décrit ci-dessus à la main.
Automatiser via CustomConvertBucketToCollections.pl
Pour résoudre ce problème, j’ai écrit un petit Perl scénario, CustomConvertBucketToCollections.pl, qui génère deux fichiers :
- CustomConvertBucketToCollections.json, est une fonction d’événement complète qui effectue tout le travail ci-dessus décrit dans cet article.
- MakeCustomKeyspaces.sh, est un fichier shell permettant de créer tous les espaces de clés nécessaires et d’importer la fonction Eventing générée.
Vous pouvez trouver ce script sur GitHub.
Attention, le script CustomConvertBucketToCollections.pl exige que les deux Perl (langage pratique d’extraction et de rapport) et jq (un processeur JSON de ligne de commande léger et flexible) sont installés sur votre système.
Exemple : migrer 250 millions d’enregistrements avec 80 types différents
Nous avons 250 millions de documents dans l’espace de clés « input._default._default » avec 80 types différents et souhaitons réorganiser les données par type en collections sous la portée « output.reorg » par type de propriété. Nous avons un cluster AWS de trois instances r5.2xlarge, toutes exécutant le service de données et le service de soirée.
Le seau d’entrée « saisir » dans cet exemple est configuré avec un quota de mémoire de 16 000 Mo.
Ci-dessous, j’utilise le CustomConvertBucketToCollections.pl Perl script de GitHub. Comme vous pouvez le voir, cela peut être trivial à faire…