O que este guia constrói
Dois terabytes de arquivos e um banco de dados Postgres ao vivo são movidos de um site para outro, com o aplicativo respondendo a requisições durante todo o processo. O método é uma pré-cópia em massa enquanto a origem continua servindo, uma réplica de streaming que permanece sincronizada, e um corte que dura segundos, com o host antigo fazendo proxy para o novo até o DNS se atualizar.
A distância é a parte interessante. Entre AMS-01 e FRA-01, o tempo de ida e volta é de sete milissegundos e um único fluxo preencherá uma porta. Execute a mesma cópia para GRU-01, onde o round trip se aproxima de duzentos, e uma transferência não ajustada se arrasta a uma pequena fração do que você paga, enquanto ambas as máquinas ficam quase ociosas. Essa discrepância se resume inteiramente à quantidade de dados que uma conexão pode ter em voo.
Antes de começar
- Instâncias de origem e destino, um túnel entre elas e acesso root em ambas.
- DNS que você controla, com o TTL do registro reduzido para sessenta segundos pelo menos um dia antes. Este é o passo que as pessoas pulam e depois esperam seis horas.
- Disco suficiente no destino para todo o conjunto de dados mais a réplica.
1. Descubra o que o link pode fazer
O produto de atraso de largura de banda decide tudo. Multiplique o tempo de ida e volta pela taxa desejada e você obtém a quantidade de dados que deve estar não reconhecidos em voo a qualquer momento:
ping -c20 target.example.com | tail -1| Caminho | RTT | Em voo para 1 Gbit/s | Janela padrão do kernel |
|---|---|---|---|
| AMS-01 a FRA-01 | 7 ms | 0.9 MB | Suficiente |
| AMS-01 a NYC-01 | 76 ms | 9.5 MB | Não suficiente |
| AMS-01 a SIN-01 | 168 ms | 21 MB | Longe de ser suficiente |
| AMS-01 a GRU-01 | 196 ms | 24.5 MB | Longe de ser suficiente |
Em ambas as máquinas:
cat > /etc/sysctl.d/75-transfer.conf <<EOF
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 262144 134217728
net.ipv4.tcp_wmem = 4096 262144 134217728
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
net.ipv4.tcp_mtu_probing = 1
EOF
sysctl --systemBBR em vez do controle de congestionamento padrão é importante em caminhos longos com qualquer perda, porque algoritmos baseados em perda interpretam um único pacote descartado como congestionamento e reduzem sua janela pela metade. Em duzentos milissegundos, a recuperação disso leva segundos, e isso acontece repetidamente.
Meça antes de comprometer dois terabytes a uma suposição:
# target
apt install -y iperf3 && iperf3 -s
# source
iperf3 -c target.example.com -P 8 -t 30Oito fluxos paralelos devem se aproximar da velocidade da porta. Se um fluxo gerencia cem megabits e oito gerenciam oitocentos, as configurações de janela não surtiram efeito; um único fluxo deve percorrer a maior parte do caminho sozinho depois que elas estiverem aplicadas.
2. Pré-cópia em massa
Execute isso contra uma origem ativa. Levará horas, e nada será interrompido enquanto isso:
apt install -y rsync
rsync -aHAX --numeric-ids --partial --inplace --info=progress2 \
-e "ssh -c [email protected] -o Compression=no" \
/srv/data/ [email protected]:/srv/data/A escolha da cifra não é superstição. Nesses processadores, o modo GCM acelerado por hardware move vários gigabytes por segundo por núcleo, enquanto a cifra negociada por padrão em algumas versões de cliente é visivelmente mais lenta e transforma sua transferência em um benchmark de um único núcleo. A compressão está desativada porque os dados já estão compactados e, se não estiverem, a CPU gasta tempo nisso em vez de mover bytes.
Para milhões de arquivos pequenos, um fluxo é o formato errado. Divida por diretório de nível superior e execute vários:
ls /srv/data | xargs -P 8 -I{} rsync -aHAX --numeric-ids \
-e "ssh -c [email protected] -o Compression=no" \
/srv/data/{}/ [email protected]:/srv/data/{}/Oito cópias paralelas em oito núcleos dedicados é o número certo aqui; dezesseis não é duas vezes mais rápido e tornará a máquina de origem desagradável para o que ainda está servindo.
3. O banco de dados, replicado em vez de copiado
Despejar e restaurar duzentos gigabytes de Postgres significa uma longa janela onde as gravações são perdidas. Transmita-o em vez disso. Na origem:
sudo -u postgres psql -c "CREATE USER repl WITH REPLICATION PASSWORD '<a long password>';"
sudo -u postgres psql -c "SELECT pg_create_physical_replication_slot('target_site');"
echo "host replication repl 10.9.0.2/32 scram-sha-256" >> /etc/postgresql/17/main/pg_hba.conf
systemctl reload postgresqlNo destino:
systemctl stop postgresql
rm -rf /var/lib/postgresql/17/main/*
sudo -u postgres pg_basebackup -h 10.9.0.1 -U repl -D /var/lib/postgresql/17/main \
-S target_site -X stream -R -P -c fast
systemctl start postgresqlA flag -R grava as configurações de conexão e o arquivo de sinal do standby, para que o destino suba como réplica e comece a seguir. A partir daqui, permanece dentro de um ou dois segundos da origem indefinidamente, o que significa que o corte não envolve mais mover o banco de dados.
4. Corte
Inicie uma sondagem de uma terceira máquina e deixe-a rodando. É tanto sua verificação quanto seu registro do que custou a troca:
while true; do curl -s -o /dev/null -w "%{http_code} %{time_total}\n" https://app.example.com/health; sleep 1; done | tee cutover.logEntão, nesta ordem e sem pausas:
# 1. final delta, source still live
rsync -aHAX --numeric-ids --delete -e "ssh -c [email protected]" /srv/data/ [email protected]:/srv/data/
# 2. stop writes on the source
systemctl stop app
# 3. one more delta, now tiny
rsync -aHAX --numeric-ids --delete -e "ssh -c [email protected]" /srv/data/ [email protected]:/srv/data/
# 4. promote the replica
ssh [email protected] "sudo -u postgres pg_ctl promote -D /var/lib/postgresql/17/main"
# 5. start the application on the target
ssh [email protected] "systemctl start app"Os passos dois a cinco levam alguns segundos. Agora, impeça o host antigo de servir conteúdo obsoleto enquanto o DNS se propaga, transformando-o em um proxy para o novo:
server {
listen 443 ssl;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
location / {
proxy_pass https://10.9.0.2;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}Esta é a peça que torna todo o processo não disruptivo. Qualquer pessoa que ainda resolva o endereço antigo obtém uma resposta correta pelo túnel em vez de um erro ou, pior, uma cópia dos dados que parou de atualizar no corte. Agora, altere o registro DNS.
Verifique
Comece com o log de sondagem que você coletou:
sort cutover.log | uniq -c | sort -rn | headCada linha deve ler 200. Algumas respostas mais lentas durante a troca são esperadas; qualquer não-200 significa que o passo cinco começou depois do passo dois por uma margem muito grande, e o proxy na seção anterior é o que reduz essa lacuna a nada.
Em seguida, prove que os dados são idênticos em vez de meramente presentes:
rsync -aHAXn --delete --itemize-changes /srv/data/ [email protected]:/srv/data/ | head
du -s --bytes /srv/data
ssh [email protected] "du -s --bytes /srv/data"Uma execução seca que não detalha nada significa que as duas árvores concordam quanto a conteúdo, permissões, propriedade e atributos estendidos. As somas de bytes devem corresponder exatamente.
Banco de dados em seguida:
ssh [email protected] "sudo -u postgres psql -c 'SELECT pg_is_in_recovery();'"
ssh [email protected] "sudo -u postgres psql app -c 'SELECT count(*) FROM orders;'"
sudo -u postgres psql app -c "SELECT count(*) FROM orders;"A recuperação deve agora ser falsa no destino, e as contagens de linhas devem concordar. Finalmente, confirme que o tráfego realmente se moveu em vez de ser silenciosamente proxiado para sempre:
dig +short app.example.com
tail -f /var/log/nginx/access.log | wc -l # on the old host, an hour laterQuando o host antigo estiver ocioso por um TTL completo mais uma margem confortável, remova o proxy e destrua a instância. Não a destrua na mesma tarde; o seguro mais barato em todo este procedimento é deixar a máquina de origem intacta e desligada por uma semana.
Depois
Dois terabytes em um caminho de longa distância bem ajustado é aproximadamente uma hora a dez gigabits e bastante mais na prática, já que a origem também está servindo. Entre sites europeus vizinhos, planeje uma tarde; entre continentes, comece à noite e faça o corte no dia seguinte. A página de localizações lista os tempos de ida e volta que medimos, e esses são os números para colocar na tabela do passo um.