Qu'est-ce que la réplication ?
Les données peuvent être copiées entre différentes bases de données dans le même compte IBM® Cloudant® for IBM Cloud® ainsi que dans des comptes et des centres de données différents.
Les données peuvent même être synchronisées entre un compte IBM Cloudant et un appareil mobile en utilisant PouchDB. La réplication peut s'exécuter dans un sens ou dans les deux sens, en tant qu'opération unique ou opération continue et peut être optimisée en utilisant des paramètres.
Le protocole de réplication d'IBM Cloudant est compatible avec plusieurs autres bases de données et bibliothèques, ce qui fait qu'il est totalement adapté à IoT (Internet of Things) et aux applications mobiles.
IBM Cloudant est un magasin de données JSON réparti incluant une API HTTP. IBM Cloudant peut être exécuté en tant que service sur plusieurs clouds, ou dans votre armoire de serveurs. Les documents sont stockés dans les base de données et peuvent atteindre n'importe quelle taille car IBM Cloudant fragmente ses données dans un grand nombre de noeuds. La réplication est le processus de copie de données entre une base de données source et une base de données cible. Il n'est pas nécessaire que ces bases de données se trouvent sur le même compte IBM Cloudant, ou même dans le même centre de données.
La réplication est terminée lorsque la dernière version de chaque document de la source est transférée vers la base de données cible. Les transferts incluent les nouveaux documents, les mises à jour apportées aux documents existants et les suppressions. Seule la version la plus récente d'un document demeure après la réplication ; Les anciennes versions sont omises.
La base de données source n'est pas modifiée par la réplication, à l'exception des données de point de contrôle qui y sont placées afin que des réplications partielles puissent reprendre à partir du dernier emplacement connu. Toutes les données pré-existantes dans la base de données cible sont conservées.
Comment démarrer la réplication à l'aide du tableau de bord ?
Le tableau de bord IBM Cloudant inclut une interface utilisateur pratique permettant de déclencher la réplication. Cliquez sur Replication dans le tableau de bord IBM Cloudant, puis sur Start Replication. Complétez
le formulaire de réplication suivant :
Pour des raisons de sécurité, l'équipe IBM Cloudant recommande d'utiliser des clés d'API IAM ou des clés d'API d'authentification existantes IBM Cloudant plutôt que des données d'identification de niveau compte pour les travaux de réplication. Pour plus d'informations, voir Gestion des accès ou la documentation existante sur l' authentification et l'autorisation.
En utilisant le formulaire, définissez les bases de données source et cible, puis cliquez sur Start Replication.
Le statut de la tâche de réplication peut être affiché en cliquant sur Replication. Chaque travail progresse et passe de l'état Running à l'état Completed. La capture d'écran suivante montre l'état « Completed ».
Comment procéder à la réplication sur différents comptes IBM Cloudant ?
La source et la cible d'une réplication sont les URL des bases de données IBM Cloudant, comme cela est présenté dans l'exemple suivant.
Voici un exemple qui définit les URL source et cible pour la réplication :
{
"source": {
"url": "https://myfirstaccount.cloudant.com/a",
"auth": {
"basic": {
"username": "$USERNAME",
"password": "$PASSWORD"
}
}
},
"target": {
"url": "https://mysecondaccount.cloudant.com/b",
"auth": {
"basic": {
"username": "$USERNAME",
"password": "$PASSWORD"
}
}
}
}
Il n'est pas nécessaire que l'élément source et l'élément cible se trouvent sur le même compte. De plus, il n'est pas non plus nécessaire que les noms des bases de données source et cible soient identiques. Vous devez être autorisé à accéder à la source et à la cible et à écrire dans la cible.
La réplication s'exécute-t-elle sur la source ou la cible ?
La réplication peut être démarrée sur l'élément source ou cible. Autrement dit, vous pouvez décider si le compte A transmet des données au compte B ou si le compte B extrait des données du compte A. Dans certains cas, il peut ne pas être possible d'exécuter la réplication, par exemple lorsqu'un des comptes se trouve derrière un pare-feu. La réplication s'effectue via le protocole HTTPS; il n'est donc pas nécessaire d'ouvrir des ports non standard. Il vous revient de choisir quel appareil démarre la réplication.
Comment la réplication affecte-t-elle la liste des modifications ?
Vous pouvez obtenir la liste des modifications apportées à un document en utilisant le point de terminaison _changes. Toutefois, le fait que les bases de données IBM Cloudant
soient réparties implique que la réponse fournie par le flux _changes ne peut pas être une simple liste des modifications survenues après une date et heure spécifiques.
La discussion sur leThéorème CAP indique clairement que IBM Cloudant utilise un modèle "éventuellement cohérent". Avec ce modèle, vous pouvez obtenir des résultats différents lorsque vous demandez deux répliques différentes d'une base de données pour un document en même temps. Cette situation peut se produire lorsque l'une des copies de base de données attend que la réplication se termine.
Pour finir, les copies de base de données terminent leur réplication, afin que toutes les modifications apportées à un document soient présentes dans chaque copie.
Ce modèle de "cohérence finale" présente deux caractéristiques qui affectent une liste de modifications :
- Une modification affectant un document a certainement lieu à différents moments dans différentes copies de la base de données.
- L'ordre dans lequel les modifications affectent les documents peut différer entre les différentes copies de la base de données, selon l'emplacement et le moment de la réplication.
Conséquence de la première caractéristique : il est inutile de demander une liste de modifications après un moment défini. Cela est dû au fait que la liste de modifications peut être fournie par une autre copie de base de données, ce qui génère des mises à jour de document à des moments différents. Toutefois, il est important de demander une liste de modifications suite à une modification spécifique, définie à l'aide d'un identificateur de séquence.
Une autre conséquence de la première caractéristique est qu'il peut être nécessaire de consulter les changements précédents pour valider la liste des modifications. Autrement dit, pour obtenir une liste des modifications, vous commencez à partir de la modification la plus récente validée par les copies de base de données. Le point d'accord entre les copies de base de données est identifié dans IBM Cloudant à l'aide du mécanisme depoint de contrôle qui permet de synchroniser la réplication entre les copies de base de données.
Enfin, lorsque vous consultez une liste de modifications, celles-ci peuvent apparaître dans un ordre différent dans les demandes ultérieures. L'ordre dépend de la façon dont les documents ont été modifiés dans les différentes copies de base
de données. Autrement dit, une liste initiale de modifications peut signaler les modifications de rapport A,
B et
C dans cet ordre. Mais une liste suivante de modifications peut signaler les modifications C,
A et B dans cet ordre. Toutes les modifications sont répertoriées, mais dans un ordre différent. Cette différence est due au fait que l'ordre des modifications reçues lors de la réplication peut être différent dans
deux copies de la base de données.
A quoi correspond la "cohérence finale" pour la liste de modifications ?
Lorsque vous demandez une liste de modifications, la réponse obtenue peut varier en fonction de la copie de base de données fournissant la liste.
L'option since permet d'obtenir la liste des modifications après un identificateur de séquence de mise à jour spécifique. La liste inclut toujours les modifications effectuées après la mise à jour, mais les modifications effectuées
avant la mise à jour peuvent également apparaître. Cela est dû au fait que la copie de base de données qui répond à la demande de liste doit s'assurer qu'elle répertorie les modifications, en cohérence avec toutes les répliques. Pour atteindre
cette cohérence, la copie de base de données peut se voir dans l'obligation de démarrer la liste des modifications à partir du point de concordance de toutes les copies. Ce dernier est déterminé via l'utilisation de points de contrôle.
Par conséquent, une application qui utilise le flux _changes doit être « idempotente ». L'idempotence
signifie que l'application doit pouvoir recevoir en toute sécurité les mêmes données à plusieurs reprises, et éventuellement dans un ordre différent lors de requêtes répétées.
Points de contrôle
En interne, le processus de réplication écrit son état dans les documents de "point de contrôle" stockés dans les bases de données source et cible. Les points de contrôle permettent de reprendre l'exécution d'une tâche de réplication
là où elle en était restée, sans qu'il soit nécessaire de revenir au début. Il est possible d'empêcher la création d'un point de contrôle en fournissant le Option "use_checkpoints": false lorsque vous demandez la réplication. Il est utile d'activer cette fonction si votre réplication doit reprendre à partir de son dernier emplacement connu.
Droits
Pour pouvoir insérer un document dans la base de données _replicator, l'accès admin est requis. Des droits admin complets ne sont pas requis pour les données d'identification fournies dans les paramètres source et cible. Il suffit
que les données d'identification permettent d'effectuer les tâches suivantes :
- Ecrire des documents à l'extrémité cible.
- Ecrire des documents de points de contrôle aux deux extrémités.
IBM Cloudant dispose d'un droit utilisateur _replicator spécial. Ce droit permet la création de documents de point de contrôle mais ne permet pas la création de documents ordinaires dans une base de données. En général, vous
créez des clés d'API ayant :
- un accès
_readeret_replicatorau niveau de la source. - un accès
_readeret_writerau niveau de la cible.
Les clés d'API peuvent être créées et configurées sur le tableau de bord IBM Cloudant, pour chaque base de données.
Il est également possible de les créer à l'aide d'un programme en utilisant l'API IBM Cloudant.
Pour des raisons de sécurité, l'équipe IBM Cloudant recommande d'utiliser des clés d'API IAM ou des clés d'API d'authentification existantes IBM Cloudant plutôt que des données d'identification de niveau compte pour les travaux de réplication. Pour plus d'informations, voir Gestion des accès ou la documentation existante sur l'authentification et l'autorisation.
Réplication bidirectionnelle
Les données peuvent être copiées dans les deux sens lors d'un processus appelé réplication bidirectionnelle ou synchronisation. Vous activez cette synchronisation en configurant deux processus de réplication distincts, l'un d'entre eux transférant les données de A à B et l'autre de B à A. Les deux processus de réplication fonctionnent indépendamment, avec les données transférées en toute transparence dans les deux sens.
Discussion relative à la réplication continue
Jusqu'à présent, nous avons présenté uniquement la réplication ponctuelle, qui se termine lorsque toutes les données source sont placées dans la base de données cible. Avec la réplication continue, les données transitent de manière continue. Toutes les modifications ultérieures apportées à la base de données source sont transmises à la base de données cible en temps réel.
La réplication continue est déclenchée en cochant la case « Make this replication continuous » lors de la définition d'une tâche de réplication dans le tableau de bord d' IBM Cloudant, ou en activant le continuous indicateur dans l’API « IBM Cloudant ».
La réplication bidirectionnelle peut être rendue continue dans un sens ou les deux, en définissant l'indicateur continuous.
Voici un exemple qui utilise HTTP pour démarrer une réplication continue :
POST /_replicator HTTP/1.1
Content-Type: application/json
Host: $SERVICE_URL
Authorization: ...
Consultez l'exemple suivant pour lancer une réplication continue :
curl -X POST \
-H "Content-type: application/json" \
"$SERVICE_URL/_replicator" \
-d '{ "_id": "repldoc-example",
"continuous": true,
"create_target": true,
"source": { "url": "'"$SOURCE_SERVICE_URL/source"'" },
"target": {
"auth": { "iam": { "api_key": "'"$API_KEY"'" } },
"url": "'"$TARGET_SERVICE_URL/target"'"
}
}'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.DocumentResult;
import com.ibm.cloud.cloudant.v1.model.PutReplicationDocumentOptions;
import com.ibm.cloud.cloudant.v1.model.ReplicationDatabase;
import com.ibm.cloud.cloudant.v1.model.ReplicationDatabaseAuth;
import com.ibm.cloud.cloudant.v1.model.ReplicationDatabaseAuthIam;
import com.ibm.cloud.cloudant.v1.model.ReplicationDocument;
Cloudant service = Cloudant.newInstance();
ReplicationDatabase sourceDb = new ReplicationDatabase.Builder()
.url("<your-source-service-url>/source")
.build();
ReplicationDatabaseAuthIam targetAuthIam =
new ReplicationDatabaseAuthIam.Builder()
.apiKey("<your-iam-api-key>")
.build();
ReplicationDatabaseAuth targetAuth = new ReplicationDatabaseAuth.Builder()
.iam(targetAuthIam)
.build();
ReplicationDatabase targetDb = new ReplicationDatabase.Builder()
.auth(targetAuth)
.url("<your-target-service-url>/target")
.build();
ReplicationDocument replDocument = new ReplicationDocument();
replDocument.setSource(sourceDb);
replDocument.setTarget(targetDb);
replDocument.setContinuous(true);
PutReplicationDocumentOptions replicationDocumentOptions =
new PutReplicationDocumentOptions.Builder()
.docId("repldoc-example")
.replicationDocument(replDocument)
.build();
DocumentResult response =
service.putReplicationDocument(replicationDocumentOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
const sourceDb: CloudantV1.ReplicationDatabase = {
url: '<your-source-service-url>/source'
};
const targetDb: CloudantV1.ReplicationDatabase = {
auth: {
iam: {
'api_key': '<your-iam-api-key>'
}
},
url: '<your-target-service-url>/target'
};
const replDocument: CloudantV1.ReplicationDocument = {
id: 'repldoc-example',
continuous: true,
create_target: true,
source: sourceDb,
target: targetDb
}
service.putReplicationDocument({
docId: 'repldoc-example',
replicationDocument: replDocument
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1, ReplicationDocument, ReplicationDatabase, ReplicationDatabaseAuthIam, ReplicationDatabaseAuth
service = CloudantV1.new_instance()
source_db = ReplicationDatabase(
url='<your-source-service-url>/source'
)
target_auth_iam = ReplicationDatabaseAuthIam(
api_key='<your-iam-api-key>'
)
target_auth = ReplicationDatabaseAuth(
iam=target_auth_iam
)
target_db = ReplicationDatabase(
auth=target_auth,
url='<your-target-service-url>/target'
)
replication_document = ReplicationDocument(
id='repldoc-example',
continuous=True,
create_target=True,
source=source_db,
target=target_db
)
response = service.put_replication_document(
doc_id='repldoc-example',
replication_document=replication_document
).get_result()
print(response)
source, err := service.NewReplicationDatabase(
"<your-source-service-url>/source",
)
if err != nil {
panic(err)
}
target, err := service.NewReplicationDatabase(
"<your-target-service-url>/target",
)
if err != nil {
panic(err)
}
auth, err := service.NewReplicationDatabaseAuthIam(
"<your-iam-api-key>",
)
if err != nil {
panic(err)
}
target.Auth = &cloudantv1.ReplicationDatabaseAuth{Iam: auth}
replicationDoc, err := service.NewReplicationDocument(
source,
target,
)
if err != nil {
panic(err)
}
replicationDoc.Continuous = core.BoolPtr(true)
replicationDoc.CreateTarget = core.BoolPtr(true)
putReplicationDocumentOptions := service.NewPutReplicationDocumentOptions(
"repldoc-example",
replicationDoc,
)
documentResult, response, err := service.PutReplicationDocument(putReplicationDocumentOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(documentResult, "", " ")
fmt.Println(string(b))
L'exemple précédent de Go requiert le bloc d'importation suivant :
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
Tous les exemples de Go nécessitent l'initialisation de l'objet service. Pour plus d'informations, reportez-vous à la documentation de l'API Section Authentification pour avoir des exemples.
Voici un exemple de document JSON qui définit une réplication continue :
{
"_id": "weekly_continuous_backup",
"source": {
"url": "https://$SOURCE_SERVICE_DOMAIN/source",
"auth": {
"basic": {
"username": "$USERNAME",
"password": "$PASSWORD"
}
}
},
"target": {
"url": "https://$TARGET_SERVICE_DOMAIN/target",
"auth": {
"basic": {
"username": "$USERNAME",
"password": "$PASSWORD"
}
}
},
"continuous": true
}
Autres cas d'utilisation de la réplication
Le protocole de réplication d'IBM Cloudant est compatible avec d'autres bases de données et bibliothèques pour différentes applications du monde réel.
Apache CouchDB
Apache CouchDB Il s'agit d'une base de données open source capable de communiquer avec IBM Cloudant, et qui ne nécessite qu'une configuration minimale. Les applications suivantes sont incluses :
- Sauvegarde - Répliquez vos données depuis IBM Cloudant vers vos propres bases de données CouchDB et effectuez des sauvegardes quotidiennes de vos données à des fins d'archivage. Envoyez les données vers un service de sauvegarde tel qu’ Amazon Glacier afin de les conserver en toute sécurité.
- Collecte de données « local-first » - Enregistrez d'abord vos données sur l' Apache CouchDB, puis le copier sur IBM Cloudant pour le stocker à long terme, agrégation, et analyse.
PouchDB
PouchDB est une base de données open source, fonctionnant directement dans le navigateur, qui permet la réplication bidirectionnelle des données entre le navigateur et IBM Cloudant. Le stockage des données dans un navigateur Web au niveau client permet aux applications Web de fonctionner, même sans connexion Internet. PouchDB peut synchroniser les données modifiées vers et depuis IBM Cloudant lorsqu'une connexion Internet est disponible. La configuration de la réplication côté client nécessite quelques lignes de JavaScript.
Voici un exemple de code JavaScript qui utilise PouchDB pour activer la réplication :
var db = new PouchDB("myfirstdatabase");
var URL = "https://$USERNAME:$PASSWORD@$SERVICE_DOMAIN/my_database");
db.sync(URL, { live: true });
Filtrage des réplications
Il est utile de pouvoir retirer certaines données pendant le processus de réplication, lorsque vous répliquez une base de données dans une autre, comme dans les exemples suivants :
- Suppression de toutes les traces des documents supprimés, ce qui fait que la base de données cible est plus petite que la base de données source.
- Répartir les données en petits blocs, par exemple en stockant les données relatives au Royaume-Uni dans une base de données et celles relatives aux États-Unis dans une autre.
Fonctions de filtrage de réplication
La réplication filtrée d'IBM Cloudant permet la définition d'une fonction JavaScript utilisant la valeur de retour pour déterminer si chaque document d'une base de données doit être filtré ou non. Les fonctions de filtrage sont stockées dans des documents de conception.
Voici un exemple de fonction de filtrage pour la réplication des documents non supprimés :
function(doc, req) {
if (doc._deleted) {
return false;
}
return true;
}
Lorsqu'un travail de réplication commence, un nom de fonction de filtrage est indiqué, combinant le document de conception dans lequel il est stocké et le nom de la fonction de filtrage. Vous pouvez également indiquer une valeur query_params.
Cette valeur est un objet qui contient les propriétés transmises à la fonction de filtrage dans la zone query de son deuxième argument (req).
Voici un exemple qui utilise HTTP pour démarrer une réplication filtrée :
POST /_replicator HTTP/1.1
Content-Type: application/json
Host: $SERVICE_URL
Authorization: ...
Voici un exemple qui utilise la ligne de commande pour démarrer une réplication filtrée :
curl -X POST \
-H "Content-type: application/json" \
"$SERVICE_URL/_replicator" \
-d @filtered-replication.json
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.DocumentResult;
import com.ibm.cloud.cloudant.v1.model.PutReplicationDocumentOptions;
import com.ibm.cloud.cloudant.v1.model.ReplicationDatabase;
import com.ibm.cloud.cloudant.v1.model.ReplicationDatabaseAuth;
import com.ibm.cloud.cloudant.v1.model.ReplicationDatabaseAuthIam;
import com.ibm.cloud.cloudant.v1.model.ReplicationDocument;
Cloudant service = Cloudant.newInstance();
ReplicationDatabase sourceDb = new ReplicationDatabase.Builder()
.url("<your-source-service-url>/source")
.build();
ReplicationDatabaseAuthIam targetAuthIam =
new ReplicationDatabaseAuthIam.Builder()
.apiKey("<your-iam-api-key>")
.build();
ReplicationDatabaseAuth targetAuth = new ReplicationDatabaseAuth.Builder()
.iam(targetAuthIam)
.build();
ReplicationDatabase targetDb = new ReplicationDatabase.Builder()
.auth(targetAuth)
.url("<your-target-service-url>/target"))
.build();
ReplicationDocument replDocument = new ReplicationDocument();
replDocument.setSource(sourceDb);
replDocument.setTarget(targetDb);
replDocument.setFilter("mydesigndoc/myfilter");
Map queryParams = new HashMap<>();
queryParams.put("foo", "bar");
queryParams.put("baz", 5);
replDocument.setQueryParams(queryParams);
PutReplicationDocumentOptions replicationDocumentOptions =
new PutReplicationDocumentOptions.Builder()
.docId("repldoc-example")
.replicationDocument(replDocument)
.build();
DocumentResult response =
service.putReplicationDocument(replicationDocumentOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
const sourceDb: CloudantV1.ReplicationDatabase = {
url: '<your-source-service-url>/source'
};
const targetDb: CloudantV1.ReplicationDatabase = {
auth: {
iam: {
'api_key': '<your-iam-api-key>'
}
},
url: '<your-target-service-url>/target'
};
const replDocument: CloudantV1.ReplicationDocument = {
id: 'repldoc-example',
filter: 'mydesigndoc/myfilter',
query_params: {'foo': 'bar', 'baz': 5},
source: sourceDb,
target: targetDb
}
service.putReplicationDocument({
docId: 'repldoc-example',
replicationDocument: replDocument
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1, ReplicationDocument, ReplicationDatabase, ReplicationDatabaseAuthIam, ReplicationDatabaseAuth
service = CloudantV1.new_instance()
source_db = ReplicationDatabase(
url='<your-source-service-url>/source'
)
target_auth_iam = ReplicationDatabaseAuthIam(
api_key='<your-iam-api-key>'
)
target_auth = ReplicationDatabaseAuth(
iam=target_auth_iam
)
target_db = ReplicationDatabase(
auth=target_auth,
url='<your-target-service-url>/target'
)
replication_document = ReplicationDocument(
id='repldoc-example',
filter='mydesigndoc/myfilter',
query_params={'foo': 'bar', 'baz': 5},
source=source_db,
target=target_db
)
response = service.put_replication_document(
doc_id='repldoc-example',
replication_document=replication_document
).get_result()
print(response)
source, err := service.NewReplicationDatabase(
"<your-source-service-url>/source",
)
if err != nil {
panic(err)
}
target, err := service.NewReplicationDatabase(
"<your-target-service-url>/target",
)
if err != nil {
panic(err)
}
auth, err := service.NewReplicationDatabaseAuthIam(
"<your-iam-api-key>",
)
if err != nil {
panic(err)
}
target.Auth = &cloudantv1.ReplicationDatabaseAuth{Iam: auth}
replicationDoc, err := service.NewReplicationDocument(
source,
target,
)
if err != nil {
panic(err)
}
replicationDoc.Filter := "mydesigndoc/myfilter"
replicationDoc.QueryParams := map[string]interface{}{"foo": "bar", "baz": 5}
putReplicationDocumentOptions := service.NewPutReplicationDocumentOptions(
"repldoc-example",
replicationDoc,
)
documentResult, response, err := service.PutReplicationDocument(putReplicationDocumentOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(documentResult, "", " ")
fmt.Println(string(b))
L'exemple précédent de Go requiert le bloc d'importation suivant :
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
"github.com/IBM/go-sdk-core/core"
)
Tous les exemples de Go nécessitent l'initialisation de l'objet service. Pour plus d'informations, reportez-vous à la documentation de l'API Section Authentification pour avoir des exemples.
Voici un exemple de document JSON qui définit une réplication filtrée :
{
"_id": "weekly_backup",
"source": {
"url": "https://$SOURCE_SERVICE_DOMAIN/source",
"auth": {
"basic": {
"username": "$USERNAME",
"password": "$PASSWORD"
}
}
},
"target": {
"url": "https://$TARGET_SERVICE_DOMAIN/target",
"auth": {
"basic": {
"username": "$USERNAME",
"password": "$PASSWORD"
}
}
},
"filter": "mydesigndoc/myfilter",
"query_params": {
"foo": "bar",
"baz": 5
}
}
Flux de modifications
IBM Cloudant publie les ajouts, modifications et suppressions affectant une base de données via un flux unique de type « HTTP » provenant du point de terminaison _changes.
Ce flux peut être utilisé par votre application pour déclencher des événements. Vous pouvez y accéder en utilisant HTTP ou curl, comme cela est présenté dans les exemples. Si vous utilisez l'option feed=continuous,
le flux inclut toutes les modifications requises pour obtenir la version la plus récente de chaque document de la base de données.
Pour plus d'informations, voir Utilisation de la Foire aux Questions sur les flux de modifications IBM Cloudant.
Voici un exemple qui utilise HTTP pour interroger le flux de modifications :
GET /$DATABASE/_changes?feed=continuous HTTP/1.1
Host: $SERVICE_URL
Authorization: ...
Voici un exemple qui utilise la ligne de commande pour interroger le flux de modifications :
curl "$SERVICE_URL/$DATABASE/_changes?feed=continuous"
Pour chaque modification, une ligne est créée indiquant sa description. Chaque modification inclut :
- une chaîne contenant un numéro de séquence (
seq). - une chaîne contenant l'ID du document modifié.
- un tableau de modifications.
Pour voir le corps du document lui-même, ajoutez &include_docs=true à la commande curl.
Chaque modification est décrite en utilisant le format présenté dans l'exemple suivant (abrégé).
Voici un exemple de flux _changes :
{
"seq":"11-g1A...c1Q",
"id":"6f8ab9fa52c117eb76240daa1a55827f",
"changes":[
{
"rev":"1-619d7981d7027274a4b88810d318a7b1"
}
]
}
Pour rejoindre le flux de modifications à partir d'un emplacement connu, transmettez un argument since avec le numéro de séquence à partir duquel commencer.
Voici un exemple (abrégé) qui utilise HTTP pour fournir l'option since afin de rejoindre un flux _changes à une position connue :
GET /$DATABASE/_changes?feed=continuous&include_docs=true&since=11-g1A...c1Q HTTP/1.1
HOST: $SERVICE_URL
Authorization: ...
Voici un exemple (abrégé) qui utilise la ligne de commande pour fournir l'option since afin de rejoindre un flux _changes à une position connue :
curl "$SERVICE_URL/$DATABASE/_changes?feed=continuous&include_docs=true&since=11-g1A...c1Q"
Pour rejoindre le flux de modifications à partir du moment actuel, indiquez since=now.
Voici un exemple qui utilise HTTP pour fournir since=now afin de rejoindre un flux _changes à partir du moment actuel :
GET /$DATABASE/_changes?feed=continuous&include_docs=true&since=now HTTP/1.1
Host: $SERVICE_URL
Authorization: ...
Voici un exemple qui utilise la ligne de commande pour fournir since=now afin rejoindre un flux _changes à partir du moment actuel :
curl "$SERVICE_URL/$DATABASE/_changes?feed=continuous&include_docs=true&since=now"
L'accès aux données _changes à l'aide d'un programme est direct. Par exemple, consultez les exemples de SDK dans la documentation d'API IBM Cloudant pour suivre
les modifications avec quelques lignes de code.
La liste suivante inclut des exemples de cas d'utilisation :
- Ajout d'éléments à une file d'attente de messages afin de déclencher des actions dans votre application, telles l'envoi d'un message électronique.
- Mise à jour d'une base de données en mémoire afin d'enregistrer le nombre d'activités en cours.
- Placement de données dans un fichier de texte afin de transmettre les données dans une base de données SQL.
Le flux de modifications peut être filtré, en utilisant une technique similaire au filtrage lors de la réplication.
Voici un exemple qui utilise HTTP pour filtrer le flux de modifications :
GET /$DATABASE/_changes?feed=continuous&include_docs=true&since=now&filter=mydesigndoc/myfilter HTTP/1.1
Host: $SERVICE_URL
Authorization: ...
Voici un exemple qui utilise la ligne de commande pour filtrer le flux de modifications :
curl "$SERVICE_URL/$DATABASE/_changes?feed=continuous&include_docs=true&since=now&filter=mydesigndoc/myfilter"
L'ordre des documents dans le flux _changes n'est pas toujours le même. Autrement dit, les modifications peuvent ne pas apparaître dans un ordre temporel strict. Cela est dû au fait que les données sont renvoyés à partir de plusieurs
noeuds IBM Cloudant et que les règles de cohérence finale s'appliquent.
Inconvénients de la réplication
Pour qu'une réplication aboutisse, la somme de la taille des documents et de toutes les pièces jointes doit être inférieure à la taille de demande maximale du cluster cible. Ainsi, si taille de demande HTTP maximale est 11 Mo, les scénarios suivants s'appliquent :
| Taille de document | Taille de la pièce jointe | Taille totale | Réplication ? |
|---|---|---|---|
| 1 Mo | 5 pièces jointe de 2 Mo | 11 Mo | Oui |
| 1 Mo | 1 pièce jointe de 10 Mo | 11 Mo | Oui |
| 1 Mo | 100 pièces jointes de 1 Mo | 101 Mo | Non |
Lors de l'utilisation de la réplication, plusieurs éléments sont à prendre en compte.
Droits utilisateur incorrects
Pour que la réplication fonctionne de manière optimale lorsque vous répliquez de la base de données "a" vers la base de données "b", les données d'identification fournies doivent avoir :
- des droits
_readeret_replicatorsur la base de données "a". - des droits
_writersur la base de données "b".
Les clés API sont générées dans le tableau de bord d' IBM Cloudant ou via l'API. Chaque clé peut disposer de droits individuels concernant une base de données IBM Cloudant spécifique. IBM Cloudant doit pouvoir écrire ses documents de point de contrôle à la fin de la "lecture" de la réplication. Sinon, aucun état n'est sauvegardé et la réplication ne peut pas reprendre à partir de son emplacement d'arrêt. Si l'état n'est pas sauvegardé, cela peut générer des problèmes de performances lorsque la réplication d'une grande quantité de données reprend. Effectivement, sans point de contrôle, le processus de réplication recommence au début à chaque reprise.
Le document de réplication est en conflit
Une autre conséquence d'une définition incorrecte des droits utilisateur fait que le document _replicator est en conflit. Le document _replicator enregistre l'état en cours du processus de réplication. Dans une situation
extrême, le document peut devenir énorme car il contient un grand nombre de conflits non résolus. Un document de cette taille utilise une grand quantité de l'espace disponible et provoque un chargement supplémentaire du serveur.
Vous pouvez vérifier la taille de votre base de données _replicator en envoyant une demande GET au noeud final /_replicator :
curl "$SERVICE_URL/_replicator"
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.DatabaseInformation;
import com.ibm.cloud.cloudant.v1.model.GetDatabaseInformationOptions;
Cloudant service = Cloudant.newInstance();
GetDatabaseInformationOptions databaseInfoOptions =
new GetDatabaseInformationOptions.Builder()
.db("_replicator")
.build();
DatabaseInformation response =
service.getDatabaseInformation(databaseInfoOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.getDatabaseInformation({db: '_replicator'}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.get_database_information(db='_replicator').get_result()
print(response)
getDatabaseInformationOptions := service.NewGetDatabaseInformationOptions(
"_replicator",
)
databaseInformation, response, err := service.GetDatabaseInformation(getDatabaseInformationOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(databaseInformation, "", " ")
fmt.Println(string(b))
L'exemple précédent de Go requiert le bloc d'importation suivant :
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
Tous les exemples de Go nécessitent l'initialisation de l'objet service. Pour plus d'informations, reportez-vous à la documentation de l'API Section Authentification pour avoir des exemples.
Obtenir les conflits à partir du document de réplication
Dans l'élément JSON, recherchez la valeur disk_size. Si la valeur indique une taille supérieure à 1 Go, accédez auPortail de support IBM Cloud pour obtenir des conseils
supplémentaires.
Vous pouvez rechercher des conflits dans un document _replicator, comme cela est présenté dans l'exemple suivant :
curl "$SERVICE_URL/_replicator/$DOCID?conflicts=true"
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.GetReplicationDocumentOptions;
import com.ibm.cloud.cloudant.v1.model.ReplicationDocument;
Cloudant service = Cloudant.newInstance();
GetReplicationDocumentOptions replicationDocOptions =
new GetReplicationDocumentOptions.Builder()
.conflicts(true)
.docId("$DOCID")
.build();
ReplicationDocument response =
service.getReplicationDocument(replicationDocOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.getReplicationDocument({
conflicts: true,
docId: '$DOCID'
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.get_replication_document(
conflicts=True,
doc_id='$DOCID'
).get_result()
print(response)
getReplicationDocumentOptions := service.NewGetReplicationDocumentOptions(
"$DOCID",
)
replicationDocument, response, err := service.GetReplicationDocument(getReplicationDocumentOptions)
if err != nil {
panic(err)
}
replicationDocument.Conflicts = core.BoolPtr(true)
b, _ := json.MarshalIndent(replicationDocument, "", " ")
fmt.Println(string(b))
L'exemple précédent de Go requiert le bloc d'importation suivant :
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
"github.com/IBM/go-sdk-core/core"
)
Tous les exemples de Go nécessitent l'initialisation de l'objet service. Pour plus d'informations, reportez-vous à la documentation de l'API Section Authentification pour avoir des exemples.
Annuler toutes les réplications
Si vous souhaitez annuler toutes les réplications et en commencer une nouvelle, nettoyez la base de données _replicator, supprimez puis recréez la base de données replicator.
Consultez l' HTTP suivante pour supprimer et recréer la base de données _replicator:
DELETE /_replicator HTTP/1.1
HOST: $SERVICE_URL
Authorization: ...
PUT /_replicator HTTP/1.1
HOST: $SERVICE_URL
Authorization: ...
Supprimer la base de données du réplicateur
Consultez l'exemple suivant pour supprimer la base de données _replicator:
curl -X DELETE "$SERVICE_URL/_replicator"
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.DeleteDatabaseOptions;
import com.ibm.cloud.cloudant.v1.model.Ok;
Cloudant service = Cloudant.newInstance();
DeleteDatabaseOptions deleteDatabaseOptions = new DeleteDatabaseOptions.Builder()
.db("_replicator")
.build();
Ok response = service.deleteDatabase(deleteDatabaseOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.deleteDatabase({db: '_replicator'}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.delete_database(db='_replicator').get_result()
print(response)
deleteDatabaseOptions := service.NewDeleteDatabaseOptions(
"_replicator",
)
ok, response, err := service.DeleteDatabase(deleteDatabaseOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(ok, "", " ")
fmt.Println(string(b))
L'exemple précédent de Go requiert le bloc d'importation suivant :
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
Tous les exemples de Go nécessitent l'initialisation de l'objet service. Pour plus d'informations, reportez-vous à la documentation de l'API Section Authentification pour avoir des exemples.
Recréation de la base de données du réplicateur
Consultez l'exemple suivant pour recréer la base de données _replicator:
curl -X PUT "$SERVICE_URL/_replicator"
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.Ok;
import com.ibm.cloud.cloudant.v1.model.PutDatabaseOptions;
Cloudant service = Cloudant.newInstance();
PutDatabaseOptions databaseOptions = new PutDatabaseOptions.Builder()
.db("_replicator")
.build();
Ok response =
service.putDatabase(databaseOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.putDatabase({
db: '_replicator'
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.put_database(db='_replicator').get_result()
print(response)
putDatabaseOptions := service.NewPutDatabaseOptions(
"_replicator",
)
ok, response, err := service.PutDatabase(putDatabaseOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(ok, "", " ")
fmt.Println(string(b))
L'exemple précédent de Go requiert le bloc d'importation suivant :
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
Tous les exemples de Go nécessitent l'initialisation de l'objet service. Pour plus d'informations, reportez-vous à la documentation de l'API Section Authentification pour avoir des exemples.
Nombre de réplications simultanées élevé
Il est facile d'oublier que vous avez déjà configuré une réplication entre deux bases de données et donc de créer par erreur des processus de réplication supplémentaires. Chaque travail de réplication est indépendant des autres, IBM Cloudant ne vous empêche donc pas de créer des processus de réplication supplémentaires. Toutefois, chaque tâche de réplication utilise des ressources système.
Vous pouvez vérifier les "réplications actives" dans le tableau de bord IBM Cloudant afin de vous assurer qu'aucune tâche de réplication non souhaitée n'est en cours. Supprimez tous les documents _replicator qui ne sont
plus requis.
Optimisation de la vitesse de réplication
Par défaut, La réplication IBM Cloudant s'exécute à un taux approprié pour extraire les données de la source vers la cible sans affecter les performances. Le fait de choisir entre la vitesse de réplication et les performances du cluster pour d'autres tâches constitue un compromis. Votre cas d'utilisation peut exiger une réplication plus rapide au détriment des autres services IBM Cloudant. Il peut également être nécessaire que les performances du cluster soient prioritaires. La réplication est alors traitée en processus d'arrière-plan.
Des options d'API de réplication avancées sont disponibles. Elles permettent d'augmenter ou de réduire la puissance de calcul utilisée lors de la réplication,
- Si vos documents comportent des pièces jointes, il peut être nécessaire de réduire batch_size et d'augmenter worker_processes, afin de prendre en charge des documents plus importants sous forme de lots plus petits.
- Si vous avez un grand nombre de documents minuscules, pensez à augmenter les valeurs
worker_processethttp_connections. - Si vous souhaitez exécuter la réplication avec un faible impact, attribuer la valeur 1 à
worker_processesethttp_connectionspeut être approprié. - Pour plus d'informations, voir Consommation des opérations de lecture et d'écriture par réplication.
Pour plus d'informations sur la meilleure configuration selon votre cas d'utilisation, rendez-vous sur le Portail de support IBM Cloud.
Les performances de réplication peuvent être améliorées en activant l'option de réplication "use_bulk_get": true". Dans ce cas, le réplicateur extrait les documents de la source par lots plutôt qu'individuellement.
{
"_id": "rep_doc_id",
"source": "https://account1.cloudant.com/db1",
"target": "https://account2.cloudant.com/db2",
"use_bulk_get": true
}
Le taux de réplication accru peut consommer la capacité de débit de lecture ou d'écriture disponible sur les comptes de noeud final source et cible.
Suppression des révisions de document en conflit avec la réplication
L'activation de l'option "winning_revs_only": true permet de supprimer les révisions de document en conflit via la réplication. Cette option réplique uniquement les révisions de document gagnantes. Il s'agit de
la révision renvoyée par défaut par une demande GET $SERVICE_URL/$DATABASE/$DOCID. Cette option est une option avancée, car elle supprime les révisions de document en conflit. Utilisez cette option avec prudence.