IBM Cloud Docs
Was ist Replikation?

Was ist Replikation?

Daten können aus einer Datenbank in eine andere Datenbank im selben IBM® Cloudant® for IBM Cloud®-Konto, über Konten und Rechenzentren hinweg, kopiert werden.

Mithilfe von IBM Cloudant Sync oder PouchDBkönnen Daten sogar in und von einem IBM Cloudant-Konto und einem mobilen Gerät repliziert werden. Die Replikation kann in einer Richtung oder in beiden Richtungen ausgeführt werden, als "Einzelschuss" oder als Dauerbetrieb, und kann mit Hilfe von Parametern fein abgestimmt werden.

Das Replikationsprotokoll von IBM Cloudant ist mit einer Reihe von anderen Datenbanken und Bibliotheken kompatibel, was es zu einer hervorragenden Ergänzung des Internet of Things (IoT) und mobiler Anwendungen macht.

IBM Cloudant ist ein verteilter JSON-Datenspeicher mit einer HTTP-API. IBM Cloudant kann als Service in mehreren Clouds oder in Ihrem Server-Rack ausgeführt werden. Dokumente werden in Datenbanken gespeichert und können jede Größe annehmen, da IBM Cloudant die zugehörigen Daten über viele Knoten verteilt. Replikation ist das Kopieren von Daten aus einer Quellendatenbank in eine Zieldatenbank. Die Quellen- und Zieldatenbanken müssen sich nicht im selben IBM Cloudant-Konto und auch nicht im selben Rechenzentrum befinden.

Die Abbildung zeigt ein Bild der Datenbank a und b. Datenbank b hat ein Dokument. Nach der Replizierung werden die Dokumente aus Datenbank a in Datenbank b angezeigt.
Replication in pictures

Die Replikation ist abgeschlossen, wenn die aktuelle Version jedes Dokuments in der Quelle in die Zieldatenbank übertragen wird. Diese Übertragungen umfassen neue Dokumente, Aktualisierungen an vorhandenen Dokumenten und Löschungen. Nur die aktuelle Version eines Dokuments bleibt nach der Replikation bestehen. Ältere Versionen werden weggelassen.

Die Quellendatenbank bleibt durch die Replikation unverändert, abgesehen von Prüfpunktdaten, die in die Datenbank geschrieben werden, damit partielle Replikationen an der letzten bekannten Position fortgesetzt werden können. Alle bereits vorhandenen Daten in der Zieldatenbank bleiben bestehen.

Vorgehensweise zum Starten der Replikation über das Dashboard

Das IBM Cloudant-Dashboard stellt eine komfortable Benutzerschnittstelle zum Auslösen der Replikation bereit. Klicken Sie im IBM Cloudant-Dashboard auf Replication und dann auf Start Replication. Füllen Sie das folgende Replikationsformular aus:

Dieser Screenshot zeigt das Replikationsformular, in dem alle richtigen Felder ausgefüllt sind. Es gibt einen Quellenabschnitt, bei dem es sich um die lokale Datenbank handelt, und einen Zielabschnitt, bei dem es sich um die neue Datenbank und die Authentifizierung handelt. Im Abschnitt "Optionen" wählen Sie eine Replizierung oder Wiederholung aus und fügen ein Replizierungsdokument hinzu.
Replication form

Aus Sicherheitsgründen empfiehlt das IBM Cloudant-Team, dass Sie für Replikationsjobs IAM-API-Schlüssel oder API-Schlüssel der traditionellen IBM Cloudant-Authentifizierung verwenden und keine Berechtigungsnachweise auf Kontoebene. Weitere Informationen finden Sie in der Dokumentation unter Zugriff verwalten oder in der traditionellen Dokumentation unter Authentifizierung und Autorisierung.

Definieren Sie mithilfe des Formulars die Quellen- und Zieldatenbanken und klicken Sie dann auf Start Replication.

Der Status der einzelnen Replikationstasks kann durch Klicken auf Replication angezeigt werden. Die Statusangaben der einzelnen Jobs ändern sich im Zeitverlauf von Running in Completed. Der folgende Screenshot zeigt den Zustand von " Completed.

Unter dem Feld 'Status' in der Tabelle wird 'Abgeschlossen' angezeigt.
Completed state

Vorgehensweise zur Replikation über verschiedene IBM Cloudant-Konten

Die Quelle und das Ziel einer Replikation sind URLs von IBM Cloudant-Datenbanken, wie im folgenden Beispiel gezeigt.

Beim folgenden Beispiel werden die Quellen- und die Ziel-URL für die Replikation definiert:

{
  "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"
      }
    }
  }
}

Die Quelle und das Ziel müssen sich nicht in demselben Konto befinden. Die Quellen- und Zieldatenbankennamen müssen nicht übereinstimmen. Sie müssen berechtigt sein, sowohl auf die Quelle, als auch auf das Ziel zuzugreifen, und Sie müssen berechtigt sein, in das Ziel zu schreiben.

Wird Replikation in der Quelle oder im Ziel ausgeführt?

Die Replikation kann entweder in der Quelle oder im Ziel gestartet werden. Das heißt, Sie entscheiden, ob Konto A Daten nach Konto B schiebt oder Konto B Daten von Konto A abruft. In manchen Fällen kann es unmöglich sein, die Replikation überhaupt auszuführen, z. B. wenn ein Konto sich hinter der Firewall befindet. Die Replikation erfolgt über HTTPS, so dass keine nicht standardmäßigen Ports geöffnet werden müssen. Sie treffen die Entscheidung, welches Gerät die Replikation startet.

Wie wirkt sich die Replikation auf die Liste von Änderungen aus?

Sie können eine Liste der Änderungen, die an einem Dokument vorgenommen wurden, mithilfe des Endpunkts _changes abrufen. Allerdings führt die verteilte Struktur von IBM Cloudant-Datenbanken dazu, dass die vom Feed _changes bereitgestellte Antwort keine einfache Liste von Änderungen sein kann, die nach einem bestimmten Datum und einer bestimmten Uhrzeit ausgeführt wurden.

In der CAP Theorem-Diskussion wird deutlich, dass IBM Cloudant ein "sukzessive konsistentes" Modell verwendet. Das heißt in der Praxis: Wenn Sie zwei verschiedene Replikate einer Datenbank zum selben Zeitpunkt nach einem Dokument fragen, erhalten Sie unter Umständen verschiedene Ergebnisse. Dies ist möglich, wenn eine der Datenbankkopien noch auf den Abschluss der Replikation wartet.

Die Replikation der Datenbanken wird sukzessive abgeschlossen, damit alle Änderungen an einem Dokument in allen Kopien widergespiegelt werden.

Dieses "sukzessive konsistente" Modell hat zwei Merkmale, die sich auf eine Liste von Änderungen auswirken:

  1. Eine Änderung, die ein Dokument betrifft, erfolgt fast sicher an unterschiedlichen Zeitpunkten in verschiedenen Kopien der Datenbank.
  2. Die Reihenfolge, in der Änderungen Dokumente betreffen, kann sich zwischen verschiedenen Kopien der Datenbank unterscheiden, abhängig davon, wann und wo die Replikation gestartet wurde.

Eine Folge des ersten Merkmals ist: Wenn Sie nach einer Liste von Änderungen fragen, spielt der Zeitpunkt der Änderungen keine Rolle. Die Liste wird unter Umständen von einer anderen Datenbankkopie bereitgestellt, in der Dokumentaktualisierungen zu anderen Zeitpunkten ausgeführt wurden. Allerdings ist es wichtig, nach einer Liste von Änderungen im Anschluss an eine bestimmte Änderung zu fragen, die durch eine Sequenz-ID angegeben wird.

Eine zusätzliche Folge des ersten Merkmals ist, dass es erforderlich sein könnte, bei vorhergehenden Änderungen "zurückblicken", um sich auf der Liste der Änderungen zu einigen. Mit anderen Worten: Um eine Liste von Änderungen abzurufen, starten Sie mit der letzten Änderung, die in beiden Datenbankkopien vorgenommen wurde. Diese Übereinstimmung zwischen Datenbankkopien wird in IBM Cloudant mithilfe des Prüfpunktmechanismus angegeben, der die Replikation zwischen zu synchronisierenden Datenbanken ermöglicht.

Und schließlich ist es möglich, dass sich bei einem Blick auf eine Liste der Änderungen zeigt, dass sie in nachfolgenden Anforderungen in einer anderen Reihenfolge aufgeführt werden. Die Reihenfolge hängt davon ab, wie Dokumente zwischen verschiedenen Datenbankkopien geändert wurden. Mit anderen Worten, eine anfängliche Liste von Änderungen kann Änderungen melden A, B, dann C in dieser Reihenfolge. Eine nachfolgende Liste von Änderungen kann jedoch Änderungen melden C, A, dann B in dieser Reihenfolge. Alle Änderungen sind aufgeführt, aber in einer anderen Reihenfolge. Der Unterschied kommt dadurch zustande, dass die Abfolge von Änderungen, die während der Replikation empfangen werden, zwischen verschiedenen Kopien der Datenbank abweichen kann.

Was bedeutet "sukzessive Konsistenz" für die Liste der Änderungen?

Wenn Sie eine Liste von Änderungen anfordern, kann die Antwort je nach der Datenbankkopie, von der die Liste bereitgestellt wird, variieren.

Mit der Option since wird eine Liste von Änderungen nach einer bestimmten Aktualisierungssequenz-ID abgerufen. Die Liste enthält in jedem Fall Änderungen nach der Aktualisierung, jedoch können auch Änderungen vor der Aktualisierung eingeschlossen werden. Der Grund dafür ist, dass die Datenbankkopie, die auf die Listenanforderung antwortet, sicherstellen muss, dass sie alle Änderungen aufführt, konsistent mit allen Replikaten. Um diese Konsistenz zu erzielen, muss die Datenbankkopie die Liste von Änderungen ab dem Punkt beginnen, an dem alle Kopien identisch waren. Dieser Punkt wird mithilfe von Prüfpunkten angegeben.

Deshalb muss eine Anwendung, die den ' _changes-Feed verwendet 'idempotent' sein. Idempotenz bedeutet, dass die Anwendung in der Lage sein muss, dieselben Daten mehrmals sicher zu empfangen, und bei wiederholten Anfragen möglicherweise in einer anderen Reihenfolge.

Prüfpunkte

Intern schreibt der Replikationsprozess seinen Status in Prüfpunktdokumente, die sowohl in den Quellen- als auch in den Zieldatenbanken gespeichert werden. Prüfpunkte lassen zu, dass eine Replikationstask ab dem Punkt fortgesetzt wird, an der sie gestoppt wurde. Die Erstellung von Prüfpunkten kann verhindert werden, indem die Option "use_checkpoints": false, wenn Sie die Replikation anfordern. Es ist sinnvoll, die Funktion aktiviert zu lassen, wenn Ihre Replikation effizienterweise an ihrer zuletzt bekannten Position fortgesetzt werden soll.

Berechtigungen

Administratorzugriff ist erforderlich, um ein Dokument in die Datenbank _replicator einzufügen. Die Anmeldeberechtigungsnachweise, die in den Quellen- und Zielparametern angegebenen sind, benötigen keine umfassenden Administratorberechtigungen. Es reicht aus, wenn die Berechtigungsnachweise die folgenden Tasks zulassen:

  • Dokumente im Ziel schreiben.
  • Prüfpunktdokumente in der Quelle und im Ziel schreiben.

IBM Cloudant verfügt über die spezielle Benutzerberechtigung _replicator. Mit dieser Berechtigung können Prüfpunktdokumente erstellt werden, aber keine normalen Dokumente in einer Datenbank. Allgemein sollten Sie API-Schlüssel erstellen mit:

  • _reader- und _replicator-Zugriff auf Quellenseite.
  • _reader- und _writer-Zugriff auf Zielseite.

API-Schlüssel können im IBM Cloudant-Dashboard pro Datenbank erstellt und konfiguriert werden.

API-Schlüssel können im IBM Cloudant Dashboard für jede Datenbank erstellt und konfiguriert werden
IBM Cloudant Benutzer und API-Schlüssel mit

Sie können auch programmgesteuert mithilfe der IBM Cloudant-API erstellt werden.

Aus Sicherheitsgründen empfiehlt das IBM Cloudant-Team, dass Sie für Replikationsjobs IAM-API-Schlüssel oder API-Schlüssel der traditionellen IBM Cloudant-Authentifizierung verwenden und keine Berechtigungsnachweise auf Kontoebene. Weitere Informationen finden Sie unter Zugriff verwalten oder traditionelle Authentifizierungund Berechtigung Dokumentation.

Bidirektionale Replikation

Daten können in einem Prozess, der als bidirektionale Replikation oder Synchronisierung bekannt ist, in beide Richtungen kopiert werden. Sie aktivieren diese Synchronisierung, indem Sie zwei separate Replikationsprozesse einrichten, einen, bei dem die Daten von A nach B kopiert werden, und einen, bei dem die Daten von B nach A kopiert werden. Die beiden Replikationsprozesse arbeiten unabhängig, wobei die Daten nahtlos in beide Richtungen bewegt werden.

Die Abbildung zeigt Datenbank a und b. Datenbank a hat vier Dokumente, eines ist durchgestrichen. Datenbank b hat ein Dokument. Nach der Replikation von Datenbank a auf Datenbank b enthält Datenbank b fünf Dokumente, von denen eines durchgestrichen ist. Nach dem Replizieren von Datenbank b auf Datenbank a enthält Datenbank a ebenfalls fünf Dokumente, eines davon ist unterbrochen.
Bidirektionale Replikation

Erörterung der fortlaufenden Replikation

Bisher haben wir uns nur mit der Einmalreplikation befasst, die fertiggestellt ist, wenn alle Quellendaten in die Zieldatenbank geschrieben sind. Bei einer fortlaufenden Replikation fließen die Daten kontinuierlich. Alle nachfolgenden Änderungen an der Quellendatenbank werden in Echtzeit in die Zieldatenbank übertragen.

Die kontinuierliche Replikation wird durch Anklicken des Kontrollkästchens " Make this replication continuous ausgelöst, wenn Sie eine Replikationsaufgabe im IBM Cloudant Dashboard, oder durch Setzen des ' continuous-Flags in der IBM Cloudant API.

Eine bidirektionale Replikation kann in eine der beiden Richtungen oder in beiden Richtungen als fortlaufend definiert werden, indem Sie das Flag continuous festlegen.

Bei dem folgenden Beispiel wird eine fortlaufende Replikation unter Verwendung von HTTP gestartet:

POST /_replicator HTTP/1.1
Content-Type: application/json
Host: $SERVICE_URL
Authorization: ...

Das folgende Beispiel zeigt, wie eine kontinuierliche Replikation gestartet wird:

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))

Das vorherige Go-Beispiel erfordert den folgenden Importblock:

import (
   "encoding/json"
   "fmt"
   "github.com/IBM/cloudant-go-sdk/cloudantv1"
)

Für alle Go-Beispiele muss das Objekt service initialisiert sein. Weitere Informationen finden Sie in den Beispielen im Abschnitt 'Authentifizierung' in der API-Dokumentation.

Das folgende JSON-Beispieldokument definiert eine fortlaufende Replikation:

{
    "_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
}

Weitere Replikationsanwendungsfälle

Das Replikationsprotokoll von IBM Cloudant ist kompatibel mit anderen Datenbanken und Bibliotheken für verschiedene in der Praxis eingesetzte Anwendungen.

Apache CouchDB

Apache CouchDB ist eine Open Source Datenbank die mit IBM Cloudant kommunizieren kann, und die minimale Einrichtung erfordert. Die folgenden Anwendungen sind enthalten:

  • Sicherung - Replizieren Sie Ihre Daten aus IBM Cloudant in Ihre eigenen CouchDB-Datenbanken und erstellen Sie nächtliche Momentaufnahmen Ihrer Daten für Archivierungszwecke. Senden Sie die Daten an einen Sicherungsdienst wie Amazon Glacier zur sicheren Aufbewahrung.
  • Zuerst lokale Datenerfassung - Schreiben Sie Ihre Daten zunächst in die lokale Apache CouchDB-Instanz, replizieren Sie sie dann für eine Langzeitspeicherung, -aggregation und -analyse auf IBM Cloudant.

PouchDB

PouchDB ist eine Open Source, in-Browser-Datenbank, die es ermöglicht, Daten in beide Richtungen zwischen dem Browser und IBM Cloudant zu replizieren. Dank des Speicherns von Daten in einem Web-Browser auf Clientseite können Webanwendungen auch ohne Internetverbindung funktionieren. PouchDB kann alle geänderten Daten mit IBM Cloudant synchronisieren, wenn eine Internetverbindung besteht. Zum Einrichten einer Replikation auf Clientseite müssen ein paar Zeilen JavaScript geschrieben werden.

Mit dem JavaScript-Beispiel wird die Replikation mit PouchDB aktiviert:

var db = new PouchDB("myfirstdatabase");
var URL = "https://$USERNAME:$PASSWORD@$SERVICE_DOMAIN/my_database");
db.sync(URL, { live: true });

Gefilterte Replikationen

Es ist nützlich, einige Daten während des Replikationsprozesses entfernen zu können, wenn Sie eine Datenbank in eine andere replizieren, wie dies in den folgenden Beispielen gezeigt wird:

  • Entfernen aller Spuren gelöschter Dokumente, wodurch die Zieldatenbank kleiner als die Quelle ist.
  • Aufteilung der Daten in kleinere Einheiten, z. B. Speicherung von Daten aus dem Vereinigten Königreich in einer Datenbank und von US-Daten in einer anderen.

Replikationsfilterfunktionen

Die gefilterte Replikation in IBM Cloudant ermöglicht die Definition einer JavaScript-Funktion, die den Rückgabewert verwendet, um zu bestimmen, ob die einzelnen Dokumente in einer Datenbank gefiltert werden sollen oder nicht. Filterfunktionen werden in Entwurfsdokumenten gespeichert.

Mit der folgenden Beispielfilterfunktion werden nicht gelöschte Dokumente repliziert:

function(doc, req) {
    if (doc._deleted) {
        return false;
    }
    return true;
}

Wenn ein Replikationsjob gestartet wird, wird der Name einer Filterfunktion als Kombination des Entwurfsdokuments, in dem der Job gespeichert ist, und dem Namen der Filterfunktion angegeben. Sie können auch einen Wert query_params angeben. Dieser Wert ist ein Objekt, das Eigenschaften enthält, die an die Filterfunktion im Feld query des zweiten Arguments (req) weitergegeben werden.

Bei dem folgenden Beispiel wird eine gefilterte Replikation unter Verwendung von HTTP gestartet:

POST /_replicator HTTP/1.1
Content-Type: application/json
Host: $SERVICE_URL
Authorization: ...

Bei dem folgenden Beispiel wird eine gefilterte Replikation über die Befehlszeile gestartet:

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))

Das vorherige Go-Beispiel erfordert den folgenden Importblock:

import (
   "encoding/json"
   "fmt"
   "github.com/IBM/cloudant-go-sdk/cloudantv1"
   "github.com/IBM/go-sdk-core/core"
)

Für alle Go-Beispiele muss das Objekt service initialisiert sein. Weitere Informationen finden Sie in den Beispielen im Abschnitt 'Authentifizierung' in der API-Dokumentation.

Mit dem folgenden JSON-Beispieldokument wird eine gefilterte Replikation definiert:

{
    "_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
    }
}

Feed mit Änderungen

IBM Cloudant veröffentlicht die Hinzufügungen, Bearbeitungen und Löschungen, die sich auf die Datenbank auswirken, über einen einzelnen HTTP-Feed vom Endpunkt _changes. Dieser Feed kann von Ihrer Anwendung verwendet werden, um Ereignisse auszulösen. Sie können auf den Feed mithilfe von HTTP oder curl zugreifen, wie in den Beispielen gezeigt. Wenn Sie die Option feed=continuous verwenden, informiert Sie der Stream über jede Änderung, die erforderlich ist, damit Sie die aktuelle Version jedes Dokuments in der Datenbank abrufen.

Weitere Informationen finden Sie unter Häufig gestellte Fragen zur Verwendung des IBM Cloudant-Änderungsfeeds.

Bei dem folgenden Beispiel wird der Änderungsfeed unter Verwendung von HTTP abgefragt:

GET /$DATABASE/_changes?feed=continuous HTTP/1.1
Host: $SERVICE_URL
Authorization: ...

Bei dem folgenden Beispiel wird der Änderungsfeed über die Befehlszeile abgefragt:

curl "$SERVICE_URL/$DATABASE/_changes?feed=continuous"

Die Änderungen werden in Form von einer Zeile pro Änderung beschrieben. Jede Änderung besteht aus:

  1. Einer Zeichenfolge, die eine Sequenznummer enthält (seq).
  2. Einer Zeichenfolge, die die ID des geänderten Dokuments enthält.
  3. Einem Array von Änderungen.

Zum Anzeigen des Dokumenthauptteils hängen Sie &include_docs=true an den 'curl'-Befehl an.

Jede Änderung wird mithilfe des im folgenden (gekürzten) Beispiel angezeigten Formats beschrieben.

Orientieren Sie sich am folgenden Beispiel für den Feed _changes:

{
    "seq":"11-g1A...c1Q",
    "id":"6f8ab9fa52c117eb76240daa1a55827f",
    "changes":[
        {
          "rev":"1-619d7981d7027274a4b88810d318a7b1"
        }
    ]
}

Um den Feed mit Änderungen an einer bekannten Position zu öffnen, übergeben Sie ein since-Argument mit der Sequenznummer, ab der Sie starten möchten.

Bei dem folgenden Beispiel (gekürzt) wird die Option since unter Verwendung von HTTP übergeben, um einen _changes-Feed an einer bestimmten Position zu verknüpfen:

GET /$DATABASE/_changes?feed=continuous&include_docs=true&since=11-g1A...c1Q HTTP/1.1
HOST: $SERVICE_URL
Authorization: ...

Bei dem folgenden Beispiel (gekürzt) wird die Option since über die Befehlszeile übergeben, um einen _changes-Feed an einer bestimmten Position zu verknüpfen:

curl "$SERVICE_URL/$DATABASE/_changes?feed=continuous&include_docs=true&since=11-g1A...c1Q"

Um den Feed mit Änderungen an der aktuellen Position wieder zu öffnen, legen Sie since=now fest.

Bei dem folgenden Beispiel wird since=now unter Verwendung von HTTP übergeben, um einen _changes-Feed zum aktuellen Zeitpunkt zu verknüpfen:

GET /$DATABASE/_changes?feed=continuous&include_docs=true&since=now HTTP/1.1
Host: $SERVICE_URL
Authorization: ...

Bei dem folgenden Beispiel wird since=now über die Befehlszeile übergeben, um einen _changes-Feed zum aktuellen Zeitpunkt zu verknüpfen:

curl "$SERVICE_URL/$DATABASE/_changes?feed=continuous&include_docs=true&since=now"

Der programmgesteuerte Zugriff auf die _changes-Daten ist einfach. Sehen Sie sich beispielsweise die SDK-Beispiele in der Dokumentation zurIBM Cloudant-API an, um Änderungen mit einigen Codezeilen zu folgen.

Die folgende Liste enthält einige Beispiele für Anwendungsfälle:

  • Hinzufügen von Elementen zu einer Nachrichtenwarteschlange, um Aktionen in Ihrer Anwendung auszulösen, z. B. das Senden von Kunden-E-Mail.
  • Aktualisieren einer speicherinternen Datenbank, um zeitnah die Zahl von Aktivitäten aufzuzeichnen.
  • Schreiben von Daten in eine Textdatei, um Daten per Push-Operation in eine SQL-Datenbank zu übertragen.

Der Feed mit Änderungen kann mit einer Filterfunktion gefiltert werden, unter Einsatz einer ähnlichen Technik wie beim Filtern während der Replikation.

Bei dem folgenden Beispiel wird der Änderungsfeed unter Verwendung von HTTP gefiltert:

GET /$DATABASE/_changes?feed=continuous&include_docs=true&since=now&filter=mydesigndoc/myfilter HTTP/1.1
Host: $SERVICE_URL
Authorization: ...

Bei dem folgenden Beispiel wird der Änderungsfeed über die Befehlszeile gefiltert:

curl "$SERVICE_URL/$DATABASE/_changes?feed=continuous&include_docs=true&since=now&filter=mydesigndoc/myfilter"

Die Reihenfolge von Dokumenten im Feed _changes ist nicht immer gleich. Mit anderen Worten: Änderungen werden nicht unbedingt in streng zeitlicher Reihenfolge angezeigt. Grund ist, dass Daten von mehreren IBM Cloudant-Knoten zurückgegeben werden und möglicherweise Konsistenzregeln gelten.

Replikationsprobleme

Für eine erfolgreiche Replikation muss die Summe aus Dokumentgröße und allen Anhangsgrößen kleiner als die maximale Anforderungsgröße des Zielclusters sein. Wenn die maximale HTTP-Anforderungsgröße beispielsweise 11 MB beträgt, gelten die folgenden Szenarios:

Verschiedene Szenarien auf der Grundlage der maximalen HTTP-Anfragegröße 11 MB
Dokumentgröße Anhangsgröße Gesamtgröße Replikation möglich?
1 MB Fünf 2-MB-Anhänge 11 MB Ja
1 MB Ein 10-MB-Anhang 11 MB Ja
1 MB Einhundert 1-MB-Anhänge 101 MB Nein

Bei der Verwendung von Replikation müssen verschiedene Aspekte berücksichtigt werden.

Falsche Benutzerberechtigungen

Damit die Replikation optimal ausgeführt wird, wenn Sie von Datenbank "a" nach Datenbank "b" replizieren, müssen die bereitgestellten Berechtigungsnachweise Folgendes aufweisen:

  • Berechtigungen _reader und _replicator für Datenbank 'a'.
  • Berechtigungen _writer für Datenbank 'b'.

API-Schlüssel werden im IBM Cloudant Dashboard oder über die API generiert. Jedem Schlüssel können individuelle Berechtigungen zugewiesen werden, die sich auf eine bestimmte IBM Cloudant-Datenbank beziehen. IBM Cloudant muss die zugehörigen Prüfpunktdokumente nach dem Lesevorgang der Replikation schreiben können, sonst wird kein Status gespeichert und die Replikation kann nicht ab dem Punkt fortgesetzt werden, an dem sie gestoppt wurde. Wird der Status nicht gespeichert, kann dies zu Leistungsproblemen führen, wenn die Replikation großer Datenmengen fortgesetzt wird. Denn ohne Prüfpunkte wird der Replikationsprozess jedes Mal von vorne gestartet.

Replikationsdokument enthält Konflikte

Eine andere Folge der falschen Angabe von Benutzerberechtigungen ist, dass das Dokument _replicator Konflikte enthält. Das Dokument _replicator zeichnet den aktuellen Status des Replikationsprozesses auf. In extremen Fällen kann das Dokument sehr groß werden, weil es viele nicht gelöste Konflikte enthält. Ein solches Dokument belegt einen großen Teil des verfügbaren Speicherplatzes und verursacht zusätzliche Serverauslastung.

Sie können die Größe Ihrer Datenbank _replicator prüfen, indem Sie eine GET-Anforderung an den Endpunkt /_replicator senden:

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))

Das vorherige Go-Beispiel erfordert den folgenden Importblock:

import (
   "encoding/json"
   "fmt"
   "github.com/IBM/cloudant-go-sdk/cloudantv1"
)

Für alle Go-Beispiele muss das Objekt service initialisiert sein. Weitere Informationen finden Sie in den Beispielen im Abschnitt 'Authentifizierung' in der API-Dokumentation.

Konflikte aus Replikationsdokument abrufen

Suchen Sie im zurückgegebenen JSON-Code nach dem Wert für disk_size. Wenn der Wert eine Größe von über 1 GB angibt, rufen Sie das IBM Cloud Support-Portal auf, um weitere Informationen zu erhalten.

Sie können ein einzelnes _replicator-Dokument auf Konflikte prüfen, wie im folgenden Beispiel gezeigt:

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))

Das vorherige Go-Beispiel erfordert den folgenden Importblock:

import (
   "encoding/json"
   "fmt"
   "github.com/IBM/cloudant-go-sdk/cloudantv1"
   "github.com/IBM/go-sdk-core/core"
)

Für alle Go-Beispiele muss das Objekt service initialisiert sein. Weitere Informationen finden Sie in den Beispielen im Abschnitt 'Authentifizierung' in der API-Dokumentation.

Alle Replikationen abbrechen

Wenn Sie alle Replikationen abbrechen und mit einer neuen sauberen Datenbank _replicator starten möchten, müssen Sie die Datenbank replicator zunächst löschen und dann neu erstellen.

Siehe den folgenden HTTP, um die Datenbank " _replicator zu entfernen und neu zu erstellen:

DELETE /_replicator HTTP/1.1
HOST: $SERVICE_URL
Authorization: ...

PUT /_replicator HTTP/1.1
HOST: $SERVICE_URL
Authorization: ...

Replikatordatenbank löschen

Sehen Sie sich das folgende Beispiel an, um die _replicator-Datenbank zu entfernen:

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))

Das vorherige Go-Beispiel erfordert den folgenden Importblock:

import (
   "encoding/json"
   "fmt"
   "github.com/IBM/cloudant-go-sdk/cloudantv1"
)

Für alle Go-Beispiele muss das Objekt service initialisiert sein. Weitere Informationen finden Sie in den Beispielen im Abschnitt 'Authentifizierung' in der API-Dokumentation.

Replikatordatenbank erneut erstellen

Sehen Sie sich das folgende Beispiel an, um die _replicator-Datenbank erneut zu erstellen:

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))

Das vorherige Go-Beispiel erfordert den folgenden Importblock:

import (
   "encoding/json"
   "fmt"
   "github.com/IBM/cloudant-go-sdk/cloudantv1"
)

Für alle Go-Beispiele muss das Objekt service initialisiert sein. Weitere Informationen finden Sie in den Beispielen im Abschnitt 'Authentifizierung' in der API-Dokumentation.

Viele gleichzeitige Replikationen

Es wird leicht vergessen, dass Sie bereits die Replikation zwischen zwei Datenbanken eingerichtet haben, und so aus Versehen zusätzliche Replikationsprozesse erstellen. Jeder Replikationsjob ist unabhängig von den anderen, deshalb hindert IBM Cloudant Sie nicht daran, zusätzliche Replikationsprozesse zu erstellen. Aber jede Replikationstask verbraucht Systemressourcen.

Sie können Ihre aktiven Replikationen im IBM Cloudant-Dashboard prüfen, um sicherzustellen, dass sich keine unerwünschten Replikationstasks in Bearbeitung befinden. Löschen Sie alle _replicator-Dokumente, die nicht mehr benötigt werden.

Replikationsgeschwindigkeit optimieren

Standardmäßig werden IBM Cloudant-Replikationen mit einer angemessenen Geschwindigkeit ausgeführt, um die Daten von der Quelle zum Ziel zu übertragen, ohne dass sich dies negativ auf die Leistung auswirkt. Die Entscheidung zwischen Replikationsrate und Clusterleistung für andere Tasks ist immer ein Kompromiss. Ihr Anwendungsfall macht vielleicht eine schnellere Replikation auf Kosten anderer IBM Cloudant-Services erforderlich. Oder die Clusterleistung muss Vorrang vor der im Hintergrund ausgeführten Replikation bekommen.

Es sind erweiterte API-Optionen für die Replikation verfügbar. Diese Optionen ermöglichen eine Erhöhung oder Verringerung der während der Replikation genutzten Rechenleistung, wie in den folgenden Beispielen gezeigt:

  • Wenn Ihre Dokumente Anhänge enthalten, sollten Sie darüber nachdenken, die Stapelgröße (batch_size) zu reduzieren und die Anzahl der Worker-Prozesse (worker_processes) zu erhöhen, um größere Dokumente in kleineren Stapeln zusammenzufassen.
  • Wenn Sie viele sehr kleine Dokumente haben, sollten Sie darüber nachdenken, die Werte für worker_process und http_connections zu erhöhen.
  • Wenn Sie eine Replikation mit minimalen Auswirkungen durchführen möchten, können Sie worker_processes und http_connections auf 1 festlegen.
  • Weitere Informationen finden Sie unter Verbrauch von Lese-und Schreiboperationen durch Replikation.

Wenden Sie sich für weitere Unterstützung zur besten Konfiguration für Ihren Anwendungsfall an das IBM Cloud Support-Portal.

Die Replikationsleistung kann verbessert werden, indem die Replikationsoption "use_bulk_get": true" aktiviert wird. In diesem Fall ruft die Replikationsfunktion Dokumente in Stapeln und nicht einzeln aus der Quelle ab.

{
  "_id": "rep_doc_id",
  "source": "https://account1.cloudant.com/db1",
  "target": "https://account2.cloudant.com/db2",
  "use_bulk_get": true
}

Die höhere Replikationsrate kann die verfügbare Lese-oder Schreibratenkapazität auf den Quellen-und Zielendpunktkonten verbrauchen.

In Konflikt stehende Dokumentüberarbeitungen mit Replikation entfernen

Eine Möglichkeit, Dokumentrevisionen mit Konflikten durch Replikation zu entfernen, besteht darin, die Option "winning_revs_only": true zu aktivieren. Diese Option repliziert nur die Gewinner-Dokumentüberarbeitungen. Dies ist die Revision, die standardmäßig von einer GET $SERVICE_URL/$DATABASE/$DOCID-Anforderung zurückgegeben wird. Diese Option ist eine erweiterte Option, da sie kollidierende Dokumentüberarbeitungen verwirft. Verwenden Sie diese Option mit Vorsicht.