İçeriğe geç
academia.sh

Ders 06 / 15

Sır Deposu Mimarisi

Sır deposu erişim denetimi cinsinden ölçülür: yol öneki politikası dokuz uygulamaya 79 (uygulama, sır) kalemi açıyor, doksan günlük okuma kaydı 31 diyor ve 48 kalem hiç kullanılmadan duruyor. Üç sırrı hiçbir uygulama okumuyor; en geniş veri sırrına altı uygulama erişebiliyor. Merkezîleşmenin bedeli tek noktadır — dokuz uygulamanın hiçbiri depo olmadan başlayamıyor ve günde 41 başlatma denemesi bu tek noktadan geçiyor.

İçindekiler

Önceki ders istek katmanını kapattı: uygulama katmanı güvenlik duvarının ve davranış puanlamasının neyi yakaladığı, neyi kaçırdığı ve neyi yanlış yere kestiği sayıldı. Bütün o katmanların arkasında tek bir sessiz varsayım duruyordu — uygulamanın veri deposuna, kuyruğa ve dış geçitlere bağlanmak için taşıdığı anahtarların yerli yerinde ve yalnız kendisinde olduğu. Bu ders o varsayımı kaldırır ve anahtarların durduğu yeri, yani sır deposunu, tek bir eksende ölçer: kim neye erişebiliyor.

Sırrın nerede saklandığı, kaç kopya hâlinde durduğu ve merkezî bir deponun kopyayı nasıl azalttığı daha önce ölçüldü ve burada tekrarlanmıyor. Buranın sorusu depo kurulduktan sonra başlıyor: depo kurulmuş, sırlar içine konmuş ve her uygulamaya bir politika yazılmıştır. O politika kaç kaleme izin veriyor, uygulamalar kaçını gerçekten okuyor ve aradaki fark ele geçen bir uygulamadan ne kadar açıyor.

  • SR1. Abone portalı ve saha uygulamasının üretim ortamı kurgudur: dokuz uygulama, yirmi sır ve bir sır deposu. Ölçülen şey node ile yazılmış bir modeldir.
  • SR2. Modelde gerçek sır değeri yoktur; yalnız sır yolları, uygulama adları ve sayılar taşınır. Sır yolu alan/kalem biçimindedir ve politika yol öneki ile yazılır.
  • SR3. Bir politika kuralı, kendisiyle başlayan her sır yolunu açar. veri/ kuralı beş veri sırrının beşini birden verir; tam yol yazan kural tek sır verir.
  • SR4. Okuma kaydı iki pencerede okunur: son otuz gün ve son doksan gün. Doksan günlük pencere bu modelde gerçek ihtiyaç sayılır; gerçekte hiçbir pencere ihtiyacın tamamını göstermez.
  • SR5. Rastgelelik yok; bütün sayılar model tablolarından türetiliyor ve çıktı koşumdan koşuma aynı. Yeniden başlatma sayıları kurgu birimdir.
  • SR6. Deponun kendi kesintisi tek değerli modellenir: depo ya vardır ya yoktur. Kısmi bozulma ve çoğaltılmış depo modellenmiyor; çoğaltma kesinti kalemini düşürür, erişim kalemini düşürmez.

Erişim Matrisi

// depo.mjs — sir deposu envanteri, politika kurallari ve okuma kaydi. MODELDIR.
// Abone portali ve saha uygulamasinin uretim ortami KURGUDUR; dokuz uygulama, bir depo.
// GERCEK SIR YOKTUR: yalniz sir YOLLARI, uygulama adlari ve sayilar modellenir.
export const SIR = Object.entries({
  veri: ["portal-birincil", "portal-okuma", "saha-birincil", "fatura-birincil", "arsiv"],
  kuyruk: ["olcum-alim", "bildirim-kuyrugu", "is-emri-kuyrugu"],
  dis: ["odeme-gecidi", "harita-servisi", "kisa-mesaj-gecidi", "eposta-gecidi", "kimlik-saglayici"],
  imza: ["oturum-imzalama", "belge-imzalama", "ic-cagri-imzalama"],
  altyapi: ["nesne-deposu", "onbellek", "olcut-yazma", "gunluk-yazma"],
}).flatMap(([a, l]) => l.map((k) => `${a}/${k}`));

// kural: politikanin verdigi yol oneki. okur: son 30 gunun okuma kaydindaki sirlar.
// bicim/omur: sirrin nasil alindigi. yb: gunde kac yeniden baslatma (dagitim + olcek).
export const UYG = {
  "portal-onyuz": { kural: ["dis/kimlik-saglayici", "imza/"], bicim: "baslangicta", omur: 0, yb: 6,
    okur: ["imza/oturum-imzalama"] },
  "portal-api": { kural: ["veri/", "imza/", "altyapi/"], bicim: "onbellekli", omur: 60, yb: 12,
    okur: ["veri/portal-birincil", "veri/portal-okuma", "imza/oturum-imzalama",
      "imza/ic-cagri-imzalama", "altyapi/onbellek"] },
  "abone-kayit": { kural: ["veri/", "dis/"], bicim: "baslangicta", omur: 0, yb: 3,
    okur: ["veri/portal-birincil", "dis/eposta-gecidi", "dis/kisa-mesaj-gecidi"] },
  "fatura-servisi": { kural: ["veri/", "dis/", "imza/belge-imzalama"], bicim: "onbellekli",
    omur: 240, yb: 2,
    okur: ["veri/fatura-birincil", "veri/portal-okuma", "dis/odeme-gecidi", "imza/belge-imzalama"] },
  "odeme-koprusu": { kural: ["dis/"], bicim: "her-istekte", omur: -1, yb: 2,
    okur: ["dis/odeme-gecidi"] },
  "saha-api": { kural: ["veri/", "kuyruk/", "dis/harita-servisi", "imza/"], bicim: "onbellekli",
    omur: 60, yb: 8,
    okur: ["veri/saha-birincil", "kuyruk/is-emri-kuyrugu", "dis/harita-servisi",
      "imza/ic-cagri-imzalama"] },
  "is-emri": { kural: ["veri/", "kuyruk/"], bicim: "baslangicta", omur: 0, yb: 4,
    okur: ["veri/saha-birincil", "kuyruk/is-emri-kuyrugu", "kuyruk/bildirim-kuyrugu"] },
  "bildirim": { kural: ["kuyruk/", "dis/"], bicim: "onbellekli", omur: 15, yb: 3,
    okur: ["kuyruk/bildirim-kuyrugu", "dis/eposta-gecidi", "dis/kisa-mesaj-gecidi"] },
  "rapor-uretici": { kural: ["veri/", "altyapi/"], bicim: "baslangicta", omur: 0, yb: 1,
    okur: ["veri/portal-okuma", "veri/arsiv", "altyapi/nesne-deposu"] },
};
export const AD = Object.keys(UYG);
// 30 gunluk pencerede hic gorunmeyen, 90 gunde goruleni olan mesru okumalar.
export const NADIR = [["fatura-servisi", "veri/arsiv"], ["is-emri", "dis/harita-servisi"],
  ["portal-api", "altyapi/gunluk-yazma"], ["rapor-uretici", "dis/eposta-gecidi"]];

export const erisir = (a, s) => UYG[a].kural.some((k) => s.startsWith(k));
export const okur90 = (a) => [...UYG[a].okur, ...NADIR.filter((n) => n[0] === a).map((n) => n[1])];
export const topla = (f) => AD.reduce((t, a) => t + f(a), 0);
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([16, 8, 14, 12, 12, 11]);
  console.log(`model: ${SIR.length} sir, ${AD.length} uygulama, 1 depo (kurgu uretim ortami)\n`);
  console.log(yz(["uygulama", "kural", "erisebildigi", "30 g okur", "90 g okur", "fazladan"]));
  for (const a of AD) {
    const e = SIR.filter((s) => erisir(a, s)).length;
    console.log(yz([a, UYG[a].kural.length, e, UYG[a].okur.length, okur90(a).length,
      e - okur90(a).length]));
  }
  const E = topla((a) => SIR.filter((s) => erisir(a, s)).length);
  const O30 = topla((a) => UYG[a].okur.length), O90 = topla((a) => okur90(a).length);
  console.log(yz(["toplam", topla((a) => UYG[a].kural.length), E, O30, O90, E - O90]));

  const ters = SIR.map((s) => [s, AD.filter((a) => erisir(a, s)).length,
    AD.filter((a) => okur90(a).includes(s)).length]).sort((x, y) => y[1] - x[1]);
  console.log("\nen genis dort sir (kac uygulama erisebiliyor / kaci gercekten okuyor):");
  for (const [s, e, o] of ters.slice(0, 4)) console.log(`  ${s.padEnd(24)} ${e} / ${o}`);
  const hic = ters.filter((t) => t[2] === 0), pay = ters.filter((t) => t[2] > 1);
  console.log(`hicbir uygulamanin okumadigi sir: ${hic.length} (${hic.map((t) => t[0]).join(", ")})`);
  console.log(`birden cok uygulamanin okudugu sir: ${pay.length} / ${SIR.length}; ` +
    `bu sirlarin biri degistiginde ortalama ` +
    `${(pay.reduce((t, x) => t + x[2], 0) / pay.length).toFixed(1)} uygulama etkilenir`);
  console.log(`\nele gecen bir uygulamadan acilan sir — politikayla ortalama ` +
    `${(E / AD.length).toFixed(1)}, en genis ${Math.max(...AD.map((a) =>
      SIR.filter((s) => erisir(a, s)).length))}; en az yetkiyle ortalama ` +
    `${(O90 / AD.length).toFixed(1)}, en genis ${Math.max(...AD.map((a) => okur90(a).length))}`);
  console.log(`en az yetki politikasi: ${O90} satir (bugun ${topla((a) => UYG[a].kural.length)}), ` +
    `kapanan kalem ${E - O90}; 30 gunluk gozlemle yazilsa ${O90 - O30} mesru okuma kesilirdi`);
}
model: 20 sir, 9 uygulama, 1 depo (kurgu uretim ortami)

uygulama           kural  erisebildigi   30 g okur   90 g okur   fazladan
portal-onyuz           2             4           1           1          3
portal-api             3            12           5           6          6
abone-kayit            2            10           3           3          7
fatura-servisi         3            11           4           5          6
odeme-koprusu          1             5           1           1          4
saha-api               4            12           4           4          8
is-emri                2             8           3           4          4
bildirim               2             8           3           3          5
rapor-uretici          2             9           3           4          5
toplam                21            79          27          31         48

en genis dort sir (kac uygulama erisebiliyor / kaci gercekten okuyor):
  veri/portal-birincil     6 / 2
  veri/portal-okuma        6 / 3
  veri/saha-birincil       6 / 2
  veri/fatura-birincil     6 / 1
hicbir uygulamanin okumadigi sir: 3 (dis/kimlik-saglayici, kuyruk/olcum-alim, altyapi/olcut-yazma)
birden cok uygulamanin okudugu sir: 12 / 20; bu sirlarin biri degistiginde ortalama 2.2 uygulama etkilenir

ele gecen bir uygulamadan acilan sir — politikayla ortalama 8.8, en genis 12; en az yetkiyle ortalama 3.4, en genis 6
en az yetki politikasi: 31 satir (bugun 21), kapanan kalem 48; 30 gunluk gozlemle yazilsa 4 mesru okuma kesilirdi

Yirmi bir kural satırı yetmiş dokuz (uygulama, sır) kalemi açıyor. Doksan günlük okuma kaydında görünen kalem otuz bir. Aradaki kırk sekiz kalem, yani açılan erişimin yüzde altmış biri, hiçbir uygulamanın hiç dokunmadığı sırlara verilmiş durumda. Bu fark bir tembellikten değil, kural biçiminden geliyor: veri/ yazmak bir satırdır, beş sır verir; beş sırrın hangisinin gerçekten gerektiğini yazmak beş satırdır.

Satır satır bakıldığında en pahalı iki kalem saha uygulaması tarafındadır. saha-api dört kural satırıyla on iki sırra erişebiliyor, dördünü okuyor; sekiz kalem karşılıksız. portal-api on iki sırra erişip altısını okuyor. Karşılıksız kalemin en büyük tek kaynağı veri/ önekidir: beş veri sırrının her birine altı uygulama erişebiliyor, ama en çok okunanı üç uygulama, en az okunanı tek uygulama okuyor. Fatura veri tabanının birincil kimlik bilgisine altı uygulama ulaşabiliyor; onu okuyan tek uygulama var.

Üç sır listede hiç görünmüyor: kimlik sağlayıcı sırrı, ölçüm alım kuyruğunun anahtarı ve ölçüt yazma anahtarı doksan gün boyunca hiçbir uygulama tarafından okunmamış. Bunlar erişim matrisinin en ucuz kalemleridir — okuyanı olmayan sır, kimseyi kesmeden kapatılır.

Bir sonraki satır matrisi ters yönde okuyor ve bu dersin dışına taşan tek sayıyı veriyor: yirmi sırrın on ikisi birden çok uygulama tarafından okunuyor, ortalama 2,2 uygulama tarafından. Erişim matrisi daraltılsa bile bu paylaşım kalır — çünkü paylaşım politikadan değil, mimariden gelir; iki uygulama aynı veri tabanına yazıyorsa aynı kimlik bilgisini okur. Bu on iki sırrın herhangi biri değiştirildiğinde ortalama iki uygulama aynı anda yeni değere geçmek zorundadır, ve o geçişin nasıl yapılacağı erişim denetiminin çözebileceği bir soru değildir.

Son iki satır kararı veriyor. Ele geçen bir uygulama bugünkü politikayla ortalama 8,8 sır açıyor, en kötü durumda on iki. En az yetkiye inildiğinde ortalama 3,4’e, en kötü durum altıya iniyor. Bedel de aynı satırda: politika yirmi bir satırdan otuz bir satıra çıkıyor. Daraltma politikayı kısaltmaz, uzatır. Ve daraltma otuz günlük gözlemle yazılırsa dört meşru okumayı keser — yıl sonu arşiv okuması, toplu rota yeniden hesabı, tanı kipindeki günlük yazımı ve aylık özet gönderimi. Bu dördü otuz günlük pencerede hiç görünmez; kesildiklerinde de dağıtım anında değil, ilk çalıştıkları gün fark edilirler.

Merkezîleşmenin Tek Noktası

// kesinti.mjs — merkezilesmenin tek nokta bedeli: depo dustugunde kim durur, kim baslayamaz
import { AD, UYG, topla, gen } from "./depo.mjs";

const yz = gen([14, 14, 17, 16, 20]);
const YB = topla((a) => UYG[a].yb);                       // gunluk yeniden baslatma (kurgu)
const derhal = AD.filter((a) => UYG[a].bicim === "her-istekte");
const biten = (D) => AD.filter((a) => UYG[a].bicim === "onbellekli" && UYG[a].omur < D);
console.log(`gunluk yeniden baslatma ${YB} (dagitim + olcek); depo olmadan baslayabilen ` +
  `uygulama 0 / ${AD.length}\n`);
console.log(yz(["kesinti(dk)", "derhal duran", "onbellegi biten", "duran uygulama",
  "basarisiz baslatma"]));
for (const D of [1, 15, 30, 60, 120, 240, 480, 1440])
  console.log(yz([D, derhal.length, biten(D).length, derhal.length + biten(D).length,
    Math.round((D / 1440) * YB)]));

console.log(`\nbicim dagilimi:`);
for (const b of ["her-istekte", "onbellekli", "baslangicta"]) {
  const l = AD.filter((a) => UYG[a].bicim === b);
  console.log(`  ${b.padEnd(13)} ${l.length}  ${l.join(", ")}`);
}
const ayakta = AD.filter((a) => UYG[a].bicim === "baslangicta");
console.log(`\n1440 dk kesintide: ${derhal.length + biten(1440).length} uygulama durur, ` +
  `${ayakta.length} uygulama calismaya devam eder ama ${YB} baslatma denemesi basarisiz olur`);
console.log(`kesintiden hic etkilenmeyen uygulama: 0 / ${AD.length}`);
gunluk yeniden baslatma 41 (dagitim + olcek); depo olmadan baslayabilen uygulama 0 / 9

kesinti(dk)     derhal duran  onbellegi biten  duran uygulama  basarisiz baslatma
1                          1                0               1                   0
15                         1                0               1                   0
30                         1                1               2                   1
60                         1                1               2                   2
120                        1                3               4                   3
240                        1                3               4                   7
480                        1                4               5                  14
1440                       1                4               5                  41

bicim dagilimi:
  her-istekte   1  odeme-koprusu
  onbellekli    4  portal-api, fatura-servisi, saha-api, bildirim
  baslangicta   4  portal-onyuz, abone-kayit, is-emri, rapor-uretici

1440 dk kesintide: 5 uygulama durur, 4 uygulama calismaya devam eder ama 41 baslatma denemesi basarisiz olur
kesintiden hic etkilenmeyen uygulama: 0 / 9

Kırk sekiz kalemi kapatmanın karşılığında ne alındığı bu tablodadır. Bir yerde toplanan sır, bir yerde toplanan bağımlılıktır. Deponun bir dakikalık kesintisinde bile bir uygulama duruyor: ödeme köprüsü sırrı her istekte okuyor, dolayısıyla depoya erişemediği anda ödeme almıyor. Bu, en duyarlı sırrın en sıkı okunmasının doğal sonucudur — sıkı okuma, kesintiye en açık olma biçimidir.

Sonraki satırlar önbellek ömrünün gecikmeli bir tampon olduğunu gösteriyor. Otuz dakikalık kesintide bildirim servisi düşüyor (önbellek ömrü on beş dakika), iki saatte portal ve saha uygulama arayüzleri de düşüyor, sekiz saatte önbellekli dört uygulamanın dördü duruyor. Önbellek kesintiyi engellemiyor, erteliyor; ertelediği süre tam olarak önbellek ömrü kadar.

Sağdaki sütun tablonun asıl bulgusudur. Başlangıçta okuyan dört uygulama kesinti boyunca çalışmaya devam ediyor ve ilk bakışta bağışık görünüyorlar. Bağışık değiller: dokuz uygulamanın hiçbiri depo olmadan başlayamıyor ve bu ortamda günde kırk bir yeniden başlatma var — dağıtım, ölçek büyütme ve sağlıksız örneğin değiştirilmesi. Dört saatlik bir kesinti yedi başlatma denemesini, bir günlük kesinti kırk birini düşürür. Yük artışıyla aynı saate denk gelen bir depo kesintisinde ölçek büyütme çalışmaz; sistem, ayakta kalan örnekleriyle yükün altında kalır.

Tablonun son satırı merkezîleşmenin gerçek ifadesidir: kesintiden hiç etkilenmeyen uygulama sıfırdır. Depoyu kurmak kırk sekiz karşılıksız erişim kalemini kapatılabilir hâle getirir; aynı adım, dokuz uygulamanın tamamına ortak bir başlatma bağımlılığı yazar. İkinci kalem birincinin faturasıdır ve çoğaltmayla küçültülebilir, sıfırlanamaz.

Daha Ucuz Aşama

Kırk sekiz karşılıksız kalem çalışma zamanında ölçüldü, ama çalışma zamanında doğmadı. Her kalem, bir uygulamaya politika yazılırken doğdu: veri/ öneki, o uygulamanın hangi veri sırrına ihtiyaç duyduğu bilinmediği için yazıldı. Aynı kalem dağıtım aşamasında kapanabilirdi — her uygulama ihtiyaç duyduğu sır yollarını dağıtım tanımında açıkça bildirseydi, politika o bildirimden üretilir ve otuz bir kalem dışında hiçbir kalem hiç açılmazdı. İşin ölçüsü de farklı: dokuz uygulama için dokuz bildirim yazmak ile yetmiş dokuz kalemlik matrisi elle gözden geçirip hangisinin gereksiz olduğuna karar vermek arasında yaklaşık dokuz kat fark var — ve ikincisi her yeni sır eklendiğinde yeniden yapılır, birincisi bir kez yazılır.

Çalışma zamanında ölçülmesi gereken tek kalem, bildirimin kendisinin doğru olup olmadığıdır: okuma kaydı bildirilenden fazlasını gösteriyorsa bildirim eksiktir, azını gösteriyorsa fazladır. Bu karşılaştırma bir denetimdir, bir savunma değil.

Özet

  • Yirmi bir kural satırı dokuz uygulamaya 79 (uygulama, sır) kalemi açıyor; doksan günlük okuma kaydı 31 diyor. Kırk sekiz kalem, açılan erişimin %61’i, hiç kullanılmıyor.
  • Karşılıksız kalemin kaynağı yol öneki kuralıdır: veri/ bir satırdır ve beş sır verir; beş veri sırrının her birine altı uygulama erişebiliyor, en çok okunanını üç uygulama okuyor.
  • Üç sırrı hiçbir uygulama okumuyor; bunlar kimseyi kesmeden kapatılabilecek en ucuz kalemlerdir.
  • En az yetki ele geçen bir uygulamadan açılan sırrı ortalama 8,8’den 3,4’e, en kötü durumda 12’den 6’ya indiriyor. Bedeli politikanın 21 satırdan 31 satıra uzamasıdır; otuz günlük gözlemle yazılırsa dört meşru okumayı keser ve kesinti ancak o iş ilk çalıştığında görünür.
  • Merkezîleşmenin bedeli tek noktadır: bir dakikalık kesinti bir uygulamayı durduruyor, sekiz saatlik kesinti beşini; dokuz uygulamanın hiçbiri depo olmadan başlayamıyor ve günde 41 başlatma denemesi bu noktadan geçiyor.
  • Kırk sekiz kalem çalışma zamanında ölçüldü ama dağıtım aşamasında doğdu; sır yolları dağıtım tanımında bildirilseydi hiç açılmayacaktı — dokuz bildirim ile 79 kalemlik matris incelemesi arasında yaklaşık dokuz kat fark var.

Sonraki Adım

Bu ders erişimi daralttı ama sırların kendisine hiç dokunmadı. Otuz bir kalemin her birinde duran şey hâlâ ömrü olmayan bir değerdir: kurulum günü yazılmış, o gün bu gündür aynı. Erişim matrisi daraltıldığında bir uygulamadan açılan sır altıya iner, ama o altı sır sızdığında ne kadar süre çalışacağı sorusu hiç sorulmadı. Sonraki ders o süreyi ölçer: statik bir sır sızdığında açık pencere kaç gün sürüyor, istek üzerine üretilen kısa ömürlü bir kimlik bilgisi aynı pencereyi kaç kata indiriyor ve bu daralmanın karşılığında depoya günde kaç ek istek, sisteme kaç yeni bağımlılık ekleniyor.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat