Dua belas build

Memindahkan dua terabyte antara dua situs kami tanpa downtime

Pre-copy, replika streaming, dan cutover dengan proxy, dengan penyesuaian TCP yang menentukan apakah transfer jarak jauh memakan waktu satu jam atau satu hari.

Yang Dihasilkan

Dua terabyte berkas dan basis data Postgres aktif dipindahkan dari satu situs ke situs lain, dengan aplikasi tetap menjawab permintaan selama proses berlangsung. Caranya adalah pra-salin massal sementara sumber terus melayani, replika streaming yang tetap sinkron, dan peralihan yang diukur dalam hitungan detik dengan host lama menjadi proksi ke host baru sampai DNS menyesuaikan.

Jarak adalah bagian yang menarik. Antara AMS-01 dan FRA-01, waktu bolak-balik adalah tujuh milidetik dan satu aliran akan memenuhi port. Jalankan salinan yang sama ke GRU-01, yang waktu bolak-baliknya mendekati dua ratus, dan transfer yang tidak disetel merangkak pada sebagian kecil dari yang Anda bayar sementara kedua mesin hampir menganggur. Kesenjangan itu sepenuhnya karena seberapa banyak data yang diizinkan dalam perjalanan pada satu koneksi.

Sebelum Memulai

  • Instance sumber dan target, terowongan di antara keduanya, dan root di keduanya.
  • DNS yang Anda kendalikan, dengan TTL catatan diturunkan ke enam puluh detik setidaknya sehari sebelumnya. Ini adalah langkah yang dilewati orang dan kemudian menunggu enam jam.
  • Cukup disk di target untuk seluruh dataset ditambah replika.

1. Cari Tahu Kemampuan Tautan

Produk bandwidth-delay menentukan segalanya. Kalikan waktu bolak-balik dengan kecepatan yang Anda inginkan dan Anda mendapatkan jumlah data yang harus tidak diakui dalam perjalanan pada saat tertentu:

ping -c20 target.example.com | tail -1
JalurRTTDalam perjalanan untuk 1 Gbit/sJendela kernel default
AMS-01 ke FRA-017 ms0,9 MBCukup
AMS-01 ke NYC-0176 ms9,5 MBTidak cukup
AMS-01 ke SIN-01168 ms21 MBJauh dari cukup
AMS-01 ke GRU-01196 ms24,5 MBJauh dari cukup

Di kedua mesin:

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

BBR daripada kontrol kemacetan default penting pada jalur panjang dengan kehilangan apa pun, karena algoritma berbasis kehilangan menafsirkan satu paket yang dijatuhkan sebagai kemacetan dan membagi dua jendelanya. Lebih dari dua ratus milidetik, memulihkan dari itu membutuhkan detik, dan itu terjadi berulang kali.

Ukur sebelum Anda mengkomit dua terabyte pada asumsi:

# target
apt install -y iperf3 && iperf3 -s
# source
iperf3 -c target.example.com -P 8 -t 30

Delapan aliran paralel harus mendekati kecepatan port. Jika satu aliran mencapai seratus megabit dan delapan mencapai delapan ratus, pengaturan jendela tidak berlaku; satu aliran harus mendapatkan sebagian besar ke sana sendiri setelah itu berlaku.

2. Pra-Salin Massal

Jalankan ini terhadap sumber yang aktif. Ini akan memakan waktu berjam-jam, dan tidak ada yang terganggu selama itu:

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/

Pilihan sandi bukan takhayul. Pada prosesor ini, mode GCM yang dipercepat perangkat keras memindahkan beberapa gigabyte per detik per inti, sementara sandi default yang dinegosiasikan pada beberapa versi klien terasa lebih lambat dan mengubah transfer Anda menjadi tolok ukur satu inti. Kompresi dimatikan karena data sudah dikompresi dan, jika tidak, CPU menghabiskan waktunya untuk itu alih-alih memindahkan byte.

Untuk jutaan berkas kecil, satu aliran adalah bentuk yang salah. Pisahkan berdasarkan direktori tingkat atas dan jalankan beberapa:

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

Delapan salinan paralel pada delapan inti khusus adalah angka yang tepat di sini; enam belas tidak dua kali lebih cepat dan akan membuat mesin sumber tidak nyaman untuk apa pun yang masih dilayaninya.

3. Basis Data, Direplikasi Daripada Disalin

Membuang dan memulihkan dua ratus gigabyte Postgres berarti jendela panjang di mana penulisan hilang. Streaming saja. Di sumber:

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 postgresql

Di target:

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 postgresql

Bendera -R menulis pengaturan koneksi dan file sinyal standby, sehingga target muncul sebagai replika dan mulai mengikuti. Dari sini tetap dalam satu atau dua detik dari sumber tanpa batas, yang berarti peralihan tidak lagi melibatkan pemindahan basis data sama sekali.

4. Peralihan

Mulai probe dari mesin ketiga dan biarkan berjalan. Ini adalah verifikasi Anda dan catatan Anda tentang biaya peralihan:

while true; do curl -s -o /dev/null -w "%{http_code} %{time_total}\n" https://app.example.com/health; sleep 1; done | tee cutover.log

Kemudian, dalam urutan ini dan tanpa jeda:

# 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"

Langkah dua sampai lima memakan waktu beberapa detik. Sekarang hentikan host lama dari melayani konten basi saat DNS menyebar, dengan mengubahnya menjadi proksi untuk yang baru:

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;
  }
}

Ini adalah bagian yang membuat semuanya tidak mengganggu. Siapa pun yang masih menyelesaikan alamat lama mendapatkan jawaban yang benar melalui terowongan daripada kesalahan atau, lebih buruk, salinan data yang berhenti diperbarui saat peralihan. Sekarang ubah catatan DNS.

Verifikasi

Mulai dengan log probe yang telah Anda kumpulkan:

sort cutover.log | uniq -c | sort -rn | head

Setiap baris harus berbunyi 200. Beberapa respons lebih lambat selama peralihan diharapkan; non-200 apa pun berarti langkah lima dimulai setelah langkah dua dengan margin terlalu lebar, dan proksi di bagian sebelumnya adalah yang mengecilkan celah itu menjadi nol.

Kemudian buktikan data identik daripada hanya ada:

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"

Uji coba yang tidak merinci apa pun berarti kedua pohon setuju pada konten, izin, kepemilikan, dan atribut luas. Total byte harus cocok persis.

Basis data berikutnya:

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;"

Pemulihan sekarang harus false di target, dan jumlah baris harus setuju. Akhirnya, konfirmasi lalu lintas benar-benar telah pindah daripada diam-diam diproksikan selamanya:

dig +short app.example.com
tail -f /var/log/nginx/access.log | wc -l   # on the old host, an hour later

Ketika host lama telah idle untuk TTL penuh plus margin yang nyaman, turunkan proksi dan hancurkan instance. Jangan hancurkan pada sore yang sama; asuransi termurah dalam seluruh prosedur ini adalah membiarkan mesin sumber utuh dan dimatikan selama seminggu.

Setelahnya

Dua terabyte melalui jalur jarak jauh yang disetel dengan baik kira-kira satu jam pada sepuluh gigabit dan agak lebih lama dalam praktiknya, karena sumber juga melayani. Antara situs Eropa yang berdekatan, rencanakan sore; antara benua, mulai di malam hari dan lakukan peralihan keesokan harinya. Halaman lokasi mencantumkan waktu bolak-balik yang kami ukur, dan itulah angka untuk dimasukkan ke dalam tabel di langkah satu.

Siap saat Anda siap

Pilih kota. Pilih ukuran. Bayar dengan koin.

Tanpa formulir tentang siapa Anda, tanpa menunggu manusia untuk menyetujui, tanpa panggilan telepon untuk memverifikasi apa pun. Invoice dibersihkan dan kredensial masuk ke kotak masuk Anda.