Ders 08 / 15
Anahtar Döndürme
Döndürme, iki sırrın birlikte geçerli kaldığı pencere cinsinden ölçülür: on yedi sırrın asgari örtüşmesi 60 ile 1.440 dakika arasında, ortalaması 815 dakika ve on birinde pencereyi tek başına başlangıçta okuyan dört uygulama belirliyor. Örtüşme kısa tutulduğunda hesap tersine döner — 60 dakikalık pencerede 36 istemci yeni değeri kaçırıyor ve 87.427 meşru istek kesiliyor, sıra ters çevrildiğinde her istekte okuyan tek uygulama bile kesiliyor. Aynı pencere, hata üzerine yeniden okuma eklendiğinde 1.440 dakikadan 240 dakikaya iniyor.
İçindekiler
Önceki ders on beş kalemde açık pencerenin kısaltılamadığını gösterdi: imza anahtarları, dış geçit anahtarları ve önbellek sunucusu istek üzerine kimlik bilgisi üretmiyor. O kalemler için geriye tek araç kalıyor — sırrı belirli aralıklarla değiştirmek. Döndürme, açık pencereyi periyoduyla sınırlar; doksan günde bir döndürülen bir anahtarın penceresi doksan günden uzun olamaz.
Ama döndürme bir anda olmaz. Yeni değer depoya yazıldığı anda hiçbir uygulama ondan haberdar değildir; her uygulama kendi okuma biçimine göre, kendi hızında geçer. O geçiş tamamlanana kadar iki değer de geçerli kalmak zorundadır. Bu ders o zorunlu pencereyi ölçer: kaç dakika, neyin belirlediği, kısa tutulduğunda ne kesildiği ve sıra ters çevrildiğinde ne olduğu.
- SR13. Önceki iki dersin modeli sürüyor: dokuz uygulama, on yedi okunan sır. Ortam
kurgudur, ölçülen şey
nodeile yazılmış bir modeldir ve gerçek sır değeri taşımaz. - SR14. Geçiş süresi okuma biçiminden türetilir. Her istekte okuyan uygulama derhal geçer; önbellekli uygulama en geç önbellek ömrü kadar sonra; yalnız başlangıçta okuyan uygulama ancak yeniden başladığında. Sonuncusu için modelde ortalama örnek yaşam süresi kullanılıyor: günlük yeniden başlatma sayısına bölünmüş örnek sayısı.
- SR15. Kesilen istek en kötü durum sayılır: bir uygulamanın bütün örnekleri geçiş süresinin sonunda geçer. Gerçekte geçişler örnekler arasına dağılır ve kesilen istek bu sayının altında kalır; sıralaması değişmez.
- SR16. On yedi sır ayrı ayrı döndürülür ve sonuçlar toplanır. Deponun eski değeri iptal etmesi anlık kabul ediliyor; iptalin kendi yayılma süresi modellenmiyor.
- SR17. Rastgelelik yok; bütün sayılar model tablolarından türetiliyor ve çıktı koşumdan koşuma aynı.
Pencereyi En Yavaş Okuyucu Belirler
// gecis.mjs — dondurmede iki sirrin birlikte gecerli kalmasi gereken asgari sure. MODELDIR. // Ortam KURGUDUR; GERCEK SIR DEGERI YOKTUR, yalniz sir yollari ve gecis sureleri modellenir. export const OKUR = { "portal-onyuz": ["imza/oturum-imzalama"], "portal-api": ["veri/portal-birincil", "veri/portal-okuma", "imza/oturum-imzalama", "imza/ic-cagri-imzalama", "altyapi/onbellek", "altyapi/gunluk-yazma"], "abone-kayit": ["veri/portal-birincil", "dis/eposta-gecidi", "dis/kisa-mesaj-gecidi"], "fatura-servisi": ["veri/fatura-birincil", "veri/portal-okuma", "veri/arsiv", "dis/odeme-gecidi", "imza/belge-imzalama"], "odeme-koprusu": ["dis/odeme-gecidi"], "saha-api": ["veri/saha-birincil", "kuyruk/is-emri-kuyrugu", "dis/harita-servisi", "imza/ic-cagri-imzalama"], "is-emri": ["veri/saha-birincil", "kuyruk/is-emri-kuyrugu", "kuyruk/bildirim-kuyrugu", "dis/harita-servisi"], "bildirim": ["kuyruk/bildirim-kuyrugu", "dis/eposta-gecidi", "dis/kisa-mesaj-gecidi"], "rapor-uretici": ["veri/portal-okuma", "veri/arsiv", "altyapi/nesne-deposu", "dis/eposta-gecidi"], }; // bicim/omur: sirrin okunma bicimi. ornek: calisan ornek. yb: gunluk yeniden baslatma. // istek: gunluk istek (kurgu birim). export const UYG = { "portal-onyuz": { bicim: "baslangicta", omur: 0, ornek: 4, yb: 6, istek: 84000 }, "portal-api": { bicim: "onbellekli", omur: 60, ornek: 8, yb: 12, istek: 96000 }, "abone-kayit": { bicim: "baslangicta", omur: 0, ornek: 2, yb: 3, istek: 1400 }, "fatura-servisi": { bicim: "onbellekli", omur: 240, ornek: 2, yb: 2, istek: 6200 }, "odeme-koprusu": { bicim: "her-istekte", omur: -1, ornek: 3, yb: 2, istek: 3400 }, "saha-api": { bicim: "onbellekli", omur: 60, ornek: 5, yb: 8, istek: 42000 }, "is-emri": { bicim: "baslangicta", omur: 0, ornek: 3, yb: 4, istek: 9600 }, "bildirim": { bicim: "onbellekli", omur: 15, ornek: 2, yb: 3, istek: 12000 }, "rapor-uretici": { bicim: "baslangicta", omur: 0, ornek: 1, yb: 1, istek: 320 }, }; export const AD = Object.keys(UYG); export const SIR = [...new Set(Object.values(OKUR).flat())].sort(); export const okurlar = (s) => AD.filter((a) => OKUR[a].includes(s)); // gecis: yeni deger yazildiktan sonra uygulamanin ona gecmesi icin gereken en kotu sure (dk). // her istekte okuyan derhal gecer; onbellekli en gec onbellek omru kadar sonra; baslangicta // okuyan ancak yeniden baslayinca, yani ortalama ornek yasam suresi kadar sonra. export const gecis = (a) => UYG[a].bicim === "her-istekte" ? 0 : UYG[a].bicim === "onbellekli" ? UYG[a].omur : Math.round(1440 * UYG[a].ornek / UYG[a].yb); export const ortusme = (s) => Math.max(...okurlar(s).map(gecis)); export const gen = (B) => (h) => h.map((v, j) => j ? String(v).padStart(B[j]) : String(v).padEnd(B[0])).join(""); if (import.meta.url === `file://${process.argv[1]}`) { const yz = gen([19, 6, 10, 8, 24]), yz0 = gen([16, 14, 8, 6, 12]); console.log(`gecis suresi — yeni degere gecmek icin gereken en kotu sure (dk)`); console.log(yz0(["uygulama", "bicim", "ornek", "yb", "gecis(dk)"])); for (const a of AD) console.log(yz0([a, UYG[a].bicim, UYG[a].ornek, UYG[a].yb, gecis(a)])); console.log(`\n${yz(["sir", "okur", "ortusme", "= saat", "belirleyen uygulama"])}`); const sirali = [...SIR].sort((x, y) => ortusme(y) - ortusme(x) || x.localeCompare(y)); for (const s of sirali) console.log(yz([s.split("/")[1], okurlar(s).length, ortusme(s), (ortusme(s) / 60).toFixed(1), okurlar(s).filter((a) => gecis(a) === ortusme(s)).join(",")])); const O = SIR.map(ortusme); console.log(`\n${SIR.length} sir; asgari ortusme en uzun ${Math.max(...O)} dk, en kisa ` + `${Math.min(...O)} dk, ortalama ${(O.reduce((t, x) => t + x, 0) / O.length).toFixed(0)} dk`); const yavas = AD.filter((a) => UYG[a].bicim === "baslangicta"); console.log(`tek ortak pencerede dondurulurse gereken ortusme: ${Math.max(...O)} dk`); console.log(`ortusmeyi belirleyen: baslangicta okuyan ${yavas.length} uygulama, ` + `${SIR.filter((s) => okurlar(s).some((a) => UYG[a].bicim === "baslangicta" && gecis(a) === ortusme(s))).length} / ${SIR.length} sirda tek basina`); }
gecis suresi — yeni degere gecmek icin gereken en kotu sure (dk) uygulama bicim ornek yb gecis(dk) portal-onyuz baslangicta 4 6 960 portal-api onbellekli 8 12 60 abone-kayit baslangicta 2 3 960 fatura-servisi onbellekli 2 2 240 odeme-koprusu her-istekte 3 2 0 saha-api onbellekli 5 8 60 is-emri baslangicta 3 4 1080 bildirim onbellekli 2 3 15 rapor-uretici baslangicta 1 1 1440 sir okur ortusme = saat belirleyen uygulama nesne-deposu 1 1440 24.0 rapor-uretici eposta-gecidi 3 1440 24.0 rapor-uretici arsiv 2 1440 24.0 rapor-uretici portal-okuma 3 1440 24.0 rapor-uretici harita-servisi 2 1080 18.0 is-emri bildirim-kuyrugu 2 1080 18.0 is-emri is-emri-kuyrugu 2 1080 18.0 is-emri saha-birincil 2 1080 18.0 is-emri kisa-mesaj-gecidi 2 960 16.0 abone-kayit oturum-imzalama 2 960 16.0 portal-onyuz portal-birincil 2 960 16.0 abone-kayit odeme-gecidi 2 240 4.0 fatura-servisi belge-imzalama 1 240 4.0 fatura-servisi fatura-birincil 1 240 4.0 fatura-servisi gunluk-yazma 1 60 1.0 portal-api onbellek 1 60 1.0 portal-api ic-cagri-imzalama 2 60 1.0 portal-api,saha-api 17 sir; asgari ortusme en uzun 1440 dk, en kisa 60 dk, ortalama 815 dk tek ortak pencerede dondurulurse gereken ortusme: 1440 dk ortusmeyi belirleyen: baslangicta okuyan 4 uygulama, 11 / 17 sirda tek basina
Üstteki tablo geçiş süresinin nereden geldiğini gösteriyor. Ödeme köprüsü sırrı her istekte okuduğu için sıfır dakikada geçer; bildirim servisi on beş dakikalık önbelleğiyle en geç on beş dakikada. Yalnız başlangıçta okuyan dört uygulamada ise geçiş süresi bir ayar değil, bir istatistiktir: rapor üreticisi tek örnekle çalışıyor ve günde bir kez yeniden başlıyor, dolayısıyla yeni değeri ortalama bin dört yüz kırk dakika sonra görüyor. Bu sayı sır yönetiminin hiçbir ayarında yazmaz, dağıtım düzeninden gelir.
Alt tablo asıl ölçüyü veriyor. Bir sırrın asgari örtüşmesi, onu okuyanların en yavaşının geçiş süresidir; başka bir ifadeyle örtüşme bir ortalama değil, bir azami değerdir. Bu yüzden tek okuyucusu olan nesne deposu anahtarı ile üç okuyucusu olan e-posta geçidi anahtarı aynı satırda: ikisinde de en yavaş okuyucu rapor üreticisidir ve ikisi de yirmi dört saat örtüşme gerektirir. Okuyucu sayısı örtüşmeyi belirlemiyor; okuyucuların en kötüsü belirliyor.
En kısa örtüşme gerektiren üç sır, yalnız önbellekli uygulamalar tarafından okunanlardır: iç çağrı imzalama anahtarı iki uygulama tarafından okunuyor ve altmış dakikada dönebiliyor. Bin dört yüz kırk dakika ile altmış dakika arasında yirmi dört kat var ve bu farkın tamamı okuma biçiminden geliyor — sırların duyarlılığında ya da politikalarında hiçbir fark yok.
Son satır bulguyu tek cümlede topluyor: başlangıçta okuyan dört uygulama, on yedi sırrın on birinde örtüşmeyi tek başına belirliyor. Bunlar sistemin en küçük, en az istek alan uygulamalarıdır — rapor üreticisi günde üç yüz yirmi istek görüyor. Döndürme takviminin tamamı bu dört uygulamanın yeniden başlatma alışkanlığına bağlı.
Pencereyi Kısaltmanın Faturası
Yirmi dört saatlik örtüşme döndürmenin amacına ters düşer: sızmış eski değer o yirmi dört saat boyunca da çalışır. Pencereyi kısaltmanın ölçülebilir bir karşılığı var.
// sira.mjs — ortusme penceresi kisa tutuldugunda ve sira ters oldugunda ne kesiliyor import { AD, OKUR, SIR, UYG, gecis, okurlar, ortusme, gen } from "./gecis.mjs"; // T dakikalik ortusmede bir uygulama gecis(a) - T dakika eski degerde kalir ve o sure boyunca // o sirra bagli istekleri duser. On yedi sir ayri ayri dondurulur, sonuclar toplanir. const kesilenIstek = (T, g = gecis) => SIR.reduce((t, s) => t + okurlar(s) .reduce((x, a) => x + UYG[a].istek * Math.max(0, g(a) - T) / 1440, 0), 0); const kacanIstemci = (T, g = gecis) => SIR.reduce((t, s) => t + okurlar(s) .reduce((x, a) => x + (g(a) > T ? UYG[a].ornek : 0), 0), 0); const yz = gen([14, 18, 16, 20]); console.log(yz(["ortusme(dk)", "kacan istemci", "kesilen istek", "eski deger gecerli"])); for (const T of [0, 15, 60, 240, 960, 1080, 1440]) console.log(yz([T, kacanIstemci(T), Math.round(kesilenIstek(T)), `${T} dk`])); const ORT = SIR.map(ortusme), toplamOrt = ORT.reduce((t, x) => t + x, 0); console.log(`\nsir basina kendi asgari ortusmesi kullanilirsa: kacan istemci 0, kesilen istek 0,`); console.log(`eski deger ortalama ${(toplamOrt / SIR.length).toFixed(0)} dk ` + `(${(toplamOrt / SIR.length / 60).toFixed(1)} saat) daha gecerli kalir`); // ters sira: once eski deger iptal edilir, YAZ dakika sonra yenisi yazilir, sonra yayilir. const YAZ = 5; console.log(`\nters sira (once iptal, ${YAZ} dk sonra yeni deger): kacan istemci ` + `${kacanIstemci(-1)}, kesilen istek ${Math.round(kesilenIstek(0) + SIR.reduce((t, s) => t + okurlar(s).reduce((x, a) => x + UYG[a].istek * YAZ / 1440, 0), 0))}`); console.log(`dogru sirada hic kesilmeyen tek uygulama her istekte okuyan odeme-koprusu; ` + `ters sirada o da ${Math.round(OKUR["odeme-koprusu"].length * UYG["odeme-koprusu"].istek * YAZ / 1440)} istek kaybeder`); // hata uzerine yeniden okuma: baslangicta okuyan uygulama kimlik hatasinda sirri tazeler. const HATA = 5; const g2 = (a) => UYG[a].bicim === "baslangicta" ? HATA : gecis(a); const ORT2 = SIR.map((s) => Math.max(...okurlar(s).map(g2))); console.log(`\nhata uzerine yeniden okuma eklenirse (baslangicta okuyan ${AD.filter((a) => UYG[a].bicim === "baslangicta").length} uygulama, gecis ${HATA} dk):`); console.log(` asgari ortusme en uzun ${Math.max(...ORT)} -> ${Math.max(...ORT2)} dk, ` + `ortalama ${(toplamOrt / SIR.length).toFixed(0)} -> ` + `${(ORT2.reduce((t, x) => t + x, 0) / SIR.length).toFixed(0)} dk`); console.log(` 60 dk ortusmede kesilen istek ${Math.round(kesilenIstek(60))} -> ` + `${Math.round(kesilenIstek(60, g2))}, kacan istemci ${kacanIstemci(60)} -> ` + `${kacanIstemci(60, g2)}`);
ortusme(dk) kacan istemci kesilen istek eski deger gecerli 0 110 125422 0 dk 15 104 115642 15 dk 60 36 87427 60 dk 240 26 67567 240 dk 960 16 3627 960 dk 1080 4 320 1080 dk 1440 0 0 1440 dk sir basina kendi asgari ortusmesi kullanilirsa: kacan istemci 0, kesilen istek 0, eski deger ortalama 815 dk (13.6 saat) daha gecerli kalir ters sira (once iptal, 5 dk sonra yeni deger): kacan istemci 113, kesilen istek 128693 dogru sirada hic kesilmeyen tek uygulama her istekte okuyan odeme-koprusu; ters sirada o da 12 istek kaybeder hata uzerine yeniden okuma eklenirse (baslangicta okuyan 4 uygulama, gecis 5 dk): asgari ortusme en uzun 1440 -> 240 dk, ortalama 815 -> 102 dk 60 dk ortusmede kesilen istek 87427 -> 3875, kacan istemci 36 -> 10
Tablo bir ayar eğrisidir ve iki uçtan okunmalıdır. En üstteki satır örtüşmenin sıfır olduğu durumdur: yeni değer yazılır yazılmaz eski iptal edilir. Yüz on istemci — yani dokuz uygulamanın çalışan otuz örneğinin okudukları sırlar üzerinden sayıldığında yüz on kalem — eski değerde kalıyor ve on yedi döndürmenin toplamında yüz yirmi beş bin dört yüz yirmi iki meşru istek kesiliyor. En alttaki satır tersidir: bin dört yüz kırk dakikalık örtüşmede hiçbir istemci kaçmıyor, hiçbir istek kesilmiyor ve eski değer tam bir gün daha geçerli kalıyor.
Ortadaki satırlar dağılımın nasıl olduğunu gösteriyor. Altmış dakikalık örtüşme kaçan istemciyi yüz ondan otuz altıya indiriyor, ama kesilen isteği yalnız yüz yirmi beş binden seksen yedi bine. Oranların eşleşmemesi anlamlıdır: kaçan istemcilerin çoğu portal uygulama arayüzünün sekiz örneğidir ve o örnekler altmış dakikada geçer; kesilen isteğin çoğu ise tek bir uygulamadan gelir. Portal ön yüzü günde seksen dört bin istek görüyor ve dokuz yüz altmış dakika sonra geçiyor; bu tek uygulama, altmış dakikalık örtüşmede kesilen seksen yedi bin isteğin elli iki bin beş yüzünü tek başına üretiyor.
Sonraki iki satır doğru yordamı yazıyor. Her sır kendi asgari örtüşmesiyle döndürülürse kesilen istek sıfırdır; bedel, eski değerin ortalama sekiz yüz on beş dakika daha geçerli kalmasıdır. Yani örtüşme bir güvenlik ayarı değil, açık pencereye eklenen sabit bir süredir: doksan günlük periyotla döndürülen bir anahtarın gerçek en kötü penceresi doksan gün değil, doksan gün artı on üç buçuk saattir.
Ters sıra satırı ayrı bir sınıftır. Eski değer önce iptal edilip yenisi beş dakika sonra yazıldığında kaçan istemci yüz on üçe, kesilen istek yüz yirmi sekiz bin altı yüz doksan üçe çıkıyor. Aradaki fark büyük değil — üç istemci, üç bin istek — ama fark kimde olduğu belirleyicidir: doğru sırada hiç etkilenmeyen ödeme köprüsü, ters sırada on iki ödeme isteği kaybediyor. Sıfır dakikada geçen bir uygulamayı kesmenin tek yolu, geçilecek değeri henüz yazmamış olmaktır. Ters sıranın belirtisi budur ve gösterge tablosunda yalnız bu on iki istek görünür.
Pencere Nerede Kısalır
Son iki satır kursun asıl sorusunu yanıtlıyor. Yirmi dört saatlik örtüşme bir sır yönetimi sorunu değildir; başlangıçta okuyan bir uygulamanın sırrı bir daha hiç okumaması sorunudur. Uygulamalara kimlik hatası aldıklarında sırrı tazeleme davranışı eklendiğinde asgari örtüşme bin dört yüz kırk dakikadan iki yüz kırk dakikaya, ortalama sekiz yüz on beş dakikadan yüz iki dakikaya iniyor; altmış dakikalık örtüşmede kesilen istek seksen yedi bin dört yüz yirmi yediden üç bin sekiz yüz yetmiş beşe düşüyor, yani yirmi iki kat.
Bu değişikliğin nerede yapıldığı önemlidir. Sır deposunda, döndürme takviminde ya da çalışma zamanı savunmasında değil, uygulama kodunda yapılır: kimlik doğrulama hatası yakalanır, sır yeniden okunur, istek bir kez daha denenir. Birkaç düzine satırlık bir davranış döndürme penceresini yirmi dört kat kısaltıyor ve bir kez yazıldığında bütün sırlar için geçerli oluyor. Aynı sonucu çalışma zamanında elde etmenin yolu her sır için ayrı örtüşme takvimi tutmak, her döndürmede hangi uygulamanın geçtiğini izlemek ve geçmeyeni elle yeniden başlatmaktır.
Geriye kalan iki yüz kırk dakika ise gerçekten çalışma zamanına aittir: fatura servisinin dört saatlik önbellek ömrü. O bir ayardır ve düşürülebilir; düşürüldüğünde önceki dersin ölçtüğü depo isteği artar. Örtüşme, önbellek ömrü ve depo yükü tek bir sayının üç görünümüdür.
Özet
- Bir sırrın asgari örtüşmesi, onu okuyanların en yavaşının geçiş süresidir. On yedi sırda bu süre 60 ile 1.440 dakika arasında, ortalaması 815 dakika; tek ortak pencere kullanılırsa 1.440 dakika.
- Örtüşmeyi belirleyen şey sırrın duyarlılığı ya da okuyucu sayısı değil, okuma biçimidir. Başlangıçta okuyan dört uygulama 17 sırrın 11’inde pencereyi tek başına belirliyor.
- Örtüşme sıfıra çekildiğinde 110 istemci eski değerde kalıyor ve 125.422 meşru istek kesiliyor; 60 dakikada 36 istemci ve 87.427 istek, 1.440 dakikada sıfır ve sıfır. Kesilen isteğin 52.500’ü tek bir uygulamadan, portal ön yüzünden geliyor.
- Her sır kendi asgari örtüşmesiyle döndürülürse kesme sıfırdır; bedel, eski değerin ortalama 815 dakika daha geçerli kalmasıdır. Doksan günlük periyodun gerçek penceresi doksan gün artı on üç buçuk saattir.
- Ters sıra (önce iptal, sonra yazma) kesileni 128.693’e çıkarıyor. Asıl belirtisi hacim değil, doğru sırada hiç etkilenmeyen ödeme köprüsünün 12 istek kaybetmesidir.
- Örtüşmeyi kısaltan değişiklik kod aşamasındadır: hata üzerine yeniden okuma, asgari örtüşmeyi 1.440’tan 240 dakikaya, 60 dakikalık pencerede kesileni 22 kat aşağı indiriyor.
Sonraki Adım
İki ders boyunca ölçülen şey aynı nesnenin iki özelliğiydi: sırrın ömrü ve sırrın değişme maliyeti. İkisi de sırrın var olduğunu varsayıyordu. Bu varsayım kaldırılabilir. Bir uygulamanın veri tabanına bağlanmak için taşıdığı değer, o uygulamanın kim olduğunu kanıtlamanın bir yoludur; kanıt platform tarafından verilirse taşınacak bir değer kalmaz. Sonraki ders bunu tek eksende sayar: iş yükü kimliği otuz bir kalemin kaçını ortadan kaldırıyor, geriye kaç kalem ve hangi sistemler kalıyor, kaç uygulama hiçbir statik sır taşımaz hâle geliyor — ve sırrın yerini alan güven ilişkisinin kendisi kaç satır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.