Kampanya günü çökmeyen e-ticaret: önbellek ve ölçeklenme stratejisi
Trafik 20 katına çıktığında ne olur? MatbaaStore'un kampanya dönemleri için kurduğu savunma hatları.
Gece yarısını beş geçe. MatbaaStore'un kampanya SMS'i 40 bin kişiye aynı anda düşer. Bir dakika içinde dakikada 200 istek gören sistem, saniyede 7.000 isteğe tırmanır. Kartvizit fiyatını sorgulayan, sepetini dolduran, "yılbaşı kataloğu %30 indirimli" başlığına tıklayan on binlerce kişi aynı saniyelerde kapıya yüklenir. İşte bu 90 saniye, bir e-ticaret platformunun bütün mimari kararlarını sınava sokan andır.
Yıllar bize tek bir şeyi çok net öğretti: veritabanları trafikten çökmez, kötü mimariden çöker. Kampanya günü çöken siteyi açıp loglara baktığınızda neredeyse her zaman aynı manzarayı görürsünüz — uygulama sunucuları rahat, ağ rahat, ama veritabanı diz çökmüş. Çünkü her fiyat sorgusu, her sepet güncellemesi, her kategori sayfası doğrudan veritabanına inmiş. Zirve anında bu, tek bir PostgreSQL örneğine saniyede binlerce sorgu demek. O örnek ölür, ve onunla birlikte kampanya da ölür.
Bu yazıda MatbaaStore'u kampanya günü ayakta tutan mimariyi anlatacağız: kampanya trafiğinin neye benzediğini, Redis önbellek katmanlarını nasıl dizdiğimizi, Elasticsearch'ün veritabanının önünde nasıl kalkan durduğunu, mavi-yeşil dağıtımla kampanya provasını nasıl yaptığımızı ve tüm bunların tek bir hedefe nasıl hizmet ettiğini: trafik on kat artsa da veritabanı yükü sabit kalsın.
Kampanya trafiği bir dalga değil, bir duvardır
Normal bir e-ticaret trafiğini yönetmek kolaydır çünkü öngörülebilir bir eğrisi vardır. Sabah yavaş yavaş yükselir, öğlen tepe yapar, akşam iner. Kapasiteyi ortalamaya göre kurar, tepe için biraz pay bırakırsınız, iş biter. Kampanya trafiği ise bambaşka bir hayvandır. Bir dalga gibi yaklaşmaz; bir duvar gibi çarpar.
MatbaaStore'da ölçtüğümüz gerçek profil şudur: sıradan bir öğle vakti platform saniyede 150-250 istek görür. Kampanya bildirimi gittiği an, ilk 60 saniyede bu rakam saniyede 6.000-8.000 aralığına fırlar. Yani otuz kata varan bir artış, dakika değil saniye ölçeğinde. Klasik "yavaşça ölçeklen" yaklaşımı burada işe yaramaz; otomatik ölçekleyici yeni sunucuları ayağa kaldırana kadar (ki bu iyi ihtimalle 60-90 saniyedir) kampanya çoktan çökmüş olur.
Bu trafik profilinin bir başka acımasız özelliği de içeriğinin dar olmasıdır. Normal günde kullanıcılar kataloğun her köşesine dağılır. Kampanya gününde ise herkes aynı 20-30 ürüne, aynı kampanya sayfasına, aynı popüler fiyat kombinasyonlarına yüklenir. Bu, ilk bakışta kötü haber gibi görünür ama aslında en büyük kozumuzdur: trafik ne kadar dar bir kümede yoğunlaşırsa, önbellek o kadar iyi çalışır. Bizim işimiz, bu darlığı bir zayıflık değil, bir kaldıraç olarak kullanmaktır.
Bir de kampanya trafiğinin ölmesinin nasıl bir zincir tepkimeyle geldiğini anlatmak gerekir, çünkü çöküş tek bir olay değildir. Önce veritabanı yavaşlar. Yavaşlayan veritabanı yüzünden uygulama sunucularındaki istekler daha uzun süre açık kalır. Uzun süre açık kalan istekler bağlantı havuzunu tüketir. Havuz tükenince yeni istekler kuyruğa girer, kuyruk şişer, gecikme katlanır. Kullanıcı sayfa açılmayınca yeniler — ve her yenileme sisteme bir istek daha ekler. İşte bu, klasik çöküş sarmalıdır (cascading failure): tek bir yavaş katman, saniyeler içinde tüm sistemi kilitler. Bizim mimari felsefemiz baştan sona bu sarmalın ilk halkasını, yani veritabanının yavaşlamasını, hiç oluşmadan engellemek üzerine kuruludur.
Kampanya mimarisini ortalama trafiğe göre değil, ilk 90 saniyedeki duvara göre tasarlarsınız. O duvarı taşıyan sistem, geri kalan her şeyi zaten taşır.
Redis önbellek katmanları: fiyat, sepet, oturum
MatbaaStore'un çekirdeğinde anlık fiyatlandırma motoru var. Ebat, gramaj, adet, selefon, teslim süresi — onlarca değişkenin çarpımından oluşan bir uzayda her varyantın fiyatını milisaniyede hesaplıyor. Motor hızlı; ama "hızlı" ile "saniyede on binlerce kez tekrarlanabilir" aynı şey değildir. Kampanya gününde aynı 500 gr kuşe, 1000 adet, mat selefonlu kartvizit fiyatını binlerce kişi aynı anda sorar. Bu fiyatı her seferinde yeniden hesaplamak, CPU'yu boşa yakmaktır.
Bu yüzden Redis'i tek bir önbellek olarak değil, üç ayrı katman olarak kurguladık. Her katmanın kendi anahtar deseni, kendi geçerlilik süresi (TTL) ve kendi tutarlılık kuralı var:
- Fiyat önbelleği: Fiyatlandırma motorunun çıktısı, varyantın tüm değişkenlerinden türetilen bir anahtarla saklanır. Anahtar deseni ebat:gramaj:adet:selefon:teslim gibi deterministik bir dizedir. TTL 6 saat; çünkü maliyet tabloları gün içinde değişmez. Kampanya gününde bu katmanın isabet oranı %97'nin altına düşmez.
- Sepet önbelleği: Kullanıcının sepeti Redis'te bir hash olarak yaşar; veritabanına yalnızca sipariş kesinleştiğinde yazılır. Sepete ürün eklemek, adet değiştirmek, çıkarmak — hepsi Redis üzerinde döner. Bu, kampanya günü en çok yazma alan işlemi veritabanından tamamen kurtarır.
- Oturum önbelleği: Oturum ve kimlik doğrulama durumu Redis'te tutulur. Her sayfa isteğinde "bu kullanıcı kim, giriş yapmış mı, hangi B2B fiyat listesine bağlı" sorusunu veritabanına sormak, zirve anında en sinsi yüktür. Oturumu önbelleğe alınca bu sorular tamamen ortadan kalkar.
Fiyat katmanının kalbi, klasik cache-aside desenidir ama disipliniyle fark yaratır. Sıcak yolda kod şuna benzer:
func (p *PriceService) Quote(ctx context.Context, v Variant) (Price, error) {
key := v.CacheKey() // ebat:gramaj:adet:selefon:teslim
if hit, ok := p.redis.Get(ctx, key); ok {
return hit, nil // ~0.3 ms — sıcak yol, motor hiç çalışmaz
}
price := p.engine.Compute(v) // maliyet tablosu + kural motoru
p.redis.SetEX(ctx, key, price, 6*time.Hour)
return price, nil
}
Bu kod basit görünür, ama iki inatçı hataya karşı özenle tasarlandı. Birincisi cache stampede: bir anahtarın TTL'i tam kampanya anında dolarsa, aynı fiyatı bekleyen binlerce istek aynı anda motora dalar ve veritabanına iner. Bunu, popüler anahtarlar için TTL'e rastgele bir jitter ekleyerek ve tekil hesaplamayı bir singleflight kilidinin arkasına koyarak çözdük — aynı anahtar için aynı anda yalnızca bir hesaplama çalışır, diğerleri sonucu bekler. İkincisi soğuk önbellek: yeni bir sunucu ayağa kalktığında önbelleği boştur; bunu birazdan anlatacağımız ısıtma adımıyla hallettik.
Önbellek katmanlarında en çok tartıştığımız konu, beklediğinizin aksine hız değil, geçersiz kılma (invalidation) oldu. Yazılımın en zor iki probleminden biri budur ve bir e-ticaret platformunda kanlı canlı karşınıza çıkar. Fiyat önbelleği için kuralımız şu: fiyatı etkileyen bir maliyet tablosu ya da kampanya kuralı değişince, o kuralı içeren tüm anahtarları etiket bazlı bir mekanizmayla topluca düşürürüz. Ama daha önemli bir karar, neyi önbelleğe almayacağımıza dair olandır. B2B müşterilerin özel fiyat listeleri kişiye özeldir; bunları genel fiyat önbelleğine koymak, bir müşterinin özel fiyatını başkasına göstermek gibi felaket bir hataya davetiye çıkarır. Bu yüzden B2B fiyatlarını, kullanıcının cari hesabına bağlı ayrı bir anahtar alanında tutarız. Önbellekte en tehlikeli hata yavaşlık değil, yanlış veriyi hızlıca sunmaktır.
Sepet katmanında da benzer bir disiplin var. Sepeti Redis'te tutmak yazma yükünü veritabanından kurtarır, ama Redis uçucu bir bellektir; bir düğüm giderse sepetler uçabilir. Bunu, Redis'i kalıcılık (AOF) ile yapılandırıp sepetleri düğümler arası çoğaltarak dengeledik. Kritik ilke şu: kaybı tolere edilebilir veriyi hıza, tolere edilemez veriyi dayanıklılığa optimize edin. Yarım kalmış bir sepetin kaybolması can sıkıcıdır ama telafi edilebilir; kesinleşmiş bir siparişin kaybolması affedilmez. Bu ayrım, hangi verinin nerede yaşayacağına dair bütün kararlarımızın pusulasıdır.
Elasticsearch: veritabanının önündeki kalkan
Fiyat, sepet ve oturumu Redis'e taşımak yazma ve nokta-okuma yükünü çözer. Ama e-ticarette en hacimli trafik başka bir yerden gelir: gezinme. Kategori sayfaları, ürün listeleri, filtreler, arama sonuçları. Kampanya gününde herkes önce göz gezdirir. Bu sorguların hepsini ilişkisel veritabanına yöneltirseniz, karmaşık JOIN'ler ve LIKE aramalarıyla veritabanını dize getirirsiniz. Klasik "ürünleri kategori ve fiyata göre filtrele, stok durumuna göre sırala" sorgusu, milyonlarca varyantlık bir katalogda tek başına bir cinayettir.
Biz bu yükü hiç veritabanına uğratmıyoruz. MatbaaStore'da ürün kataloğu, kampanyalar ve blog içeriği Elasticsearch'te indekslenir. Kategori sayfaları, filtreler, "kartvizit" araması — hepsi Elasticsearch'ten döner. Ölçtüğümüz rakam net: kategori sayfaları kampanya trafiğinin altında bile 20 ms'nin altında yanıt verir. Veritabanı bu okuma trafiğinin varlığından bile habersizdir.
Burada altını çizmemiz gereken bir mimari ilke var: Elasticsearch'ü bir "arama kutusu" olarak görmeyin. O, katalog okuma trafiğinin tamamını üstlenen birincil okuma katmanınızdır. Veritabanı ise doğruluğun kaynağıdır (source of truth) ama okuma yolunda değildir. Ürün güncellendiğinde veritabanına yazar, ardından bir olay akışıyla Elasticsearch indeksini tazeleriz. Okuma ile yazma yollarını böyle ayırınca, kampanya gününde gezinme yükü ne kadar artarsa artsın veritabanına dokunmaz.
Bu ayrımın bir bedeli vardır ve dürüst olmak gerekir: tutarlılık artık anlıktan gecikmeliye (eventual consistency) döner. Ürünü güncellediğinizde Elasticsearch indeksi birkaç saniye sonra tazelenir; o birkaç saniye boyunca listede eski bilgi görünebilir. Çoğu ekip bundan korkar ve "her şey her an tutarlı olsun" diye tutar, sonra da veritabanını okuma yüküyle boğar. Oysa doğru soru şudur: bir kategori sayfasında bir ürünün açıklamasının üç saniye geç güncellenmesi gerçekten bir felaket mi? Değil. Ama fiyatın ve stok durumunun yanlış görünmesi felakettir. Bu yüzden çizgiyi net çekeriz: gezinme ve arama gibi görsel bilgi Elasticsearch'ten gecikmeli tutarlılıkla gelir; sipariş kesinleşirken fiyat ve stok, o an veritabanının doğruluk kaynağından bir kez daha doğrulanır. Kullanıcı listede gördüğüyle ödediği arasında asla bir fark yaşamaz.
Elasticsearch'ün kampanya gününde ölçeklenmesi de veritabanınınkinden köklü biçimde farklıdır. İlişkisel veritabanını yatay ölçeklemek zordur; okuma replikaları, sharding, hepsi ağrılıdır. Elasticsearch ise doğası gereği dağıtık ve okuma için yatay ölçeklenir — indeksi parçalara böler, düğüm ekleyerek okuma kapasitesini neredeyse lineer artırırsınız. Katalog okuma trafiğini bu katmana taşımanın gizli kazancı budur: zaten ölçeklenmesi kolay olan işi, ölçeklenmesi kolay olan sisteme verirsiniz.
İlişkisel veritabanı sipariş bütünlüğü içindir, katalog gezmek için değil. Gezinme trafiğini veritabanından uzak tutan her karar, kampanya gününde size nefes aldırır.
Hedef: veritabanı yükü sabit kalır
Şimdiye kadar anlattığımız her katman aslında tek bir cümleye hizmet ediyor, ve bu cümle MatbaaStore mimarisinin manifestosudur: trafik on kat artsa da veritabanının gördüğü yük değişmesin. Bu, kulağa slogan gibi gelen ama son derece somut, ölçülebilir bir hedeftir.
Rakamlarla konuşalım. Normal günde veritabanımız saniyede yaklaşık 300-400 sorgu görür. Kampanya gününde uygulama katmanına gelen istek saniyede 8.000'e çıktığında, veritabanının gördüğü sorgu sayısı ne olur dersiniz? Cevap: hâlâ 300-400 civarı. Belki sipariş kesinleşmeleri arttığı için yazma tarafında hafif bir tırmanış, ama okuma tarafı neredeyse düz bir çizgi. Çünkü:
- Fiyat sorgularının %97'si Redis'ten dönüyor, motor bile çalışmıyor.
- Sepet işlemlerinin tamamı Redis'te, veritabanına yalnızca kesinleşen sipariş yazılıyor.
- Oturum kontrolleri Redis'te, her istekte kimlik sorgusu yok.
- Katalog gezinme ve arama Elasticsearch'te, veritabanına hiç inmiyor.
Veritabanına kalan tek gerçek iş, kesinleşen siparişleri kalıcı ve tutarlı biçimde yazmaktır. Bu da zaten ölçekleme değil, doğruluk problemidir; ve sipariş hacmi trafik kadar patlamaz — 8.000 kişi fiyata bakar, belki 400'ü sipariş verir. Böylece grafiği izlerken içiniz rahat eder: uygulama sunucularının CPU'su yükselip alçalır, Redis bağlantı sayısı zıplar, Elasticsearch sorgu sayısı katlanır — ama veritabanının yük çizgisi kampanya boyunca neredeyse yatay uzanır. Bir mimarinin sağlığını tek bir grafikle anlatmanız gerekseydi, o grafik bu olurdu.
Bu hedefi ölçülebilir kılan şey, onu bir dilek olmaktan çıkarıp bir kabul kriterine (acceptance criteria) dönüştürmemizdi. Kampanya öncesi kontrol listemizde tek bir kırmızı çizgi vardır: yük testi sırasında veritabanına düşen sorgu oranı normal günün yüzde yirmisini aşarsa, o kampanyaya girmeyiz. Bu, kulağa katı gelen ama son derece pratik bir kuraldır; çünkü bir sınır koymazsanız, "birazcık daha veritabanına sorsak ne olur" diyen küçük kararlar zamanla birikir ve bir gün sizi kampanya gecesi vurur. Mimaride en sinsi bozulma, tek bir büyük hatayla değil, her biri masum görünen yüzlerce küçük ödünle gelir. Ölçtüğünüz ve savunduğunuz bir sınır olmadan, iyi bir mimari yavaşça kötü bir mimariye dönüşür.
Kampanya provası: yük testi ve mavi-yeşil dağıtım
Mimarinin doğru olduğuna inanmak başka, kanıtlamak başkadır. Yıllar bize öğretti ki test edilmemiş kapasite, kapasite değildir; bir umuttur. Bu yüzden MatbaaStore'da hiçbir büyük kampanyaya prova yapmadan girmeyiz. Prova iki ayaklıdır: yük testi ve mavi-yeşil dağıtım.
Yük testinde geçmiş kampanyaların gerçek trafik desenini alır, üç katına çıkarıp sisteme geri oynatırız. "Ortalama kullanıcı" simülasyonu değil bu; gerçek kampanyanın o dar, yoğun, aynı ürünlere yüklenen davranışını taklit eden bir senaryo. Beklediğimiz zirve saniyede 8.000 istekse, testi 24.000 istekle koşarız. Amaç sistemin "çalışıp çalışmadığını" görmek değil, nerede kırıldığını bulmaktır. Çünkü her sistemin bir kırılma noktası vardır; siz onu kampanya gecesi müşteriyle değil, salı öğleden sonra kendi elinizle bulmak istersiniz.
Bu testlerde tekrar tekrar aynı dersleri aldık ve paylaşmakta fayda var:
- Redis bağlantı havuzu ilk beklenmedik darboğazdı. Uygulama sunucusu başına havuz boyutunu düşük tutunca, zirvede goroutine'ler boş bağlantı beklerken kuyruğa giriyor ve gecikme şişiyordu. Havuzu genişletmek ve bağlantıları uygulama başlarken önceden açmak p99 gecikmeyi belirgin biçimde düşürdü.
- Soğuk önbellek en pahalı senaryoydu. Boş önbellekle kampanyaya girmek, ilk saniyelerde tüm trafiği motora ve veritabanına yıkmak demek. Bu yüzden kampanya öncesi önbellek ısıtmayı zorunlu bir adım yaptık.
- Elasticsearch parça (shard) dağılımı yanlış olduğunda tek bir düğüm sıcak nokta oluyordu. İndeksi yeniden bölmek yükü düzledi.
Önbellek ısıtma, mavi-yeşil dağıtımın ayrılmaz parçası oldu. Mavi-yeşil dağıtımda iki özdeş üretim ortamı vardır: biri (mavi) canlı trafiği alır, diğeri (yeşil) yeni sürümü barındırır. Yeşil ortamı canlıya almadan önce, en çok satan varyantların fiyatını önceden hesaplayıp Redis'e doldururuz — yani yeşil ortam trafiği görmeden önce önbelleği sıcaktır:
// Kampanya öncesi önbellek ısıtma — en çok satan 5.000 varyant.
// Yeşil ortamı canlıya almadan çalıştırılır; ilk istek soğuk önbellekle karşılaşmaz.
for _, v := range topVariants {
p.Quote(ctx, v) // motoru çalıştırıp sonucu Redis'e yazar
}
log.Printf("onbellek isitildi: %d varyant hazir", len(topVariants))
Bu ısıtma bittikten sonra trafiği maviden yeşile çeviririz. Geçiş anında yeşil ortam ilk isteği bile sıcak önbellekle karşılar. Bir sorun çıkarsa — ki prova yaptığımız için nadiren çıkar — trafiği saniyeler içinde maviye geri alırız. Mavi-yeşil dağıtımın gerçek değeri sıfır kesintiyle sürüm çıkmak değil, geri dönüşün maliyetini sıfıra indirmesidir. Kampanya gecesi elinizde bir "geri al" düğmesi olması, alınabilecek en büyük risk sigortasıdır.
Bir anti-pattern'i de burada net söyleyelim, çünkü çok yaygındır: kampanya günü sürüm çıkmayın. Ekiplerin yarısı, kampanyaya son dakika bir özellik yetiştirmeye çalışır ve o özelliği kampanya sabahı canlıya iter. Bu, gecenin en yüksek riskli anında sisteme yeni ve test edilmemiş bir değişken sokmaktır. Bizim kuralımız katıdır: kampanyaya girecek her sürüm, en geç 48 saat önce yeşil ortamda çalışır, yük testinden geçer ve trafiğe alınır. Kampanya penceresi bir dondurma (freeze) penceresidir; o pencerede tek yaptığınız izlemek ve gerekirse geri almaktır, yeni kod yazmak değil. Yıllar bize şunu öğretti: kampanya gecesi kahraman olmaya çalışan ekip, çoğunlukla o gecenin faciasını da yazan ekiptir.
Prova disiplininin son parçası, kampanya sırasında neye bakacağınızı önceden kararlaştırmaktır. Panik anında yüz metriğe bakamazsınız; üç tanesine bakarsınız. Bizim üç göstergemiz nettir: veritabanı sorgu oranı (yatay kalmalı), önbellek isabet oranı (%95'in üstünde kalmalı) ve p95 yanıt gecikmesi (eşiğin altında kalmalı). Bu üçünden biri bozulursa, hangi katmanın zorlandığını saniyeler içinde anlarız — çünkü her metrik belirli bir katmanı işaret eder. İyi bir gösterge paneli, size ne olduğunu değil, nereye bakacağınızı söyleyendir.
Otomatik yatay ölçekleme: ne zaman, neye göre
Önbellek katmanları veritabanını korur, ama uygulama sunucularının kendisi de zirvede yeterli sayıda olmalıdır. Burada devreye Docker ve AWS üzerinde kurduğumuz otomatik yatay ölçekleme girer. Ama en baştan bir anti-pattern'i teşhir edelim: çoğu ekip yanlış metriğe göre ölçekler. CPU kullanımına göre ölçeklemek klasik hatadır, çünkü kampanya trafiğinde CPU tırmandığını gördüğünüzde iş işten geçmiştir — yeni sunucu 60-90 saniyede ayağa kalkarken duvar çoktan çarpmıştır.
Biz iki katmanlı bir yaklaşım kullanıyoruz. Birincisi reaktif ölçekleme: istek kuyruğu derinliği ve p95 gecikme gibi, CPU'dan daha erken sinyal veren metriklere göre yeni sunucu ekleriz. İkincisi ve daha önemlisi öngörülü ölçekleme: kampanyanın ne zaman başlayacağını zaten biliyoruz. SMS gece 00:00'da gidecekse, sistemi 23:45'te elle ya da zamanlanmış bir kuralla önden ölçekleriz. Duvarın geleceğini bildiğiniz zaman, onu karşılamak için otomatik ölçekleyicinin reaksiyonunu beklemek saflıktır.
Rakamlarla: normal günde MatbaaStore 4 uygulama sunucusuyla rahat çalışır. Büyük bir kampanya öncesi bunu öngörülü olarak 16-20'ye çıkarırız; kampanya biterken kademeli olarak geri indiririz. Redis ve Elasticsearch katmanları zaten yükün büyük kısmını emdiği için, uygulama sunucularının işi hafiftir — çoğunlukla önbellekten okuyup yanıtı biçimlendirmek. Bu yüzden yatay ölçekleme lineer ve öngörülebilir davranır; iki katına çıkardığınız sunucu, gerçekten iki katı kapasite verir. Katmanlı mimarinin en güzel yan etkisi budur: her katman kendi işini yaptığı için ölçekleme sürprizsizdir.
Yatay ölçeklemenin işe yaraması için uygulama sunucularının durumsuz (stateless) olması şarttır, ve bunu baştan bir tasarım kuralı yaptık. Oturum Redis'te, sepet Redis'te, fiyat önbellekte olduğu için hiçbir uygulama sunucusu kendi belleğinde kritik bir durum tutmaz. Bir sunucuyu istediğiniz an ekleyebilir, istediğiniz an söndürebilirsiniz; hangi kullanıcının hangi sunucuya düştüğünün hiçbir önemi yoktur. Bu, kulağa akademik gelen bir ilkedir ama pratik bedeli çok somuttur: durumu uygulama belleğinde tutan bir sistemde yatay ölçekleme, "yapışkan oturumlar" (sticky sessions) ve dengesiz yük gibi bir sürü baş ağrısına dönüşür. Biz durumu en baştan katmanlara sürdüğümüz için, ölçekleme bizim için yalnızca bir sayıyı büyütmekten ibarettir.
Son bir uyarı: otomatik ölçekleme sınırsız değildir ve olmamalıdır. Her katmanın bir tavanı vardır — Redis'in bağlantı kapasitesi, Elasticsearch'ün sorgu hacmi, veritabanının yazma sınırı. Uygulama sunucularını sınırsızca çoğaltırsanız, bir noktada alttaki bir katmanı ezersiniz ve darboğazı yukarıdan aşağıya taşımış olursunuz. Bu yüzden ölçekleme tavanını, yük testinde bulduğumuz gerçek katman sınırlarına göre belirleriz. Otomatik ölçekleme bir sihir değil, ölçülmüş sınırlar içinde çalışan bir mekanizmadır; sınırı bilmeden ölçeklemek, sadece çöküşü bir katman öteye ertelemektir.
Sonuç
Kampanya günü çökmeyen bir e-ticaret sistemi kurmak, daha büyük sunucular almakla ilgili değildir. Dikey ölçekleme bir yere kadar götürür, sonra duvara toslarsınız. Asıl mesele, yükü katmanlara dağıtıp veritabanını okuma trafiğinin cenderesinden tamamen çıkarmaktır. MatbaaStore'da yaptığımız tam olarak buydu: fiyatı, sepeti ve oturumu Redis'e; katalog gezinmesini ve aramayı Elasticsearch'e taşıdık, veritabanına yalnızca kesinleşen siparişin doğruluğunu bıraktık.
Benzer bir sistem kuruyorsanız, size somut bir sıralama önerelim. Önce şu soruyu sorun: zirve anında veritabanının gördüğü sorgu sayısı, normal güne göre değişiyor mu? Eğer değişiyorsa, bir katmanı eksik kurmuşsunuz demektir — o sorguların nereden geldiğini bulun ve önüne bir önbellek ya da bir Elasticsearch koyun. Sonra kampanyaya prova yapmadan girmeyin; beklediğiniz zirvenin üç katıyla yük testi koşun ve sistemi kırın. En son, önbelleği ısıtmadan ve elinizde bir "geri al" düğmesi olmadan hiçbir kampanya sürümünü canlıya almayın.
Otuz yıl bu işi yaptıktan sonra söyleyebileceğimiz en dürüst cümle şudur: kampanya gecesi rahat uyuyan ekip, o gece bir şey yapan ekip değildir — haftalar önce doğru katmanları kuran, provasını yapan ve veritabanı yük grafiğini yatay bir çizgiye dönüştürmüş olan ekiptir. Duvar yine gelecek. Siz onu karşılamaya çoktan hazır olun.