IBM Cloud Docs
¿Qué es la réplica?

¿Qué es la réplica?

Los datos se pueden copiar de una base de datos en otra en la misma cuenta de IBM® Cloudant® for IBM Cloud®, entre cuentas y entre centros de datos.

Los datos incluso se pueden replicar en y desde una cuenta de IBM Cloudant y un dispositivo móvil utilizando IBM Cloudant Sync o PouchDB. La réplica puede ejecutarse en una dirección o en ambas direcciones, como una operación única o continua, y se puede ajustar usando parámetros.

El protocolo de réplica de IBM Cloudant es compatible con diversas bases de datos y bibliotecas, lo que lo convierte en una solución perfecta para Internet de las cosas (IoT) y para aplicaciones móviles.

IBM Cloudant es un almacén de datos JSON distribuidos con una API HTTP. IBM Cloudant se puede ejecutar como un servicio en varias nubes o en un bastidor de servidores. Los documentos se guardan en bases de datos y pueden alcanzar el tamaño deseado a medida que IBM Cloudant fragmenta sus datos entre varios nodos. La réplica es la copia de los datos de la base de datos de origen en una base de datos de destino. No es necesario que las bases de datos de origen y de destino estén en la misma cuenta de IBM Cloudant ni en el mismo centro de datos.

El gráfico muestra una imagen de la base de datos a y b. La base de datos b tiene un documento. Después de la réplica, los documentos de la base de datos a se muestran en la base de datos b.
Replication in pictures

La réplica finaliza cuando la versión más actualizada de cada documento del origen se transfiere a la base de datos de destino. Las transferencias incluyen documentos nuevos, actualizaciones de documentos existentes y supresiones. Solo queda la versión más reciente de un documento después de la réplica; se omiten las versiones anteriores.

La réplica no modifica la base de datos de origen, sin contar los datos de punto de comprobación que se escriben en la misma para permitir que las réplicas parciales se reanuden desde la última posición conocida. Los datos preexistentes en la base de datos de destino permanecen.

Cómo empezar a replicar con el panel de control

El panel de control de IBM Cloudant proporciona una interfaz de usuario adecuada para activar la réplica. Pulse Replication en el panel de control de IBM Cloudant y pulse Start Replication. Complete el siguiente formulario de réplica:

Esta captura de pantalla muestra el formulario de réplica con todos los campos adecuados rellenados. Hay una sección de origen, que es la base de datos local, y una sección de destino, que es la nueva base de datos y la autenticación. En la sección Opciones, seleccione una réplica o repetición de una sola vez y añada un documento de réplica.
Replication form

Por motivos de seguridad, el equipo de IBM Cloudant recomienda el uso de claves de API de IAM o claves de API de la autenticación heredada de IBM Cloudant en lugar de credenciales a nivel de cuenta para los trabajos de réplica. Para obtener más información, consulte la documentación sobre Gestión de acceso o autenticación y autorización anterior.

Utilizando el formulario, defina las bases de datos de origen y destino y, a continuación, pulse Start Replication.

El estado de cada tarea de réplica se puede ver pulsando Replication. Cada job modifica el estado de Running a Completed a medida que se procesa. La siguiente captura de pantalla muestra el estado ' Completed '.

En el campo Estado de la tabla, verá Completado.
Completed state

Cómo ejecutar réplicas entre distintas cuentas de IBM Cloudant

El origen y el destino de una réplica son los URL de las bases de datos de IBM Cloudant, tal como se muestra en el siguiente ejemplo.

Consulte el ejemplo siguiente que define los URL de origen y de destino para la réplica:

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

No es necesario que el origen y el destino estén en la misma cuenta. No es necesario que los nombres de la base de datos de origen y de destino coincidan. Debe tener autorización para acceder al origen y al destino y debe tener autorización para escribir en el destino.

¿La réplica se ejecuta en el origen o en el destino?

La réplica se puede iniciar en el extremo de origen o en el de destino. Esta opción significa que puede decidir si la cuenta A envía por push los datos a la cuenta B o si la cuenta B toma los datos de la cuenta A. En algunos casos, puede que sea imposible ejecutar la réplica en ninguna configuración, por ejemplo cuando una cuenta está detrás de un cortafuegos. La replicación se realiza a través de HTTPS, por lo que no es necesario abrir puertos no estándar. La decisión sobre qué dispositivo inicia la réplica es suya.

¿Cómo afectará la réplica a la lista de cambios?

Puede obtener una lista de los cambios realizados en un documento utilizando el punto final '_changes. Sin embargo, la naturaleza distribuida de las bases de datos de IBM Cloudant implica que la respuesta que ofrece el canal de información _changes no puede ser una simple lista de los cambios producidos después de una determinada fecha y hora.

El debate sobre el Teorema CAP deja claro que IBM Cloudant utiliza un modelo "eventualmente coherente". Este modelo significa que puede obtener distintos resultados si solicita dos réplicas diferentes de una base de datos para un documento al mismo tiempo. Esto puede suceder cuando una de las copias de la base de datos sigue en espera de finalizar la réplica.

Finalmente, las copias de base de datos completan su réplica, de modo que todos los cambios en un documento aparecen en cada copia.

Este modelo de "coherencia eventual" tiene dos características que afectan a una lista de cambios:

  1. Es casi seguro que un cambio que afecta a un documento se produce en distintos momentos en las diferentes copias de la base de datos.
  2. El orden en el que los cambios afectan a los documentos puede diferir entre distintas copias de la base de datos, en función de cuándo y desde dónde se haya realizado la réplica.

Una consecuencia de la primera característica es que, cuando solicita una lista de cambios, no tiene sentido solicitar una lista de cambios posteriores a un determinado punto en el tiempo. El motivo es que puede suministrar la lista de cambios una copia diferente de la base de datos, lo que da lugar a actualizaciones en el documento en distintos momentos. Sin embargo, que tiene sentido solicitar una lista de cambios después de un determinado cambio, que se especifica mediante un identificador de secuencia.

Una consecuencia adicional de la primera característica es que podría ser necesario "mirar hacia atrás" a los cambios anteriores para acordar la lista de cambios. Es decir, para obtener una lista de cambios, debe comenzar por el cambio más reciente aceptado por las copias de la base de datos. El punto de acuerdo entre las copias de la base de datos se identifica en IBM Cloudant utilizando el mecanismo de punto de comprobación que permite sincronizar la réplica entre las copias de la base de datos.

Por último, cuando examine una lista de cambios, es posible que se presenten en un orden distinto en las solicitudes posteriores. El orden depende de cómo se hayan modificado los documentos entre distintas copias de la base de datos. En otras palabras, una lista inicial de cambios podría notificar cambios A, B y, a continuación, C en ese orden. Pero una lista posterior de cambios podría informar de cambios C, A y, a continuación, B en ese orden. Todos los cambios aparecen en la lista, pero en distinto orden. Esta diferencia se debe a que la secuencia de cambios que se reciben durante la réplica puede variar entre dos copias distintas de la base de datos.

¿Qué significa "coherencia eventual" para la lista de cambios?

Cuando se solicita una lista de cambios, la respuesta que se obtiene puede variar dependiendo de la copia de base de datos que proporciona la lista.

La opción since obtiene una lista de cambios después de un identificador de secuencia de actualización específico. La lista siempre incluye los cambios después de la actualización, pero los cambios antes de la actualización también se pueden incluir. El motivo es que la copia de la base de datos que responde a la solicitud de lista debe asegurarse de que ofrece una lista de los cambios coherente con todas las réplicas. Para lograr esta coherencia, es posible que la copia de la base de datos que tenga que iniciar la lista de cambios desde el punto en el que todas las copias coinciden. Este punto se identifica mediante puntos de comprobación.

Por lo tanto, una aplicación que utilice el feed ' _changes ' debe ser 'idempotente'. Idempotencia significa que la aplicación debe ser capaz de recibir con seguridad los mismos datos varias veces, y potencialmente en un orden diferente para peticiones repetidas.

Puntos de comprobación

Internamente, el proceso de réplica escribe su estado en documentos "de punto de comprobación" que se almacenan en las bases de datos de origen y de destino. Los puntos de comprobación permiten reanudar una tarea de réplica desde el punto en el que se detuvo, sin tener que empezar desde el principio. La creación de punto de comprobación se puede evitar proporcionando el Opción "use_checkpoints": false al solicitar la réplica. Resulta útil dejar esta característica activada si la réplica se debe reanudar eficientemente desde su última posición conocida.

Permisos

Se necesita acceso de administración para insertar un documento en la base de datos _replicator. Las credenciales de inicio de sesión que se suministran en los parámetros de origen y de destino no requieren permisos completos de administración. Es suficiente si las credenciales realizan las siguientes tareas:

  • Escribir documentos en el extremo de destino.
  • Escribir documentos de punto de comprobación en ambos extremos.

IBM Cloudant tiene un permiso de usuario _replicator especial. Este permiso permite crear documentos de punto de comprobación, pero no permite crear documentos comunes en una base de datos. En general, cree claves de API que tenga:

  • Acceso _reader y _replicator en la parte de origen.
  • Acceso _reader y _writer en la parte de destino.

Las claves de API se pueden crear y configurar en el panel de control de IBM Cloudant, base de datos a base de datos.

Las claves API pueden crearse y configurarse en el IBM Cloudant Dashboard, por base de datos
IBM Cloudant usuarios y claves API con

También se pueden crear mediante programación con la API de IBM Cloudant.

Por motivos de seguridad, el equipo de IBM Cloudant recomienda el uso de claves de API de IAM o claves de API de la autenticación heredada de IBM Cloudant en lugar de credenciales a nivel de cuenta para los trabajos de réplica. Para obtener más información, consulte la documentación sobre Gestión de acceso o autenticacióny autorización anterior.

Réplica bidireccional

Los datos se pueden copiar en ambas direcciones en un proceso que se conoce como sincronización o réplica bidireccional. Para habilitar esta sincronización, configure dos procesos de réplica: uno que tome los datos de A en B y otro que tome los datos de B en A. Ambos procesos de réplica funcionan de forma independiente y los datos se mueven continuamente en ambas direcciones.

El gráfico muestra las bases de datos a y b. La base de datos a tiene cuatro documentos, uno está tachado. La base de datos b tiene un documento. Después de replicar la base de datos a en la base de datos b, la base de datos b tiene cinco documentos, uno está desactivado. Después de replicar la base de datos b en la base de datos a, la base de datos a también tiene cinco documentos, uno está tachado.
Réplica bidireccional

Réplica continua

Hasta ahora, solo se ha tratado el tema de la réplica única, que finaliza cuando todos los datos de origen se han escrito en la base de datos de destino. En una réplica continua, los datos fluyen constantemente. Los cambios siguientes en la base de datos de origen se transmiten a la base de datos de destino en tiempo real.

La replicación continua se activa haciendo clic en la casilla de verificación " Make this replication continuous " cuando se define una tarea de replicación en el IBM Cloudant Panel de control, o estableciendo el indicador " continuous " en la API IBM Cloudant API.

La réplica bidireccional se puede convertir en continua en una o en ambas direcciones mediante el distintivo continuous.

Consulte el ejemplo siguiente que utiliza HTTP para iniciar una réplica continua:

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

Consulte el siguiente ejemplo para iniciar una replicación continua:

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

El ejemplo Go anterior requiere el siguiente bloque de importación:

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

Todos los ejemplos de Go requieren que se inicialice el objeto service. Para obtener más información, consulte los ejemplos de la Sección de autenticación de la documentación de la API.

Consulte el ejemplo siguiente de un documento JSON que define una réplica continua:

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

Otros casos de uso de la réplica

El protocolo de réplica de IBM Cloudant es compatible con otras bases de datos y bibliotecas correspondientes a diversas aplicaciones reales.

Apache CouchDB

Apache CouchDB es una base de datos de código abierto que puede comunicarse con IBM Cloudant, y que requiere una configuración mínima. Se incluyen las aplicaciones siguientes:

  • Copia de seguridad: replique los datos de IBM Cloudant en sus propias bases de datos CouchDB y tome instantáneas nocturnas de los datos para archivarlos. Envíe los datos a un servicio de copia de seguridad como Amazon Glacier.
  • Recopilación de datos locales primero: escriba los datos primero en Apache CouchDB y luego realice una réplica en IBM Cloudant para su almacenamiento a largo plazo, agregación y análisis.

PouchDB

PouchDB es una base de datos de código abierto de código abierto que permite replicar datos en ambas direcciones entre el navegador y IBM Cloudant. El hecho de almacenar los datos en un navegador web en la parte del cliente permite que las aplicaciones web funcionen incluso sin una conexión a Internet. PouchDB puede sincronizar los datos modificados con IBM Cloudant cuando hay una conexión a Internet. Para configurar la réplica desde la parte cliente se requieren unas pocas líneas de JavaScript.

Consulte el siguiente ejemplo JavaScript que utiliza PouchDB para habilitar la réplica:

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

Réplicas filtradas

Resulta útil poder eliminar algunos de los datos durante el proceso de réplica, cuando se realiza una réplica de una base de datos en otra, tal como puede ver en los siguientes ejemplos:

  • Eliminación de todos los rastreos de documentos suprimidos, para que la base de datos sea menor que la de origen.
  • Separar los datos en trozos más pequeños, como almacenar los datos del Reino Unido en una base de datos y los de Estados Unidos en otra.

Funciones del filtro de réplica

La réplica filtrada de IBM Cloudant permite definir una función JavaScript que utiliza el valor de retorno para determinar si cada documento de una base de datos se ha filtrado o no. Las funciones de filtro se guardan en documentos de diseño.

Consulte la función de filtro del ejemplo siguiente para la réplica de documentos no suprimidos:

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

Cuando se inicia un trabajo de réplica, se especifica el nombre de una función de filtro como una combinación del documento de diseño en el que se almacenan los datos y el nombre de la función de filtro. También puede especificar un valor query_params. Este valor es un objeto que contiene propiedades que se pasan a la función de filtro en el campo query de su segundo argumento (req).

Consulte el ejemplo siguiente que utiliza HTTP para iniciar una réplica filtrada:

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

Consulte el ejemplo siguiente que utilizar la línea de mandatos para iniciar una réplica filtrada:

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

El ejemplo Go anterior requiere el siguiente bloque de importación:

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

Todos los ejemplos de Go requieren que se inicialice el objeto service. Para obtener más información, consulte los ejemplos de la Sección de autenticación de la documentación de la API.

Consulte el ejemplo siguiente de un documento JSON que define una réplica filtrada:

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

Canal de información de cambios

IBM Cloudant publica los añadidos, ediciones y borrados que afectan a una base de datos a través de un único feed HTTP desde el punto final '_changes'. La aplicación puede utilizar este canal de información para activar sucesos. Puede acceder al canal de información mediante HTTP o curl, tal como se muestra en los ejemplos. El uso de la opción feed=continuous significa que la corriente de datos le ofrece cada cambio necesario para obtener la versión más reciente de cada documento de la base de datos.

Para obtener más información, consulte Utilización de las preguntas más frecuentes sobre el canal de información de cambios de IBM Cloudant.

Consulte el ejemplo siguiente que utiliza HTTP para consultar el canal de información de cambios:

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

Consulte el ejemplo siguiente que utiliza la línea de mandatos para consultar el canal de información de cambios:

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

Los cambios se describen mediante una línea por cambio. Cada cambio consta de:

  1. Una serie de caracteres que contiene un número de secuencia (seq).
  2. Una serie de caracteres que contiene el ID del documento que se ha modificado.
  3. Una matriz de cambios.

Para ver propio cuerpo del documento, añada &include_docs=true al mandato curl.

Cada cambio se describe utilizando el formato que se muestra en el siguiente ejemplo (abreviado).

Consulte canal de información _changes de ejemplo siguiente:

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

Para unir el canal de información de cambios a partir de una posición conocida, pase un argumento since con el número de secuencia por el que desea comenzar.

Consulte el ejemplo siguiente (abreviado) que utiliza HTTP para suministrar la opción since con el fin de unir un canal de información _changes en una posición conocida:

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

Consulte el ejemplo siguiente (abreviado) que utiliza la línea de mandatos para suministrar la opción since con el fin de unir un canal de información _changes en una posición conocida:

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

Para volver a unir el canal de información de cambios desde el momento actual, defina since=now.

Consulte el ejemplo siguiente que utiliza HTTP para suministrar since=now con el fin de unir un canal de información _changes en el momento actual:

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

Consulte el ejemplo siguiente que utiliza la línea de mandatos para suministrar since=now con el fin de unir un canal de información _changes en el momento actual:

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

El acceso a los datos _changes mediante programación es muy sencillo. Por ejemplo, consulte los ejemplos de SDK en la documentación de la API deIBM Cloudant para seguir los cambios con algunas líneas de código.

La lista siguiente incluye algunos casos prácticos de ejemplo:

  • Adición de elementos a una cola de mensajes para activar acciones dentro de la aplicación, como por ejemplo el envío de un correo electrónico al cliente.
  • Actualización de una base de datos en memoria para registrar recuentos dinámicos de actividad.
  • Escritura de datos en un archivo de texto para enviar datos por push a una base de datos SQL.

El canal de información de cambios se puede filtrar con una función de filtro, utilizando una técnica parecida a la de filtrado durante la réplica.

Consulte el ejemplo siguiente que utiliza HTTP para filtrar el canal de información de cambios:

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

Consulte el ejemplo siguiente que utiliza la línea de mandatos para filtrar el canal de información de cambios:

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

El orden de los documentos dentro del canal de información _changes no siempre es el mismo. Es decir, es posible que los cambios no aparezcan en estricto orden cronológico. El motivo es que los datos se devuelven desde varios nodos de IBM Cloudant, y se aplican reglas de coherencia final.

Inconvenientes de la réplica

Para realizar la réplica correctamente, la suma del tamaño de documento y el tamaño de todos los archivos adjuntos debe ser menor que el tamaño máximo de solicitud del clúster de destino. Por ejemplo, si el tamaño máximo de solicitud HTTP es de 11 MB, se aplicarán los casos de ejemplo siguientes:

Varios escenarios basados en el tamaño máximo de solicitud HTTP 11 MB
Tamaño de documento Tamaño de archivo adjunto Tamaño total ¿Se replica?
1 MB Cinco archivos adjuntos de 2 MB 11 MB
1 MB Un archivo adjunto de 10 MB 11 MB
1 MB Cien archivos adjuntos de 1 MB 101 MB No

Debe tener en cuenta varias consideraciones cuando utilice la réplica.

Permisos de usuario incorrectos

Para que la réplica se ejecute de forma óptima cuando se realiza una réplica de la base de datos "a" en la base de datos "b", las credenciales que se especifiquen deben tener:

  • Los permisos _reader y _replicator sobre la base de datos "a".
  • Los permisos _writer sobre la base de datos "b".

Las claves API se generan en el IBM Cloudant O a través de la API. Se pueden otorgar a cada clave permisos individuales con relación a una determinada base de datos de IBM Cloudant. IBM Cloudant debe poder escribir sus documentos de punto de comprobación en el extremo "de lectura" de la réplica; de lo contrario no se guarda ningún estado y la réplica no se puede reanudar desde donde se detuvo. Si el estado no se guarda, pueden producirse problemas de rendimiento cuando se reanuda una réplica de grandes conjuntos de datos. El motivo es que, sin puntos de comprobación, el proceso de réplica se reinicia desde el principio cada vez que se reanuda.

El documento de réplica es conflictivo

Otra consecuencia de establecer incorrectamente los permisos de usuario es que el documento _replicator se convierte en conflictivo. El documento _replicator registra el estado actual del proceso de réplica. En un caso extremo, el documento puede llegar a ser inmenso porque contiene muchos conflictos sin resolver. Este tipo de documentos muy grandes utilizan gran parte del espacio disponible y generan una carga adicional en el servidor.

Puede comprobar el tamaño de la base de datos _replicator enviando una solicitud GET al punto 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))

El ejemplo Go anterior requiere el siguiente bloque de importación:

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

Todos los ejemplos de Go requieren que se inicialice el objeto service. Para obtener más información, consulte los ejemplos de la Sección de autenticación de la documentación de la API.

Obtener conflictos del documento de réplica

En el documento JSON que se devuelve, busque el valor de disk_size. Si el valor indica un tamaño de más de 1 GB, vaya al Portal de soporte de IBM Cloud para obtener más ayuda.

Puede comprobar si existen conflictos en un documento _replicator individual, tal como se muestra en el siguiente ejemplo:

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

El ejemplo Go anterior requiere el siguiente bloque de importación:

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

Todos los ejemplos de Go requieren que se inicialice el objeto service. Para obtener más información, consulte los ejemplos de la Sección de autenticación de la documentación de la API.

Cancelar todas las réplicas

Si desea cancelar todas las réplicas y empezar con una base de datos _replicator nueva, suprima y vuelva a crear la base de datos replicator.

Consulte el siguiente HTTP para eliminar y volver a crear la base de datos ' _replicator:

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

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

Suprimir la base de datos de replicador

Consulte el ejemplo siguiente para eliminar la base de datos _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))

El ejemplo Go anterior requiere el siguiente bloque de importación:

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

Todos los ejemplos de Go requieren que se inicialice el objeto service. Para obtener más información, consulte los ejemplos de la Sección de autenticación de la documentación de la API.

Volver a crear la base de datos de replicador

Consulte el ejemplo siguiente para volver a crear la base de datos _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))

El ejemplo Go anterior requiere el siguiente bloque de importación:

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

Todos los ejemplos de Go requieren que se inicialice el objeto service. Para obtener más información, consulte los ejemplos de la Sección de autenticación de la documentación de la API.

Muchas réplicas simultáneas

Es fácil olvidar que anteriormente se ha configurado una réplica entre dos bases de datos y crear erróneamente procesos de réplica adicionales. Cada trabajo de réplica es independiente de los demás, de modo que IBM Cloudant no impide que cree procesos de réplica adicionales. Sin embargo, cada tarea de réplica utiliza recursos del sistema.

Puede comprobar sus "réplicas activas" en el panel de control de IBM Cloudant para asegurarse de que no hay tareas de réplica no deseadas en curso. Suprima los documentos _replicator que ya no necesite.

Ajuste de la velocidad de réplica

De forma predeterminada, La réplica de IBM Cloudant se ejecuta a una velocidad adecuada para obtener los datos del origen para el destino sin afectar negativamente al rendimiento. Lo ideal es encontrar el equilibrio entre ritmo de réplica y rendimiento del clúster para otras tareas. En algunos casos quizás sea preferible una réplica más rápida a costa de otros servicios de IBM Cloudant. También es posible que tenga que dar prioridad al rendimiento del clúster y tratar la réplica como proceso de fondo.

Hay Opciones avanzadas de API de réplica disponibles. Estas opciones permiten aumentar o reducir la cantidad de potencia de cálculo que se utiliza durante la réplica, tal como se muestra en los ejemplos siguientes:

  • Si los documentos contienen archivos adjuntos, tenga en cuenta la posibilidad de reducir el valor de batch_size y de aumentar el valor de worker_processes para dar cabida a documentos mayores en lotes más pequeños.
  • Si tiene muchos documentos pequeños, tenga en cuenta la posibilidad de aumentar los valores de worker_process y http_connections.
  • Si desea ejecutar la réplica con un impacto mínimo, establecer worker_processes y http_connections en 1 puede ser lo adecuado.
  • Para obtener más información, consulte Consumo de operaciones de lectura y escritura por réplica.

Para obtener más ayuda sobre la mejor configuración para su caso de uso, vaya al Portal de soporte de IBM Cloud.

El rendimiento de réplica se puede mejorar habilitando la opción de réplica "use_bulk_get": true". En ese caso, el replicador capta documentos del origen en lotes en lugar de individualmente.

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

El aumento de la velocidad de réplica puede consumir la capacidad de velocidad de lectura o escritura disponible en las cuentas de punto final de origen y destino.

Eliminación de revisiones de documentos en conflicto con la réplica

Una forma de eliminar revisiones de documentos en conflicto a través de la réplica es habilitando la opción "winning_revs_only": true. Esta opción sólo replica las revisiones de documento ganadoras. Es la revisión devuelta de forma predeterminada por una solicitud GET $SERVICE_URL/$DATABASE/$DOCID. Esta opción es una opción avanzada, ya que descarta revisiones de documentos en conflicto. Utilice esta opción con precaución.