Replicação entre centros de dados (XDCR) no Couchbase oferece uma maneira fácil de replicar dados de um cluster para outro. Em geral, os clusters são definidos em locais geograficamente
diversos data centers. Isso permite a recuperação de desastres ou a aproximação dos dados dos usuários para um acesso mais rápido aos dados. Este blog mostrará:
- Configurar dois data centers usando o Docker Swarm
- Execute contêineres do Couchbase em cada nó do Docker Swarm
- Configure um cluster do Couchbase em cada cluster do Docker Swarm
- Configurar XDCR unidirecional entre dois clusters do Couchbase
Para os fins deste blog, os dois data centers serão configurados em uma máquina local usando o Docker Machine.

O código completo usado neste blog está disponível em: github.com/arun-gupta/couchbase-xdcr-docker.
Criar o serviço de descoberta da Consul
Cada nó no Docker Swarm precisa ser registrado com um serviço de descoberta. Este blog usará o Consul para essa finalidade. E até mesmo o Consul será executado em uma máquina Docker. Normalmente, você executará o
um cluster do Consul, mas, para simplificar, uma única instância será iniciada em nosso caso. Crie uma máquina Docker e inicie o Consul usando este script:
|
1 2 3 4 5 6 7 8 9 10 11 |
# Docker Machine for Consul docker-machine create -d virtualbox consul-machine # Start Consul docker $(docker-machine config consul-machine) run -d --restart=always -p "8500:8500" -h "consul" progrium/consul -server -bootstrap |
Criar um cluster do Docker Swarm
O Docker Swarm permite que vários hosts do Docker sejam vistos como uma única unidade. Isso permite que seus aplicativos com vários contêineres sejam executados facilmente em vários hosts. O Docker Swarm serve o mesmo API remota como servido por um único host. Isso permite que suas ferramentas existentes tenham como alvo um único host ou um cluster de hosts. Os dois clusters do Docker Swarm serão registrados em um único serviço de descoberta. Isso é obtido com o uso do seguinte valor para
--swarm-discovery:
|
1 |
consul://$(docker-machine ip consul-machine):8500/v1/kv/ |
Criar um cluster do Docker Swarm usando o Docker Machine 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 master docker-machine create -d virtualbox --swarm --swarm-master --swarm-discovery="consul://$(docker-machine ip consul-machine):8500/v1/kv/cluster$1" --engine-opt="cluster-store=consul://$(docker-machine ip consul-machine):8500/v1/kv/cluster$1" --engine-opt="cluster-advertise=eth1:2376" swarm-master-$1 # Docker Swarm node-01 docker-machine create -d virtualbox --swarm --swarm-discovery="consul://$(docker-machine ip consul-machine):8500/v1/kv/cluster$1" --engine-opt="cluster-store=consul://$(docker-machine ip consul-machine):8500/v1/kv/cluster$1" --engine-opt="cluster-advertise=eth1:2376" swarm-node-$1-01 # Docker Swarm node-02 docker-machine create -d virtualbox --swarm --swarm-discovery="consul://$(docker-machine ip consul-machine):8500/v1/kv/cluster$1" --engine-opt="cluster-store=consul://$(docker-machine ip consul-machine):8500/v1/kv/cluster$1" --engine-opt="cluster-advertise=eth1:2376" swarm-node-$1-02 # Configure to use Docker Swarm cluster eval "$(docker-machine env --swarm swarm-master-$1)" |
O script precisa ser chamado como:
|
1 2 |
./create-docker-swarm-cluster.sh A ./create-docker-swarm-cluster.sh B |
Isso criará dois clusters do Docker Swarm com um "mestre" e dois "trabalhadores", conforme mostrado abaixo:
|
1 2 3 4 5 6 7 8 9 |
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS consul-machine - virtualbox Running tcp://192.168.99.101:2376 v1.11.1 default * virtualbox Running tcp://192.168.99.100:2376 v1.11.1 swarm-master-A - virtualbox Running tcp://192.168.99.102:2376 swarm-master-A (master) v1.11.1 swarm-master-B - virtualbox Running tcp://192.168.99.105:2376 swarm-master-B (master) v1.11.1 swarm-node-A-01 - virtualbox Running tcp://192.168.99.103:2376 swarm-master-A v1.11.1 swarm-node-A-02 - virtualbox Running tcp://192.168.99.104:2376 swarm-master-A v1.11.1 swarm-node-B-01 - virtualbox Running tcp://192.168.99.106:2376 swarm-master-B v1.11.1 swarm-node-B-02 - virtualbox Running tcp://192.168.99.107:2376 swarm-master-B v1.11.1 |
O Consul está sendo executado em uma máquina Docker com endereço IP 192.168.99.101. Assim, a interface do usuário da Consul pode ser acessada em https://192.168.99.101:8500:
Ele mostra dois clusters do Docker Swarm que foram registrados. A lista exata de nós para cada cluster também pode ser vista. Nós em clusterA são mostrados: 
Nós em clusterB são mostrados:

Executar contêineres do Couchbase
Execute o contêiner do Couchbase em cada nó do cluster do Docker Swarm usando o seguinte Compor arquivo.
|
1 2 3 4 5 6 7 8 9 10 |
version: "2" services: db: image: arungupta/couchbase network_mode: "host" ports: - 8091:8091 - 8092:8092 - 8093:8093 - 11210:11210 |
Configure o Docker CLI para o primeiro cluster e execute 3 contêineres:
|
1 2 |
eval "$(docker-machine env --swarm swarm-master-A)" docker-compose scale db=3 |
Verifique os contêineres em execução:
|
1 2 3 4 5 |
> docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3ec0f15aaee0 arungupta/couchbase "/entrypoint.sh /opt/" 3 hours ago Up 3 hours swarm-master-A/couchbasexdcrdocker_db_3 07af2ac53539 arungupta/couchbase "/entrypoint.sh /opt/" 3 hours ago Up 3 hours swarm-node-A-02/couchbasexdcrdocker_db_2 c94878f543fd arungupta/couchbase "/entrypoint.sh /opt/" 3 hours ago Up 3 hours swarm-node-A-01/couchbasexdcrdocker_db_1 |
Configure o Docker CLI para o segundo cluster e execute 3 contêineres:
|
1 2 |
eval "$(docker-machine env --swarm swarm-master-B)" docker-compose scale db=3 |
Verifique os contêineres em execução:
|
1 2 3 4 5 6 |
> eval "$(docker-machine env --swarm swarm-master-B)" > docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3e3a45480939 arungupta/couchbase "/entrypoint.sh /opt/" 3 hours ago Up 3 hours swarm-master-B/couchbasexdcrdocker_db_3 1f31f23e337d arungupta/couchbase "/entrypoint.sh /opt/" 3 hours ago Up 3 hours swarm-node-B-01/couchbasexdcrdocker_db_1 1feab04c494c arungupta/couchbase "/entrypoint.sh /opt/" 3 hours ago Up 3 hours swarm-node-B-02/couchbasexdcrdocker_db_2 |
Criar/Rebalancear o cluster do Couchbase
Dimensionamento e rebalanceamento do cluster do Couchbase usando a CLI explica como criar um cluster de nós do Couchbase e reequilibrar um cluster existente usando o CLI do Couchbase.
Crie o cluster do Couchbase em cada cluster do Swarm usando este script.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
export COUCHBASE_CLI=/Users/arungupta/tools/Couchbase-Server-4.0.app/Contents/Resources/couchbase-core/bin/couchbase-cli for node in 01 02 do $COUCHBASE_CLI server-add --cluster=$(docker-machine ip swarm-master-$1):8091 --user Administrator --password password --server-add=$(docker-machine ip swarm-node-$1-$node) --server-add-username=Administrator --server-add-password=password done $COUCHBASE_CLI setting-cluster --cluster=$(docker-machine ip swarm-master-$1):8091 --user Administrator --password password --cluster-name=cluster$1 |
O script precisa ser chamado como:
|
1 |
./create-couchbase-cluster.sh A |
E agora reequilibre esse cluster usando este script:
|
1 2 3 4 5 6 7 8 |
export COUCHBASE_CLI=/Users/arungupta/tools/Couchbase-Server-4.0.app/Contents/Resources/couchbase-core/bin/couchbase-cli $COUCHBASE_CLI rebalance --cluster=$(docker-machine ip swarm-master-$1):8091 --user Administrator --password password --server-add-username=Administrator --server-add-password=password |
Esse script é chamado como:
|
1 |
./rebalance-couchbase-cluster.sh A |
Console da Web do Couchbase para qualquer nó no cluster mostrará a saída:

Invoque esse script para criar o segundo cluster do Couchbase como:
|
1 |
./create-couchbase-cluster.sh B |
Rebalancear esse cluster como:
|
1 |
./rebalance-couchbase-cluster.sh B |
O Console da Web do Couchbase para qualquer nó no segundo cluster mostrará a saída: 
Configuração do XDCR
A replicação entre datacenters pode ser configurada para ser unidirecional, bidirecional ou multidirecional. A unidirecional permite que os dados sejam replicados do cluster de origem para o cluster de destino, a bidirecional permite a replicação em ambos os sentidos e a multidirecional
permite a configuração em qualquer direção. Criaremos uma replicação unidirecional simples 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 |
export COUCHBASE_CLI=/Users/arungupta/tools/Couchbase-Server-4.0.app/Contents/Resources/couchbase-core/bin/couchbase-cli $COUCHBASE_CLI xdcr-setup --cluster=$(docker-machine ip swarm-master-$1):8091 --user Administrator --password password --create --xdcr-cluster-name=cluster$1 --xdcr-hostname=$(docker-machine ip swarm-master-$2):8091 --xdcr-username=Administrator --xdcr-password=password --xdcr-demand-encryption=0 $COUCHBASE_CLI xdcr-replicate --cluster $(docker-machine ip swarm-master-$1):8091 --xdcr-cluster-name=cluster$1 --user Administrator --password password --create --xdcr-from-bucket=travel-sample --xdcr-to-bucket=travel-sample |
Esse script é chamado como:
|
1 |
./setup-xdcr.sh A B |
Uma replicação bidirecional pode ser criada facilmente executando os comandos novamente, mas invertendo o cluster de origem e de destino. O Console da Web do Couchbase para o cluster de origem será exibido:

O Console da Web do Couchbase para o cluster de destino será exibido:

Aproveite!
Este blog mostra como você pode simplificar suas implantações complexas usando o Docker Machine, o Docker Swarm e o Docker Compose.

Olá, segui sua postagem aqui para configurar 2 nós de 3 clusters do couchbase porque uso o modo docker swarm:
https://www.couchbase.com/docker-service-swarm-mode-couchbase-cluster/
Usei o vagrant com o modo docker swarm. Eles pareciam funcionar bem. Mas quando tentei configurar o XDCR via WebUI, recebi o seguinte erro :
Atenção - 2017-04-07 15:13:09 10.0.0.6:CheckpointMgr:Falha ao obter o seqno inicial para o pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-903583530
Atenção - 2017-04-07 15:13:02 10.0.0.3:CheckpointMgr:Falha ao obter o seqno inicial para o pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-908871718
Atenção - 2017-04-07 15:12:58 10.0.0.5:CheckpointMgr:Falha ao obter o seqno inicial para o pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-259497001
Quando dei uma olhada no goxdcr.log, encontrei algo assim :
GenericPipeline 2017-04-07T15:14:07.863Z [DEBUG] 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-413659460 chamando o construtor de configuração de atualização no contexto de tempo de execução com 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] Atualizando configurações no pipelineSupervisor PipelineSupervisor_690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr. settings=map[pipeline_loglevel:Debug]
CheckpointManager 2017-04-07T15:14:07.864Z [DEBUG] Atualizando as configurações no gerenciador de pontos de verificação para o pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr. settings=map[checkpoint_interval:1800]
StatisticsManager 2017-04-07T15:14:07.864Z [DEBUG] Atualizando as configurações no gerenciador de estatí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] Relatório de erro recebido: 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 do tipo *supervisor.GenericSupervisor relatou erros no mapa [CheckpointMgr:Falha ao obter o seqno inicial para o pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-413659460]
PipelineManager 2017-04-07T15:14:07.865Z [INFO] O atualizador de pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr foi lançado com retry_interval=10
CheckpointManager 2017-04-07T15:14:07.865Z [INFO] Concluído com 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] O atualizador 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr foi movido de 0 para 1
DcpNozzle 2017-04-07T15:14:07.892Z [DEBUG] dcp_690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr_10.0.0.3:11210_0 starting vb stream for vb=100, opaque=38204
DcpNozzle 2017-04-07T15:14:07.892Z [DEBUG] dcp_690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr_10.0.0.3:11210_0 starting vb stream for 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 starting vb stream for vb=300, opaque=38205
DcpNozzle 2017-04-07T15:14:07.908Z [DEBUG] dcp_690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr_10.0.0.3:11210_1 starting vb stream for 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] batimento cardíaco assíncrono chamado
GenericSupervisor 2017-04-07T15:14:08.074Z [DEBUG] respondeu ao batimento cardíaco enviado em 2017-04-07 15:14:08.074118904 +0000 UTC
StatisticsManager 2017-04-07T15:14:08.564Z [INFO] O pipeline não está mais em execução, saia.
StatisticsManager 2017-04-07T15:14:08.564Z [INFO] expvar=Stats for pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-413659460 {"Errors": "[{\"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": "Relatório de erro recebido: map[CheckpointMgr:Failed to get starting seqno for pipeline 690841985e8189a6c431bd9f25faf8a7/test-xdcr/test-xdcr-413659460]", "Status": "Pending"}
Você pode me dizer por que esse erro ocorre e como resolvê-lo, por favor?
Saudações.