---
title: 'Yönetilen Anahtar–Değer Servisi'
source: 'https://academia.sh/tr/kurslar/bulut-depolama/yonetilen-anahtar-deger-servisi'
course: 'Bulutta Depolama ve Veri'
language: tr
updated: '2026-08-17T18:06:56+00:00'
license: 'CC BY-SA 4.0'
---

# Yönetilen Anahtar–Değer Servisi

Bölüm anahtarı seçiminin üç aday üzerinde gerçek anahtar dağılımıyla ölçülmesi: her adayda bölüm başına düşen istek, en dolu bölümün payı ve anahtarla desteklenmeyen erişim örüntüsünün karşılanamayan sorgu olarak sayılması, ayrılmış kapasite ile istek başına modelin aynı yük profilinde karşılaştırılıp sıcak bölümün zorladığı aşırı ayırmanın hesaplanması ve bölüm anahtarını değiştirmenin süre ve kurgu birim olarak bedelinin çıkarılması.

Önceki iki derste elde kalan kararların hemen hepsi ayardı: yapışkan pencere değiştirilebilir,
kopya kapatılabilir. Yönetilen anahtar–değer servisinde tablo değişir. Veri, **bölüm anahtarı**
denen alanın değerine göre yerleşir ve o anahtar seçildikten sonra hangi sorguların
karşılanabileceği sabitlenir.

Bölümlemenin mekaniği — aralığa göre mi karmaya göre mi bölündüğü, yeniden dengelemenin taşıdığı
veri — İleri Veri Ölçekleme kursunda ölçüldü ve burada tekrarlanmaz. Bu dersin ölçtüğü iki şey
bulut bağlamına özgüdür: anahtarın **kapasite modeline** ne yaptığı ve anahtarı değiştirmenin
**geri alınamazlığı**.

## Karşılanamayan Sorgu

Bir sorgu bölüm anahtarını eşitlikle sabitliyorsa istek doğrudan ilgili bölüme gider;
sabitlemiyorsa servis nereye bakacağını bilemez ve tek yol tablonun tamamını taramaktır. Bu
ölçekte tarama bir sorgu değil bir toplu işlemdir; böyle bir erişim örüntüsü **karşılanamayan
sorgu** sayılır ve aşağıda ayrı bir sütun olarak durur.

İkinci ölçü, karşılanabilen isteklerin bölümlere nasıl dağıldığıdır: on altı bölüme yayılan bir
yükte bölüm başına düşen istek ile en dolu bölümün aldığı istek arasındaki fark, **sıcak bölümün**
kendisidir.

## Düzenek

**YV13 — kurgu ölçüm ağında 40.000 sayaç, 12 bölge ve 26.000 abone vardır; her sayaç 15 dakikada
bir okuma yazar (günde 96) ve saklama 90 gündür: 345,6M öğe, öğe başına 180 bayt, 62,2 GB.**
Bölge payları 27'den 1'e iner; merkez bölge sayaçların yaklaşık dörtte birini taşır. **YV14 —
erişim karışımı: bir sayacın son 24 saati yüzde 38, tek okuma kaydı yüzde 22, bir bölgenin günlük
toplamı yüzde 17, bir abonenin son okumaları yüzde 10, günün eşik aşan okumaları yüzde 8, son bir
saatin tüm okumaları yüzde 5.** **YV15 — servis veriyi 16 bölüme yayar; ayrılmış kapasitede toplam
birim bölümlere eşit bölünür ve bir bölüm kendi payını aşamaz.** **YV16 — istek hızı ortalama
1.200/sn, günlük profil 24 saatlik kurgu bir çarpan dizisidir.** **YV17 — kurgu fiyat: ayrılmış
kapasite 0,12 birim/kapasite-saat, istek başına 0,25 birim/1.000 istek, yazma birimi okumanın 5
katı.** **YV18 — anahtar değiştirme işi 12.000 öğe/sn koşar.** YV14 belirleyicidir; ağırlıklar
değişirse karşılanamayan istek payı aynı yönde değişir.

```js
// yv/model.mjs — yonetilen anahtar-deger servisi MODELI: kurgu bolgesel olcum aginin sayac
// okumalari uzerinde bolum anahtari adaylari kosturulur. Bolumleme MEKANIGI (aralik mi karma mi,
// yeniden dengeleme) M17/K05'te olculdu, burada tekrarlanmaz; olculen sey anahtarin DEGER
// DAGILIMI ile erisim orunttusune uygunlugudur. Uretec kendi yazilmistir, tohum gorunurdur.
export const BOLGE = [["merkez", 27], ["kuzey", 14], ["liman", 11], ["sanayi", 9], ["bati", 8],
  ["dogu", 7], ["yayla", 6], ["kiyi", 5], ["ova", 5], ["baraj", 4], ["tepe", 3], ["ada", 1]];
export const SAYAC = 40000, ABONE = 26000, DILIM = 96, SAKLAMA = 90, BOLUM = 16;
export const OGE = SAYAC * DILIM * SAKLAMA, OGE_BAYT = 180;
export const BUGUN = SAKLAMA - 1;

// Sayac kutugu cagirandadir: sayac_id verilince bolgesi, abone verilince sayaclari bilinir.
export function kutuk(tohum = 20260803) {
  let s = tohum % 2147483647;
  const rast = () => (s = (s * 48271) % 2147483647) / 2147483647;
  const toplam = BOLGE.reduce((t, [, w]) => t + w, 0);
  const bolgesi = new Int32Array(SAYAC), abonesi = new Int32Array(SAYAC);
  const bolgeSayac = new Array(BOLGE.length).fill(0), aboneninSayaclari = new Map();
  for (let i = 0; i < SAYAC; i += 1) {
    let x = rast() * toplam, b = 0;
    for (let j = 0; j < BOLGE.length; j += 1) { if (x < BOLGE[j][1]) { b = j; break; } x -= BOLGE[j][1]; }
    bolgesi[i] = b; bolgeSayac[b] += 1;
    const a = Math.floor(rast() * ABONE);
    abonesi[i] = a;
    if (!aboneninSayaclari.has(a)) aboneninSayaclari.set(a, []);
    aboneninSayaclari.get(a).push(i);
  }
  return { rast, bolgesi, abonesi, bolgeSayac, aboneninSayaclari };
}

// Erisim orunttusu, sorguyu kurarken SABITLEYEBILDIGI alanlarla tanimlidir (YV14 sirasiyla);
// bolum anahtari o alanlar arasinda degilse sorgu karsilanamaz.
export const ERISIM = [38, 17, 22, 8, 10, 5];

export function istekUret(k, adet = 300000) {
  const agirlik = ERISIM, toplam = agirlik.reduce((a, b) => a + b, 0);
  const istek = [];
  for (let i = 0; i < adet; i += 1) {
    let x = k.rast() * toplam, tur = 0;
    for (let j = 0; j < agirlik.length; j += 1) { if (x < agirlik[j]) { tur = j; break; } x -= agirlik[j]; }
    const sayac = Math.floor(k.rast() * SAYAC);
    const abone = k.abonesi[Math.floor(k.rast() * SAYAC)];
    const eski = Math.floor(k.rast() * SAKLAMA);       // E2 ve E3 gecmise de bakar
    const gun = tur === 0 ? BUGUN                      // E1 "son 24 saat" hep bugundur
      : tur === 3 ? (k.rast() < 0.7 ? BUGUN : BUGUN - Math.floor(k.rast() * 7)) : eski;
    istek.push({ tur, sayac, bolge: k.bolgesi[sayac], abone, gun });
  }
  return istek;
}

// Istek hangi bolum anahtari DEGERLERINE dokunuyor; null = anahtar sabitlenemiyor, yani
// KARSILANAMAYAN sorgu (tum tablo taranir).
export function anahtarlar(q, aday, k) {
  const sayaclar = () => k.aboneninSayaclari.get(q.abone) ?? [q.sayac];
  if (aday === "bolge") {
    if (q.tur === 3 || q.tur === 5) return null;
    if (q.tur === 4) return [...new Set(sayaclar().map((i) => k.bolgesi[i]))].map((b) => "b" + b);
    return ["b" + q.bolge];
  }
  if (aday === "gun") {
    if (q.tur === 0) return ["g" + q.gun, "g" + Math.max(0, q.gun - 1)];
    return ["g" + (q.tur === 4 || q.tur === 5 ? BUGUN : q.gun)];
  }
  if (q.tur === 1 || q.tur === 3 || q.tur === 5) return null;   // sayac_id sabitlenemiyor
  return q.tur === 4 ? sayaclar().map((i) => "s" + i) : ["s" + q.sayac];
}

export const karma = (m) => { let h = 2166136261;
  for (const c of m) h = Math.imul(h ^ c.charCodeAt(0), 16777619); return (h >>> 0) % BOLUM; };
```

```js
// yv/olc.mjs — uc bolum anahtari adayi, sicak bolum, karsilanamayan sorgu ve kapasite modeli
import { kutuk, istekUret, anahtarlar, karma, ERISIM, BOLGE, SAYAC, ABONE,
  DILIM, SAKLAMA, BOLUM, OGE, OGE_BAYT } from "./model.mjs";

const s = (x, n) => String(x).padStart(n);
const yz = (a, b) => "%" + (100 * a / b).toFixed(2);
const k = kutuk();
const istek = istekUret(k);
const ADAY = [["bolge | zaman", "bolge", BOLGE.length], ["gun | sayac_id#zaman", "gun", SAKLAMA],
  ["sayac_id | zaman", "sayac_id", SAYAC]];
console.log(`${SAYAC} sayac, ${BOLGE.length} bolge, ${ABONE} abone, ${DILIM} okuma/gun, ` +
  `${SAKLAMA} gun saklama -> ${(OGE / 1e6).toFixed(1)}M oge, ${(OGE * OGE_BAYT / 1e9).toFixed(1)} GB.`);
console.log(`${istek.length} istek uzerinde olculdu. Tohum 20260803.\n`);

const sonuc = new Map();
console.log("bolum anahtari       | farkli deger | karsilanamayan orunttu | karsilanamayan istek | bolum basina istek (ort / en dolu) | sicak bolum");
console.log("---------------------|--------------|------------------------|----------------------|-----------------------------------|------------");
for (const [ad, aday, farkli] of ADAY) {
  const yuk = new Array(BOLUM).fill(0);
  let bos = 0;
  const orunttu = new Set();
  for (const q of istek) {
    const a = anahtarlar(q, aday, k);
    if (a === null) { bos += 1; orunttu.add(q.tur); continue; }
    for (const deger of a) yuk[karma(deger)] += 1;      // her deger ayri bir bolum istegidir
  }
  const toplam = yuk.reduce((a, b) => a + b, 0), enDolu = Math.max(...yuk);
  sonuc.set(aday, { sicak: enDolu / toplam, bos });
  console.log(`${ad.padEnd(20)} | ${s(farkli, 12)} | ${s(orunttu.size + " / " + ERISIM.length, 22)} | ` +
    `${s(bos + " (" + yz(bos, istek.length) + ")", 20)} | ` +
    `${s(Math.round(toplam / BOLUM) + " / " + enDolu, 33)} | ${s(yz(enDolu, toplam), 11)}`);
}
console.log(`ideal sicak bolum payi ${BOLUM} bolum icin %${(100 / BOLUM).toFixed(2)}; ` +
  `bolum basina istek karsilanabilen isteklerin dokundugu bolum sayisi uzerinden sayildi.`);

// Kapasite modeli. Ayrilmis kapasitede toplam birim BOLUM parcaya esit bolunur; bir bolum kendi
// payini asamaz, dolayisiyla sicak bolum toplam ayirmayi yukari zorlar.
const TABAN = 1200, FIYAT_AYRILMIS = 0.12, FIYAT_ISTEK = 0.25;
const PROFIL = [0.22, 0.18, 0.16, 0.16, 0.20, 0.35, 0.70, 1.20, 1.75, 2.10, 2.20, 2.05,
  1.80, 1.70, 1.80, 2.00, 2.30, 2.55, 2.45, 1.90, 1.30, 0.85, 0.50, 0.32];
const ort = PROFIL.reduce((a, b) => a + b, 0) / 24;
const hiz = PROFIL.map((p) => TABAN * p / ort);
const gunlukIstek = hiz.reduce((a, b) => a + b, 0) * 3600;
const tepe = Math.max(...hiz);
console.log(`\nyuk profili: ortalama ${TABAN} istek/sn, tepe ${tepe.toFixed(0)} istek/sn ` +
  `(${(tepe / TABAN).toFixed(2)} kat), gunluk ${(gunlukIstek / 1e6).toFixed(1)}M istek.`);
console.log(`kurgu fiyat: ayrilmis kapasite ${FIYAT_AYRILMIS} birim/kapasite-saat, istek basina ` +
  `${FIYAT_ISTEK} birim/1000 istek.`);
console.log("bolum anahtari       | asiri ayirma | ayrilmis (birim/gun) | istek basina | tepeye ayirmada kisilan istek");
console.log("---------------------|--------------|----------------------|--------------|------------------------------");
for (const [ad, aday] of ADAY) {
  const h = sonuc.get(aday).sicak;
  const ayrilmis = BOLUM * h * tepe * 24 * FIYAT_AYRILMIS;   // kisilmasiz ayirma = BOLUM * h * tepe
  const tavan = tepe / BOLUM;                       // yalniz toplami karsilayan ayirma: C = tepe
  const kisilan = hiz.reduce((t, r) => t + Math.max(0, h * r - tavan) * 3600, 0);
  console.log(`${ad.padEnd(20)} | ${s((BOLUM * h).toFixed(2) + " kat", 12)} | ${s(ayrilmis.toFixed(0), 20)} | ` +
    `${s((gunlukIstek / 1000 * FIYAT_ISTEK).toFixed(0), 12)} | ${s((kisilan / 1e6).toFixed(1) + "M", 29)}`);
}

// Geri alinamayan kalem: bolum anahtarini degistirmek veriyi yeniden yazmaktir.
const AKTARMA_HIZ = 12000, YAZMA_KAT = 5;
const esdeger = OGE * (1 + YAZMA_KAT), sure = OGE / AKTARMA_HIZ / 3600;
const bedel = esdeger / 1000 * FIYAT_ISTEK, gunluk = gunlukIstek / 1000 * FIYAT_ISTEK;
const cikis = OGE * OGE_BAYT / 1e9;
console.log(`\nanahtari degistirmek: ${(OGE / 1e6).toFixed(1)}M oge okunup yeni anahtarla yeniden ` +
  `yazilir (yazma birimi okumanin ${YAZMA_KAT} kati) -> esdeger istek ${(esdeger / 1e9).toFixed(2)}G.`);
console.log(`bedel ${(bedel / 1000).toFixed(1)} bin kurgu birim = gunluk isletimin ` +
  `(${gunluk.toFixed(0)} birim) ${(bedel / gunluk).toFixed(0)} kati; sure ${sure.toFixed(1)} sa ` +
  `(${AKTARMA_HIZ} oge/sn) ve o sure boyunca cift yazma penceresi.`);
console.log(`servisten cikis daha ucuz: ${cikis.toFixed(1)} GB disa aktarim, internet uzerinden ` +
  `9 birim/GB = ${(cikis * 9).toFixed(0)} kurgu birim. Farkli deger sayisi (bolge icin ` +
  `${BOLGE.length}) bolum sayisinin kosumdan bagimsiz ust siniridir.`);
```

```
40000 sayac, 12 bolge, 26000 abone, 96 okuma/gun, 90 gun saklama -> 345.6M oge, 62.2 GB.
300000 istek uzerinde olculdu. Tohum 20260803.

bolum anahtari       | farkli deger | karsilanamayan orunttu | karsilanamayan istek | bolum basina istek (ort / en dolu) | sicak bolum
---------------------|--------------|------------------------|----------------------|-----------------------------------|------------
bolge | zaman        |           12 |                  2 / 6 |       39168 (%13.06) |                     18545 / 78103 |      %26.32
gun | sayac_id#zaman |           90 |                  0 / 6 |            0 (%0.00) |                    25888 / 184840 |      %44.62
sayac_id | zaman     |        40000 |                  3 / 6 |       89856 (%29.95) |                     16010 / 16312 |       %6.37
ideal sicak bolum payi 16 bolum icin %6.25; bolum basina istek karsilanabilen isteklerin dokundugu bolum sayisi uzerinden sayildi.

yuk profili: ortalama 1200 istek/sn, tepe 2389 istek/sn (1.99 kat), gunluk 103.7M istek.
kurgu fiyat: ayrilmis kapasite 0.12 birim/kapasite-saat, istek basina 0.25 birim/1000 istek.
bolum anahtari       | asiri ayirma | ayrilmis (birim/gun) | istek basina | tepeye ayirmada kisilan istek
---------------------|--------------|----------------------|--------------|------------------------------
bolge | zaman        |     4.21 kat |                28978 |        25920 |                         16.8M
gun | sayac_id#zaman |     7.14 kat |                49127 |        25920 |                         34.7M
sayac_id | zaman     |     1.02 kat |                 7010 |        25920 |                          0.0M

anahtari degistirmek: 345.6M oge okunup yeni anahtarla yeniden yazilir (yazma birimi okumanin 5 kati) -> esdeger istek 2.07G.
bedel 518.4 bin kurgu birim = gunluk isletimin (25920 birim) 20 kati; sure 8.0 sa (12000 oge/sn) ve o sure boyunca cift yazma penceresi.
servisten cikis daha ucuz: 62.2 GB disa aktarim, internet uzerinden 9 birim/GB = 560 kurgu birim. Farkli deger sayisi (bolge icin 12) bolum sayisinin kosumdan bagimsiz ust siniridir.
```

## Üç Aday, Üç Farklı Başarısızlık

Hiçbir aday üstün çıkmıyor; her biri başka bir sütunda batıyor.

**`bolge` işletme düzenine uyuyor ve sıcak bölüm üretiyor.** Bölüm başına ortalama 18.545 istek
düşerken en dolu bölüm 78.103 alıyor: yüzde 26,32, ideal olan yüzde 6,25'in dört katı. Sebep, on
iki farklı değerden birinin sayaçların dörtte birini taşımasıdır; bölüm eklemek bunu düzeltmez,
çünkü bir anahtar değeri bölünemez.

**`gun` her sorguyu karşılıyor ve en kötü sıcak bölümü üretiyor.** Karşılanamayan örüntü sıfır —
tabloda tek sıfır bu. Karşılığında bugünün bölümü 184.840 istek alıyor, ortalamanın yedi katı,
isteklerin yüzde 44,62'si: artan bir anahtarda yeni yazma ve okumaların çoğu tek değere yığılır.

**`sayac_id` kusursuz dengeleniyor ve isteklerin üçte birini karşılayamıyor.** Ortalama 16.010,
en dolu bölüm 16.312 — sıcak bölüm yüzde 6,37, ideale yüzde 2 uzaklıkta. Buna karşılık altı
örüntünün üçü, bölge toplamı, eşik taraması ve son bir saatin okumaları, anahtarı hiç
sabitlemiyor: isteklerin yüzde 29,95'i, 89.856 istek. Bunlar yavaş çalışmıyor; **hiç çalışmıyor**.

## Sıcak Bölüm Faturaya Kapasite Modelinden Geçer

İkinci tablo sıcak bölümü paraya çeviriyor. Ayrılan toplam birim bölümlere eşit bölünür (YV15) ve
bir bölüm kendi payını aşamaz; sıcak bölümün payı h ise kısılmamak için ayrılması gereken kapasite
16 × h × tepe'dir. İlk sütun bu katsayıyı veriyor: `sayac_id` için 1,02, `bolge` için 4,21, `gun`
için 7,14 kat. Sıcak bölümü olan bir anahtarda ayrılan kapasitenin altıda beşi hiç kullanılmaz;
**kapasitenin karşılığı işlem değil, dengesizliktir.**

Gündelik bedel bunun sonucudur. `sayac_id` ile ayrılmış kapasite 7.010 kurgu birim, istek başına
model 25.920 — ayrılmış model 3,7 kat ucuz. `bolge` ile ayrılmış 28.978'e çıkıp istek başına
modelin üstüne geçiyor, `gun` ile 49.127 oluyor. **Hangi kapasite modelinin ucuz olduğunu belirleyen
şey yük değil, bölüm anahtarıdır.** İstek başına model dengesizliğe duyarsızdır; ayrılmış model onu
katsayısıyla ücretlendirir.

Son sütun ayırmanın kısıldığı durumu gösteriyor: yalnız toplam tepeyi karşılayacak kadar (2.389
birim) ayrıldığında `sayac_id` hiç kısılmıyor, `bolge` günde 16,8M, `gun` 34,7M isteği kısıyor.
Toplam kapasite yeterlidir; kısılan tek bölümdür.

## Anahtarı Değiştirmenin Bedeli

Buraya kadar ölçülen her şey bir seçim gibi görünüyor; son blok neden öyle olmadığını sayıyor.
Bölüm anahtarını değiştirmek bir ayar değişikliği değildir: 345,6M öğenin tamamı okunur ve yeni
anahtarla yeniden yazılır. Yazma birimi okumanın beş katı olduğu için eşdeğer istek 2,07 milyar,
kurgu bedeli 518,4 bin birim — **günlük işletim bedelinin 20 katı.** Süre 8 saat ve o süre boyunca
uygulama iki tabloya birden yazar, çünkü aktarma sürerken gelen yazmaların da bir yere düşmesi
gerekir. İlişkisel taraftaki ana sürüm yükseltmesi de tek yönlüydü ama veri yerinde kalıyordu;
burada geri dönüş verinin kendisini yeniden yazmaktır. Servisten büsbütün çıkmak daha ucuzdur:
62,2 GB dışa aktarım ve 560 kurgu birim. **Anahtarı değiştirmek, servisi terk etmekten 900 kat
pahalıya geliyor**; bağlayıcı olan sağlayıcı değil, şemadır.

## Özet

- `bolge` anahtarında sıcak bölüm ideal payın dört katıdır (%26,32) ve on iki farklı değer bölüm
  sayısının üst sınırını çizer; bölüm eklemek dengeyi düzeltmez.
- `gun` altı erişim örüntüsünün altısını da karşılıyor ama bugünün bölümü 184.840 istek alıyor
  (%44,62); `sayac_id` 16.010'a karşı 16.312 ile kusursuz dengeleniyor ama altı örüntünün üçünü,
  isteklerin %29,95'ini karşılayamıyor.
- Sıcak bölüm ayrılmış kapasitede aşırı ayırmaya çevrilir: 1,02 / 4,21 / 7,14 kat. Hangi kapasite
  modelinin ucuz olduğunu yük değil, bölüm anahtarı belirliyor (7.010'a karşı 25.920 kurgu birim).
- Toplam tepeyi karşılayan bir ayırma bile sıcak anahtarda günde 16,8M ve 34,7M isteği kısar.
- Anahtarı değiştirmek 345,6M öğenin yeniden yazılmasıdır: 8 saat, 518,4 bin kurgu birim ve 8
  saatlik çift yazma penceresi — servisten büsbütün çıkmanın 900 katı.

## Sonraki Adım

Tablo bir eksik bırakıyor. En iyi dengeyi veren `sayac_id` anahtarında isteklerin yüzde 29,95'i
karşılanamıyor ve bunu düzeltmenin yolu anahtarı değiştirmek değil — o kapı 518,4 bin kurgu birimle
kapandı. Yönetilen anahtar–değer servisleri bu boşluk için **ikincil dizin** sunar: aynı veriyi
başka bir anahtara göre ikinci kez yerleştirir. Sonraki ders ikincil dizinin karşılanamayan üç
örüntünün kaçını kurtardığını ve karşılığında ne aldığını sayar — ek yazma, ek saklama, geri kalma
süresi — ve **değişim akışını** bir tüketiciyle modelleyip olay sırasını, yeniden işlemeyi ve
akışın saklama süresi dolduğunda kaçırılan pencereyi ölçer.
