Bu neyi kurar
İki terabayt dosya ve canlı bir Postgres veritabanı, bir siteden diğerine taşınır ve uygulama boyunca isteklere yanıt verir. Yöntem, kaynak hizmet vermeye devam ederken toplu ön kopyalama, senkronize kalan akışlı bir kopya ve eski ana bilgisayar DNS yakalayana kadar yenisine proxy'lik ederken saniyelerle ölçülen bir geçiştir.
Mesafe ilginç kısımdır. AMS-01 ile FRA-01 arasında gidiş-dönüş yedi milisaniyedir ve tek bir akış bir portu dolduracaktır. Aynı kopyayı GRU-01'e çalıştırın, gidiş-dönüş iki yüze yakın olduğunda, ayarlanmamış bir aktarım, her iki makine de neredeyse boşta dururken ödediğinizin küçük bir kısmıyla sürünür. Bu fark tamamen tek bir bağlantının uçuşta sahip olabileceği veri miktarına bağlıdır.
Başlamadan önce
- Kaynak ve hedef örnekler, aralarında bir tünel ve her ikisinde de root erişimi.
- Kontrol ettiğiniz DNS ve kaydın TTL'si en az bir gün önceden altmış saniyeye düşürülmüş olmalı. Bu, insanların atladığı ve sonra altı saat beklediği adımdır.
- Hedefte tüm veri seti artı kopya için yeterli disk.
1. Bağlantının neler yapabileceğini belirleyin
Bant genişliği-gecikme çarpımı her şeyi belirler. Gidiş-dönüş süresini istediğiniz hızla çarpın ve her an uçuşta onaylanmamış olması gereken veri miktarını elde edin:
ping -c20 target.example.com | tail -1| Yol | RTT | 1 Gbit/s için uçuşta | Varsayılan çekirdek penceresi |
|---|---|---|---|
| AMS-01 - FRA-01 | 7 ms | 0.9 MB | Yeterli |
| AMS-01 - NYC-01 | 76 ms | 9.5 MB | Yeterli değil |
| AMS-01 - SIN-01 | 168 ms | 21 MB | Hiç yeterli değil |
| AMS-01 - GRU-01 | 196 ms | 24.5 MB | Hiç yeterli değil |
Her iki makinede:
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, herhangi bir kayıp olan uzun yollarda varsayılan tıkanıklık kontrolünden daha önemlidir, çünkü kayıp tabanlı algoritmalar tek bir düşen paketi tıkanıklık olarak yorumlar ve pencerelerini yarıya indirir. İki yüz milisaniyenin üzerinde, bundan kurtulmak saniyeler alır ve bu tekrar tekrar olur.
Bir varsayıma iki terabayt taahhüt etmeden önce ölçün:
# target
apt install -y iperf3 && iperf3 -s
# source
iperf3 -c target.example.com -P 8 -t 30Sekiz paralel akış port hızına yaklaşmalıdır. Bir akış yüz megabit ve sekizi sekiz yüz yönetiyorsa, pencere ayarları etkili olmamıştır; tek bir akış, ayarlar yapıldıktan sonra çoğu yolu kendi başına almalıdır.
2. Toplu ön kopyalama
Bunu canlı bir kaynağa karşı çalıştırın. Saatler sürecek ve bu sırada hiçbir şey kesintiye uğramayacak:
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/Şifre seçimi batıl inanç değildir. Bu işlemcilerde donanım hızlandırmalı GCM modu çekirdek başına saniyede birkaç gigabayt taşırken, bazı istemci sürümlerinde varsayılan olarak anlaşılan şifre belirgin şekilde daha yavaştır ve aktarımınızı tek çekirdekli bir kıyaslamaya dönüştürür. Sıkıştırma kapalıdır çünkü veri zaten sıkıştırılmıştır ve eğer sıkıştırılmamışsa, CPU zamanını bayt taşımak yerine buna harcar.
Milyonlarca küçük dosya için tek akış yanlış şekildir. En üst düzey dizine göre bölün ve birkaç tane çalıştırın:
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/{}/Sekiz özel çekirdekte sekiz paralel kopya burada doğru sayıdır; on altı iki kat hızlı değildir ve kaynak makinesini hala hizmet verdiği şey için rahatsız edici hale getirir.
3. Veritabanı, kopyalanmak yerine çoğaltılmış
İki yüz gigabaytlık Postgres'i dökmek ve geri yüklemek, yazmaların kaybolduğu uzun bir pencere anlamına gelir. Bunun yerine akışını yapın. Kaynakta:
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 postgresqlHedefte:
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-R bayrağı bağlantı ayarlarını ve bekleme sinyali dosyasını yazar, böylece hedef bir kopya olarak gelir ve takip etmeye başlar. Buradan itibaren süresiz olarak kaynağın bir veya iki saniyesi içinde kalır, bu da geçişin artık veritabanını taşımayı içermediği anlamına gelir.
4. Geçiş
Üçüncü bir makineden bir kontrol çalıştırın ve çalışır durumda bırakın. Bu hem doğrulamanız hem de anahtarın maliyetinin kaydıdır:
while true; do curl -s -o /dev/null -w "%{http_code} %{time_total}\n" https://app.example.com/health; sleep 1; done | tee cutover.logArdından, bu sırayla ve duraklamadan:
# 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"İkinci ile beşinci adımlar birkaç saniye sürer. Şimdi DNS yayılırken eski ana bilgisayarın eski içerik sunmasını durdurun, onu yenisi için bir proxy'ye dönüştürerek:
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;
}
}Bu, tüm işi kesintisiz yapan parçadır. Eski adresi hala çözenler, tünel üzerinden bir hata yerine veya daha kötüsü, geçişte güncellenmeyi durduran verinin bir kopyası yerine doğru bir yanıt alır. Şimdi DNS kaydını değiştirin.
Doğrulayın
Topladığınız kontrol günlüğüyle başlayın:
sort cutover.log | uniq -c | sort -rn | headHer satır 200 okumalıdır. Anahtar sırasında birkaç yavaş yanıt beklenir; 200 dışı herhangi bir yanıt, beşinci adımın ikinci adımdan sonra çok geniş bir farkla başladığı anlamına gelir ve önceki bölümdeki proxy bu farkı sıfıra indiren şeydir.
Ardından verilerin yalnızca mevcut değil aynı olduğunu kanıtlayın:
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"Hiçbir şeyi listelemeyen kuru bir çalışma, iki ağacın içerik, izinler, sahiplik ve genişletilmiş öznitelikler konusunda anlaştığı anlamına gelir. Bayt toplamları tam olarak eşleşmelidir.
Sırada veritabanı:
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;"Kurtarma artık hedefte false olmalı ve satır sayıları eşleşmelidir. Son olarak, trafiğin gerçekten taşındığını, sessizce sonsuza dek proxy'lenmediğini doğrulayın:
dig +short app.example.com
tail -f /var/log/nginx/access.log | wc -l # on the old host, an hour laterEski ana bilgisayar tam bir TTL artı rahat bir marj boyunca boşta kaldığında, proxy'yi kaldırın ve örneği yok edin. Aynı öğleden sonra yok etmeyin; bu tüm prosedürdeki en ucuz sigorta, kaynak makineyi bozulmadan ve bir hafta kapalı bırakmaktır.
Sonrasında
İyi ayarlanmış uzun bir yol üzerinde iki terabayt, on gigabitte kabaca bir saat ve pratikte daha uzundur, çünkü kaynak da hizmet veriyordur. Komşu Avrupa siteleri arasında, bir öğleden sonra planlayın; kıtalar arasında, akşam başlatın ve geçişi ertesi gün yapın. konumlar sayfası ölçtüğümüz gidiş-dönüş sürelerini listeler ve bunlar birinci adımdaki tabloya koyulacak sayılardır.