Replicación entre centros de datos (XDCR) en Couchbase ofrece una forma sencilla de replicar datos de un clúster a otro. Los clústeres suelen estar situados en zonas geográficas diferentes.
diversos centros de datos. Esto permite la recuperación en caso de desastre o acercar los datos a los usuarios para un acceso más rápido a los mismos. En este blog se mostrará:
- Configurar dos centros de datos con Docker Swarm
- Ejecutar contenedores Couchbase en cada nodo de Docker Swarm
- Configurar un clúster Couchbase en cada clúster Docker Swarm
- Configurar XDCR unidireccional entre dos clusters Couchbase
Para el propósito de este blog, los dos centros de datos se configurarán en una máquina local utilizando Docker Machine.

El código completo utilizado en este blog está disponible en: github.com/arun-gupta/couchbase-xdcr-docker.
Crear el servicio Consul Discovery
Cada nodo en Docker Swarm necesita estar registrado con un servicio de descubrimiento. Este blog utilizará Consul para ese propósito. E incluso Consul se ejecutará en una máquina Docker. Típicamente, ejecutarás
un cluster de Consul pero por simplicidad en nuestro caso se arrancará una única instancia. Crea una máquina Docker e inicia Consul usando este script:
|
1 2 3 4 5 6 7 8 9 10 11 |
# Máquina Docker para Consul docker-máquina crear -d virtualbox cónsul-máquina # Inicio Cónsul docker $(docker-máquina config cónsul-máquina) ejecute -d --reiniciar=siempre -p "8500:8500" -h "cónsul" progrium/cónsul -servidor -arranque |
Crear clúster Docker Swarm
Docker Swarm permite que varios hosts Docker se vean como una sola unidad. Esto permite que sus aplicaciones multicontenedor se ejecuten fácilmente en varios hosts. Docker Swarm sirve lo mismo API remota servido por un único host. Esto permite que sus herramientas existentes se dirijan a un único host o a un clúster de hosts. Ambos clústeres de Docker Swarm se registrarán con un único servicio de descubrimiento. Esto se consigue utilizando el siguiente valor para
--swarm-discovery:
|
1 |
cónsul://$(docker-machine ip consul-machine):8500/v1/kv/ |
Crear un cluster Docker Swarm usando Docker Machine usando este script:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# Docker Swarm maestro docker-máquina crear -d virtualbox --enjambre --enjambre-maestro --enjambre-descubrimiento="consul://$(docker-machine ip consul-machine):8500/v1/kv/cluster$1" --motor-op="cluster-store=consul://$(docker-machine ip consul-machine):8500/v1/kv/cluster$1" --motor-op="cluster-advertise=eth1:2376" enjambre-maestro-$1 # Enjambre Docker nodo-01 docker-máquina crear -d virtualbox --enjambre --enjambre-descubrimiento="consul://$(docker-machine ip consul-machine):8500/v1/kv/cluster$1" --motor-op="cluster-store=consul://$(docker-machine ip consul-machine):8500/v1/kv/cluster$1" --motor-op="cluster-advertise=eth1:2376" enjambre-nodo-$1-01 # Enjambre Docker nodo-02 docker-máquina crear -d virtualbox --enjambre --enjambre-descubrimiento="consul://$(docker-machine ip consul-machine):8500/v1/kv/cluster$1" --motor-op="cluster-store=consul://$(docker-machine ip consul-machine):8500/v1/kv/cluster$1" --motor-op="cluster-advertise=eth1:2376" enjambre-nodo-$1-02 # Configurar para utilizar el clúster Docker Swarm evalúe "$(docker-machine env --swarm swarm-master-$1)" |
El script debe ser invocado como:
|
1 2 |
./crear-docker-enjambre-grupo.sh A ./crear-docker-enjambre-grupo.sh B |
Esto creará dos clusters Docker Swarm con un "master" y dos "worker" como se muestra a continuación:
|
1 2 3 4 5 6 7 8 9 |
NOMBRE ACTIVO CONDUCTOR ESTADO URL SWARM DOCKER ERRORES cónsul-máquina - virtualbox Ejecutar tcp://192.168.99.101:2376 v1.11.1 por defecto * virtualbox Ejecutar tcp://192.168.99.100:2376 v1.11.1 enjambre-maestro-A - virtualbox Ejecutar tcp://192.168.99.102:2376 swarm-master-A (maestro) v1.11.1 enjambre-maestro-B - virtualbox Ejecutar tcp://192.168.99.105:2376 swarm-master-B (maestro) v1.11.1 enjambre-nodo-A-01 - virtualbox Ejecutar tcp://192.168.99.103:2376 swarm-master-A v1.11.1 enjambre-nodo-A-02 - virtualbox Ejecutar tcp://192.168.99.104:2376 swarm-master-A v1.11.1 enjambre-nodo-B-01 - virtualbox Ejecutar tcp://192.168.99.106:2376 swarm-master-B v1.11.1 enjambre-nodo-B-02 - virtualbox Ejecutar tcp://192.168.99.107:2376 swarm-master-B v1.11.1 |
Consul se está ejecutando en una máquina Docker con dirección IP 192.168.99.101. Y así, Consul UI es accesible en https://192.168.99.101:8500:
Muestra dos clusters Docker Swarm que han sido registrados. También se puede ver la lista exacta de nodos de cada clúster. Nodos en clusterA se muestran: 
Nodos en clusterB se muestran:

Ejecutar contenedores Couchbase
Ejecuta el contenedor Couchbase en cada nodo del cluster Docker Swarm usando esto Componer fichero.
|
1 2 3 4 5 6 7 8 9 10 |
versión: "2" servicios: db: imagen: arungupta/couchbase modo_red: "anfitrión" puertos: - 8091:8091 - 8092:8092 - 8093:8093 - 11210:11210 |
Configura Docker CLI para el primer cluster y ejecuta 3 contenedores:
|
1 2 |
evalúe "$(docker-machine env --swarm swarm-master-A)" docker-componer escala db=3 |
Comprueba los contenedores en funcionamiento:
|
1 2 3 4 5 |
> docker ps CONTENEDOR ID IMAGEN COMANDO CREADO ESTADO PUERTOS NOMBRES 3ec0f15aaee0 arungupta/couchbase "/entrypoint.sh /opt/" 3 horas hace Arriba 3 horas enjambre-maestro-A/couchbasexdcrdocker_db_3 07af2ac53539 arungupta/couchbase "/entrypoint.sh /opt/" 3 horas hace Arriba 3 horas enjambre-nodo-A-02/couchbasexdcrdocker_db_2 c94878f543fd arungupta/couchbase "/entrypoint.sh /opt/" 3 horas hace Arriba 3 horas enjambre-nodo-A-01/couchbasexdcrdocker_db_1 |
Configura Docker CLI para el segundo cluster y ejecuta 3 contenedores:
|
1 2 |
evalúe "$(docker-machine env --swarm swarm-master-B)" docker-componer escala db=3 |
Comprueba los contenedores en funcionamiento:
|
1 2 3 4 5 6 |
> evalúe "$(docker-machine env --swarm swarm-master-B)" > docker ps CONTENEDOR ID IMAGEN COMANDO CREADO ESTADO PUERTOS NOMBRES 3e3a45480939 arungupta/couchbase "/entrypoint.sh /opt/" 3 horas hace Arriba 3 horas enjambre-maestro-B/couchbasexdcrdocker_db_3 1f31f23e337d arungupta/couchbase "/entrypoint.sh /opt/" 3 horas hace Arriba 3 horas enjambre-nodo-B-01/couchbasexdcrdocker_db_1 1feab04c494c arungupta/couchbase "/entrypoint.sh /opt/" 3 horas hace Arriba 3 horas enjambre-nodo-B-02/couchbasexdcrdocker_db_2 |
Crear/Reeequilibrar clúster Couchbase
Escalado y Reequilibrado del Cluster Couchbase usando CLI explica cómo crear un clúster de nodos Couchbase y reequilibrar un clúster existente utilizando Couchbase CLI.
Crear cluster Couchbase en cada cluster Swarm usando este script.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
exportar COUCHBASE_CLI=/Usuarios/arungupta/herramientas/Couchbase-Servidor-4.0.app/Contenido/Recursos/couchbase-núcleo/papelera/couchbase-cli para nodo en 01 02 do $COUCHBASE_CLI servidor-añada --grupo=$(docker-máquina ip enjambre-maestro-$1):8091 --usuario Administrador --contraseña contraseña --servidor-añada=$(docker-máquina ip enjambre-nodo-$1-$nodo) --servidor-añada-nombre de usuario=Administrador --servidor-añada-contraseña=contraseña hecho $COUCHBASE_CLI ajuste-grupo --grupo=$(docker-máquina ip enjambre-maestro-$1):8091 --usuario Administrador --contraseña contraseña --grupo-nombre=grupo$1 |
El script debe ser invocado como:
|
1 |
./crear-couchbase-grupo.sh A |
Y ahora reequilibra este cluster usando este script:
|
1 2 3 4 5 6 7 8 |
exportar COUCHBASE_CLI=/Usuarios/arungupta/herramientas/Couchbase-Servidor-4.0.app/Contenido/Recursos/couchbase-núcleo/papelera/couchbase-cli $COUCHBASE_CLI reequilibrar --grupo=$(docker-máquina ip enjambre-maestro-$1):8091 --usuario Administrador --contraseña contraseña --servidor-añada-nombre de usuario=Administrador --servidor-añada-contraseña=contraseña |
Este script se invoca como:
|
1 |
./reequilibrar-couchbase-grupo.sh A |
Consola web de Couchbase para cualquier nodo del cluster mostrará la salida:

Invoca este script para crear el segundo cluster de Couchbase como:
|
1 |
./crear-couchbase-grupo.sh B |
Reequilibrar este grupo como:
|
1 |
./reequilibrar-couchbase-grupo.sh B |
Couchbase Web Console para cualquier nodo en el segundo cluster mostrará la salida: 
Configurar XDCR
La replicación entre centros de datos puede configurarse como unidireccional, bidireccional o multidireccional. La unidireccional permite que los datos se repliquen del clúster de origen al de destino, la bidireccional permite la replicación en ambos sentidos, la multidireccional
permite configurar en cualquier dirección. Crearemos una replicación unidireccional sencilla utilizando este script:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
exportar COUCHBASE_CLI=/Usuarios/arungupta/herramientas/Couchbase-Servidor-4.0.app/Contenido/Recursos/couchbase-núcleo/papelera/couchbase-cli $COUCHBASE_CLI xdcr-configuración --grupo=$(docker-máquina ip enjambre-maestro-$1):8091 --usuario Administrador --contraseña contraseña --crear --xdcr-grupo-nombre=grupo$1 --xdcr-nombre de host=$(docker-máquina ip enjambre-maestro-$2):8091 --xdcr-nombre de usuario=Administrador --xdcr-contraseña=contraseña --xdcr-demanda-encriptación=0 $COUCHBASE_CLI xdcr-replicar --grupo $(docker-máquina ip enjambre-maestro-$1):8091 --xdcr-grupo-nombre=grupo$1 --usuario Administrador --contraseña contraseña --crear --xdcr-de-cubo=viaje-muestra --xdcr-a-cubo=viaje-muestra |
Este script se invoca como:
|
1 |
./configuración-xdcr.sh A B |
Se puede crear fácilmente una replicación bidireccional ejecutando de nuevo los comandos pero invirtiendo el cluster de origen y el de destino. La Consola Web de Couchbase para el cluster de origen mostrará:

Se mostrará la Consola Web de Couchbase para el cluster de destino:

¡Que aproveche!
Este blog muestra cómo puede simplificar sus despliegues complejos utilizando Docker Machine, Docker Swarm y Docker Compose.

Hola, he seguido tu post aquí para configurar 2 couchbase cluster 3 nodo porque yo uso el modo enjambre docker :
https://www.couchbase.com/docker-service-swarm-mode-couchbase-cluster/
Usé vagrant con el modo docker swarm. Parecía funcionar bien. Pero cuando traté de configurar XDCR a través de WebUI, recibí el siguiente error :
Atención - 2017-04-07 15:13:09 10.0.0.6:CheckpointMgr:Failed to get starting seqno for pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-903583530
Atención - 2017-04-07 15:13:02 10.0.0.3:CheckpointMgr:Failed to get starting seqno for pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-908871718
Atención - 2017-04-07 15:12:58 10.0.0.5:CheckpointMgr:Failed to get starting seqno for pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-259497001
Cuando eché un vistazo en goxdcr.log, encontré algo así :
GenericPipeline 2017-04-07T15:14:07.863Z [DEBUG] 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-413659460 llamando al constructor de actualización de ajustes en el contexto de tiempo de ejecución con settings=map[VBTimestamps:map[300:[vbno=300, uuid=0, seqno=0, sn_start=0, sn_end=0]].
GenericSupervisor 2017-04-07T15:14:07.863Z [DEBUG] Actualizando configuración en pipelineSupervisor PipelineSupervisor_690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr. settings=map[pipeline_loglevel:Debug]
CheckpointManager 2017-04-07T15:14:07.864Z [DEBUG] Actualizando configuración en el gestor de puntos de control para la tubería 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr. settings=map[checkpoint_interval:1800]
StatisticsManager 2017-04-07T15:14:07.864Z [DEBUG] Actualizando la configuración del gestor de estadísticas. settings=map[publish_interval:1000]
CheckpointManager 2017-04-07T15:14:07.864Z [DEBUG] 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr Set VBTimestamp for vb=300 completed
GenericSupervisor 2017-04-07T15:14:07.864Z [ERROR] Recibido informe de error : map[CheckpointMgr:Failed to get starting seqno for pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-413659460].
ReplicationManager 2017-04-07T15:14:07.864Z [INFO] Supervisor PipelineSupervisor_690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr de tipo *supervisor.GenericSupervisor informó de errores map[CheckpointMgr:Failed to get starting seqno for pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-413659460].
PipelineManager 2017-04-07T15:14:07.865Z [INFO] Pipeline updater 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr is lauched with retry_interval=10
CheckpointManager 2017-04-07T15:14:07.865Z [INFO] Finalizado SetVBTimestamps
PipelineManager 2017-04-07T15:14:07.865Z [INFO] err_list=[{"time": "2017-04-07T15:14:07.865641343Z", "errMsg": "CheckpointMgr:Failed to get starting seqno for pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-413659460″}]
PipelineManager 2017-04-07T15:14:07.865Z [INFO] Updater 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr movido a 1 desde 0
DcpNozzle 2017-04-07T15:14:07.892Z [DEBUG] dcp_690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr_10.0.0.3:11210_0 iniciando flujo vb para vb=100, opaque=38204
DcpNozzle 2017-04-07T15:14:07.892Z [DEBUG] dcp_690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr_10.0.0.3:11210_0 iniciando flujo vb para vb=0, opaque=38204
_time=2017-04-07T15:14:07.893+00:00 _level=INFO _msg=UPR_STREAMREQ for vb 100 successful
_time=2017-04-07T15:14:07.893+00:00 _level=INFO _msg=UPR_STREAMREQ for vb 0 successful
DcpNozzle 2017-04-07T15:14:07.908Z [DEBUG] dcp_690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr_10.0.0.3:11210_1 iniciando flujo vb para vb=300, opaque=38205
DcpNozzle 2017-04-07T15:14:07.908Z [DEBUG] dcp_690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr_10.0.0.3:11210_1 iniciando flujo vb para vb=200, opaque=38205
_time=2017-04-07T15:14:07.909+00:00 _level=INFO _msg=UPR_STREAMREQ for vb 300 successful
_time=2017-04-07T15:14:07.909+00:00 _level=INFO _msg=UPR_STREAMREQ for vb 200 successful
GenericSupervisor 2017-04-07T15:14:08.074Z [DEBUG] latido del corazón async llamado
GenericSupervisor 2017-04-07T15:14:08.074Z [DEBUG] respondió al latido del corazón enviado en 2017-04-07 15:14:08.074118904 +0000 UTC
StatisticsManager 2017-04-07T15:14:08.564Z [INFO] La tubería ya no se está ejecutando, exit.
StatisticsManager 2017-04-07T15:14:08.564Z [INFO] expvar=Stats para canalización 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-413659460 {"Errores": "[{\"time\":\"2017-04-07T15:14:07.865641343Z\",\"errMsg\":\"CheckpointMgr:Failed to get starting seqno for pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-413659460"}"}", "Overview": {"": 0, "bandwidth_usage": 0, "changes_left": 1, "data_replicated": 0, "dcp_datach_length": 0, "dcp_dispatch_time": 0, "deletion_docs_written": 0, "deletion_failed_cr_source": 0, "deletion_filtered": 0, "deletion_received_from_dcp": 0, "docs_checked": 0, "docs_failed_cr_source": 0, "docs_filtered": 0, "docs_opt_repd": 0, "docs_processed": 0, "docs_received_from_dcp": 0, "docs_rep_queue": 0, "docs_written": 0, "expiry_docs_written": 0, "expiry_failed_cr_source": 0, "expiry_filtered": 0, "expiry_received_from_dcp": 0, "num_checkpoints": 0, "num_failedckpts": 0, "rate_doc_checks": 0, "rate_doc_opt_repd": 0, "rate_received_from_dcp": 0, "rate_replicated": 0, "resp_wait_time": 0, "set_docs_written": 0, "set_failed_cr_source": 0, "set_filtered": 0, "set_received_from_dcp": 0, "size_rep_queue": 0, "time_committing": 0, "wtavg_docs_latency": 0, "wtavg_meta_latency": 0}, "Progress": "Received error report : map[CheckpointMgr:Failed to get starting seqno for pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-413659460]", "Status": "Pending"}
¿Puede decirme a qué se debe este error y cómo solucionarlo?
Saludos cordiales.