Fəsil 14 · 7 dəq oxu

Deployment və release strategiyaları

Deployment və release strategiyaları

Bir çox komandada hadisədir. Cümə günü edilmir, Slack kanalında hamı nəfəsini tutub gözləyir. Ch02-də belə soruşmuşduq: "merge olundu"dan "production-dadır"a qədər nə qədər vaxt keçir və bu nə dərəcədə risklidir? qorxuludursa, komanda onu seyrək edir. Seyrək deploy-lar böyük olur, böyük deploy-lar isə daha tez-tez sınır. Qorxu öz-özünü doğruldur.

Bu fəslin məqsədi adi, darıxdırıcı əməliyyata çevirməkdir. Bunun üçün dəyişikliyi kiçik saxlamaq, onu mərhələlərlə yaymaq, problemi istifadəçilərin çoxu görməmişdən əvvəl tutmaq və geri qayıtmağı ucuzlaşdırmaq lazımdır. Ch07-nin dili ilə desək, burada danışılan hər strategiya kiçiltmək və azaltmaq üçün tactic-dir.

Deploy release deyil

kodun production-a çatdırılmasıdır. isə dəyişikliyin istifadəçiyə açılmasıdır. Ənənəvi olaraq bu ikisi eyni anda baş verir: yeni build qalxır və hamı yeni davranışı dərhal görür. Elə buna görə riskli olur: texniki risk (yeni binary işləyəcəkmi?) və məhsul riski (istifadəçilər yeni feature-u necə qarşılayacaq?) bir ana yığılır.

Bu ikisini ayırmaq riski iki kiçik hissəyə bölür. Kod əvvəlcə söndürülmüş halda production-a gedir və real infrastructure-da işlədiyi yoxlanılır. Feature isə sonra, ayrıca qərarla, əvvəl daxili istifadəçilərə, sonra kiçik faizə, sonra hamıya açılır. Problem çıxanda üçün yeni lazım olmur, geri alınır.

Aşağıdakı strategiyaları bu ayrılığa görə iki qrupa bölmək olar: rolling, və idarə edir, isə .

Kiçik və tez-tez

riski onun ölçüsü ilə artır. Üç sətirlik dəyişiklik sınanda səbəbi bir dəqiqəyə tapırsınız. İki həftəlik iş yığınında, yəni qırx commit-də isə əvvəlcə hansı commit-in günahkar olduğunu axtarmalısınız. Kiçik batch həm sınma ehtimalını, həm də bərpa vaxtını azaldır.

DORA tədqiqatları bunu dörd metrika ilə ölçür:

  • frequency: nə qədər tez-tez production-a edirsiniz.
  • Lead time for changes: commit-dən production-a qədər keçən vaxt.
  • Change failure rate: neçə faizi incident və ya səbəb olur.
  • Time to restore (): uğursuz dəyişiklikdən sonra bərpa vaxtı.

Tədqiqatların əsas nəticəsi intuisiyaya ziddir: sürət və sabitlik bir-birinə qarşı deyil. Ən yaxşı komandalar həm gündə bir neçə dəfə edir, həm də daha az sınır. Çünki tez-tez edən komanda prosesi avtomatlaşdırmağa məcburdur.

Rolling və blue-green: versiyanı necə dəyişmək

Rolling deployment

instance-lar qrup-qrup yeni versiyaya keçir: bir instance-ı traffic-dən çıxarır, onu yeniləyir, keçəndən sonra geri qaytarır və növbətiyə keçir.

Üstünlüyü sadəlikdir: əlavə infrastructure tələb etmir. Qiyməti isə iki yerdə ödənir. Birincisi, boyunca iki versiya eyni anda işləyir: eyni istifadəçinin bir request-i köhnə, növbətisi yeni versiyaya düşə bilər. Deməli, yeni versiya köhnə ilə eyni API-ni, eyni queue mesaj formatını və eyni database schema-sını başa düşməlidir. Ch08-dəki backward compatibility tələbi burada service-in öz versiyaları arasında da işləyir. İkincisi, yavaşdır: geri qayıtmaq başqa bir deməkdir və yüz instance-lıq sistemdə bu dəqiqələr çəkir.

Blue-green deployment

iki tam mühit var. "Blue" hazırda traffic qəbul edir, yeni versiya "green"-də qaldırılır və orada yoxlanılır. Hazır olanda və ya DNS bütün traffic-i bir anda green-ə keçirir. Problem çıxsa, switch geri çevrilir. saniyələr çəkir, çünki blue hələ də işləyir.

Qiyməti açıqdır: switch anında ikiqat infrastructure lazımdır. Daha az görünən problem isə database-dir. İki mühit adətən eyni database-i paylaşır, çünki data-nı iki nüsxədə sinxron saxlamaq ayrıca layihədir. Bu o deməkdir ki, green-in schema dəyişikliyi blue ilə də uyğun olmalıdır, əks halda "ani " vədi yalan çıxır. Bu problemə migration bölməsində qayıdacağıq.

Canary release: riski ölçərək genişləndirmək

yeni versiyanı əvvəlcə traffic-in kiçik hissəsinə verir, məsələn 1%-ə, və qərarı metrikalara əsasən verir: hər şey normaldırsa 5%, 25%, 100%; pisləşirsə dərhal geri. Bu, birbaşa kiçiltmək deməkdir: səhv build istifadəçilərin hamısına yox, yüzdə birinə çatır və yalnız kiçik hissəsini yeyir.

gücləndirən avtomatlaşdırmadır. yeni versiyanın (ch07) eyni anda işləyən köhnə versiyanın ilə müqayisə edir: error rate, , saturation. Müqayisə mütləq hədlə yox, baseline ilə aparılır, çünki gecə saat üçdə və axşam pik saatda normal error rate fərqlidir. Fərq hədd keçirsə, sistem insanı gözləmədən edir.

şərtləri var. Kiçik faizdə statistik nəticə çıxarmaq üçün kifayət qədər traffic lazımdır: dəqiqədə on request-lik service-də 1% heç nə demir. İstifadəçi "yapışdırılmalıdır", əks halda hər səhifə yenilənəndə fərqli versiya görür. Rolling-dəki kimi iki versiya eyni anda işlədiyi üçün compatibility tələbi də qalır.

Machine Learning kitabında model baxımından baxdıq: orada əsas sual model-in keyfiyyətidir, burada isə texniki sağlamlığı. isə daha da ehtiyatlıdır: traffic yeni versiyaya kopyalanır, amma cavabı istifadəçiyə qaytarılmır. Bu, yalnız side effect-i olmayan, oxuma əməliyyatları üçün təhlükəsizdir.

Feature flag-lər: release-i kodla idarə etmək

kodun içində runtime-da dəyişdirilə bilən şərtdir: if flags.enabled("new-checkout", user). O, ilə arasındakı ayrılığı reallaşdırır və bir neçə fərqli iş görür:

  • Tədrici açılış: əvvəl komanda, sonra beta istifadəçilər, sonra faizlə hamı.
  • : problemli feature-u və ya ağır əməliyyatı etmədən söndürmək. Ch11-dəki çox vaxt məhz belə flag-lərlə həyata keçirilir.
  • : istifadəçiləri qruplara bölüb variantları biznes metrikası ilə müqayisə etmək.

Flag-lərin qiyməti texniki borcdur. Hər flag kodda iki yol yaradır və on aktiv flag nəzəri olaraq 1024 kombinasiya deməkdir, onların çoxu heç vaxt test olunmur. Köhnəlmiş flag-lər isə təhlükəlidir: 2012-ci ildə Knight Capital köhnə flag-i yeni məqsədlə təkrar istifadə etdi, səkkiz server-dən birinə yeni kod olunmamışdı və flag orada illər əvvəlki ölü kodu oyatdı. Şirkət 45 dəqiqədə 440 milyon dollar itirdi. Qayda: hər flag-inin sahibi və silinmə tarixi olsun, flag-in silinməsi feature-un "bitdi" tərifinə daxil edilsin.

Daha bir incəlik: flag dəyişikliyi pipeline-dan keçməyən . Ch07-də config-i ən təhlükəli biri adlandırmışdıq: bütün region-lara bir anda yayılan səhv flag hər hansı səhv build qədər sistemi yıxa bilər. Ona görə flag dəyişiklikləri də audit olunmalı və mərhələlərlə yayılmalıdır.

StrategiyaRisk ()İnfrastructure xərci sürətiMürəkkəblikNə vaxt uyğundur
RollingOrta: səhv tədricən hamıya çatırAşağıYavaş (yeni rollout)AşağıStateless service-lər, backward compatible dəyişikliklər
Yüksək: switch anında hamıYüksək (ikiqat mühit)AniOrtaAni switch lazımdırsa, traffic az olduğu üçün mənasızdırsa
Aşağı: əvvəl 1–5%Aşağı–ortaSürətli, avtomatikYüksək (routing, metrika, analysis)Yüksək traffic, yaxşı SLI-lar, tez-tez
Aşağı, feature səviyyəsindəAşağı (flag service)Ani, Kodda artır, borc yığılırMəhsul riski, tədrici açılış, eksperimentlər

Bu strategiyalar bir-birini əvəz etmir. Yetkin pipeline adətən ilə edir və ilə edir.

Database migration-ları: expand–contract

Kodu geri qaytarmaq asandır, data-nı yox. Schema dəyişikliyi ən riskli hissəsidir: yeni sütunu silib köhnə versiyaya qayıtmaq olar, amma silinmiş sütunun data-sını yox. Üstəlik, rolling, və köhnə və yeni versiya eyni database-ə eyni anda müraciət edir. Böyük cədvəldə ALTER TABLE uzun lock da tuta bilər.

Həll yolu breaking dəyişikliyi bir neçə kiçik, ayrıca olunan və hər biri geri qaytarıla bilən addıma bölməkdir. Bu, expand–contract (və ya ) adlanır. Nümunə: users.name sütununun adını full_name etmək.

  1. Expand. full_name sütununu nullable olaraq əlavə edin. Köhnə kod onu görmür, heç nə sınmır.
  2. . Kodu yeniləyin: hər iki sütuna yazsın, hələ də name-dən oxusun.
  3. Backfill. Köhnə sətirləri hissə-hissə, database-i boğmadan full_name-ə köçürün.
  4. Oxumanı keçirin. Kod full_name-dən oxusun, amma hər iki sütuna yazmağa davam etsin. Problem çıxsa, geri qayıtmaq təhlükəsizdir, çünki name hələ aktualdır.
  5. Köhnəyə yazmağı dayandırın. Köhnə versiyanın heç bir instance-ı qalmadığına əmin olandan sonra.
  6. Contract. Bir müddət gözləyib name sütununu silin. Yalnız bu addım geri qaytarılmır.

Bir ad dəyişikliyi üçün altı çox görünür, amma alternativ maintenance pəncərəsidir. Eyni pattern API field-ləri və queue mesaj formatları üçün də işləyir.

Chaos engineering: bərpanın işlədiyini yoxlamaq

Ch07-də , ch11-də , və dizayn etdik. Onların real failure zamanı işləyəcəyini hardan bilirik? Heç vaxt işə düşməyən adətən ilk dəfə lazım olanda sınır.

bu sualı eksperimentlə yoxlayır. Məqsəd "production-da sındırmaq" deyil, intizamlı eksperimentdir:

  • Steady state. Sistemin normal halını ilə təyin edin: "checkout uğur faizi 99.9%-dən yuxarıdır."
  • Hipotez. "Bir AZ itəndə steady state pozulmayacaq."
  • Kiçik . Bir instance ilə, staging-də, sonra production traffic-inin kiçik hissəsində başlayın. Eksperimenti dərhal dayandırmaq üçün abort şərti olsun.
  • Öyrənmə. Hipotez təsdiqlənmirsə, real əvvəl zəif nöqtə tapılıb.

Başlamağın ən ucuz yolu -dir: komanda planlı şəkildə bir failure ssenarisini canlandırır, məsələn database primary-ni söndürür, və alert-lərin, runbook-ların, necə işlədiyini birlikdə izləyir. Şərt yaxşı : nə baş verdiyini görə bilmirsinizsə, eksperiment yox, sadəcə etmiş olursunuz. Bu mövzuya fəslində qayıdacağıq.

Hazırkı sisteminiz haqqında suallar

  1. Son ay neçə dəfə etdiniz və neçəsi və ya hotfix tələb etdi? Lead time-ınızın ən uzun hissəsi hansı mərhələdir?
  2. Səhv build production-a çatsa, istifadəçilərin neçə faizi onu görəcək və neçə dəqiqə çəkəcək?
  3. Kodunuzda neçə var? Ən köhnəsi nə vaxt yaradılıb və onu kim silməlidir?
  4. və ya hansı son dəfə qəsdən test olunub? Heç biri test olunmayıbsa, ilk üçün hansı ssenarini seçərdiniz?