📚 Estudo: CouchDB – Replicação e Cluster
1. Subindo duas instâncias isoladas para testes
Arquivo docker-compose.yml
simples com duas instâncias separadas:
version: "3.9"
services:
couchdb1:
image: couchdb:3
container_name: couchdb1
environment:
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=admin
ports:
- "5984:5984"
networks:
- couchdbnet
couchdb2:
image: couchdb:3
container_name: couchdb2
environment:
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=admin
ports:
- "5985:5984"
networks:
- couchdbnet
networks:
couchdbnet:
driver: bridge
Acesso via API / Fauxton
- Instância 1:
http://localhost:5984/_utils/
- Instância 2:
http://localhost:5985/_utils/
Login:admin
/admin
.
2. Replicação entre duas instâncias
2.1 Replicação pontual (one-shot)
# Criar base na origem
curl -X PUT http://admin:admin@localhost:5984/minha_base
# Inserir documento exemplo
curl -X POST http://admin:admin@localhost:5984/minha_base \
-H "Content-Type: application/json" \
-d '{"_id":"doc1","tipo":"exemplo","ok":true}'
# Replicar origem -> destino
curl -X POST http://admin:admin@localhost:5984/_replicate \
-H "Content-Type: application/json" \
-d '{
"source": "http://admin:admin@localhost:5984/minha_base",
"target": "http://admin:admin@localhost:5985/minha_base",
"create_target": true
}'
2.2 Replicação contínua (_replicator
)
# Criar DB de replicações (se não existir)
curl -X PUT http://admin:admin@localhost:5984/_replicator
# Criar replicação contínua
curl -X POST http://admin:admin@localhost:5984/_replicator \
-H "Content-Type: application/json" \
-d '{
"_id": "replica-minha_base-para-5985",
"source": "http://admin:admin@localhost:5984/minha_base",
"target": "http://admin:admin@localhost:5985/minha_base",
"create_target": true,
"continuous": true,
"user_ctx": { "name": "admin", "roles": ["_admin"] }
}'
2.3 Replicação com filtro
Criar filtro:
curl -X PUT http://admin:admin@localhost:5984/minha_base/_design/rep \
-H "Content-Type: application/json" \
-d '{
"filters": {
"somente_tipo_exemplo": "function(doc, req) { return doc.tipo === \"exemplo\"; }"
}
}'
Usar filtro na replicação:
curl -X POST http://admin:admin@localhost:5984/_replicate \
-H "Content-Type: application/json" \
-d '{
"source": "http://admin:admin@localhost:5984/minha_base",
"target": "http://admin:admin@localhost:5985/minha_base",
"create_target": true,
"filter": "rep/somente_tipo_exemplo"
}'
3. Configurando um Cluster
3.1 docker-compose.yml
para cluster
version: "3.9"
services:
couchdb1:
image: couchdb:3
container_name: couchdb1
hostname: couchdb1
environment:
- NODENAME=couchdb@couchdb1
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=admin
- COUCHDB_SECRET=super-secret-long-random-string
- ERL_FLAGS=-setcookie couchdb-cluster-cookie
ports:
- "5984:5984"
volumes:
- c1data:/opt/couchdb/data
networks:
- couchdbnet
couchdb2:
image: couchdb:3
container_name: couchdb2
hostname: couchdb2
environment:
- NODENAME=couchdb@couchdb2
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=admin
- COUCHDB_SECRET=super-secret-long-random-string
- ERL_FLAGS=-setcookie couchdb-cluster-cookie
ports:
- "5985:5984"
volumes:
- c2data:/opt/couchdb/data
networks:
- couchdbnet
networks:
couchdbnet:
driver: bridge
volumes:
c1data:
c2data:
Importante:
NODENAME
diferente por nó, mas mesmoCOUCHDB_SECRET
e cookie (-setcookie
).- Ambos na mesma rede
couchdbnet
.
3.2 Configuração via API
USER=admin
PASS=admin
# Checar nós
curl -s http://$USER:$PASS@localhost:5984/ | jq .
curl -s http://$USER:$PASS@localhost:5985/ | jq .
# 1) Habilitar cluster no nó 1
curl -s -X POST http://$USER:$PASS@localhost:5984/_cluster_setup \
-H "Content-Type: application/json" \
-d '{
"action":"enable_cluster",
"bind_address":"0.0.0.0",
"username":"'"$USER"'",
"password":"'"$PASS"'",
"port":5984,
"node_count":"2",
"remote_node":"couchdb2",
"remote_current_user":"'"$USER"'",
"remote_current_password":"'"$PASS"'"
}' | jq .
# 2) Adicionar nó 2
curl -s -X POST http://$USER:$PASS@localhost:5984/_cluster_setup \
-H "Content-Type: application/json" \
-d '{
"action":"add_node",
"host":"couchdb2",
"port":5984,
"username":"'"$USER"'",
"password":"'"$PASS"'"
}' | jq .
# 3) Finalizar cluster
curl -s -X POST http://$USER:$PASS@localhost:5984/_cluster_setup \
-H "Content-Type: application/json" \
-d '{"action":"finish_cluster"}' | jq .
# 4) Verificar membros
curl -s http://$USER:$PASS@localhost:5984/_membership | jq .
3.3 Criando base no cluster
# 8 shards, 2 réplicas
curl -s -X PUT "http://$USER:$PASS@localhost:5984/minha_base" \
-H "Content-Type: application/json" \
-d '{"q":8,"n":2}' | jq .
# Ver shards
curl -s "http://$USER:$PASS@localhost:5984/minha_base/_shards" | jq .
4. Vantagens do Cluster
- Alta disponibilidade: tolerância a falhas com réplicas automáticas.
- Escalabilidade horizontal: sharding e distribuição de carga.
- Gerenciamento unificado: acesso a todos os nós via um único endpoint.
- Resiliência de dados: fator de réplica garante recuperação em caso de perda.
- Balanceamento automático: coordenação de leitura/escrita entre nós.
- Menos risco de inconsistência: replicação interna e controlada por quorum.
Com isso, você tem:
- Cenário de duas instâncias isoladas para testar replicação manual.
- Cenário de cluster real com sharding, replicação automática e quorum.
- Exemplos práticos de
docker-compose
, chamadascurl
e explicações.