---
title: 'Nesne Depolama'
source: 'https://academia.sh/tr/kurslar/bulut-depolama/nesne-depolama'
course: 'Bulutta Depolama ve Veri'
language: tr
updated: '2026-08-17T18:06:56+00:00'
license: 'CC BY-SA 4.0'
---

# Nesne Depolama

Kova, nesne ve anahtar modelinin dosya sisteminden kalem kalem ayrılması: dizin yerine önek, yeniden adlandırma yerine kopyalama, kısmi güncellemenin olmaması ve listelemenin ücretli bir işlem olması; her farkın istek sayısına ve bayta çevrilmesi ve anahtar düzeninin geri alınamayan kalem olarak sayılması.

Önceki kurs makineyi ve ağı kiralayarak bitti: örnekler açıldı, alt ağlara yerleşti, filtreden geçti
ve dışarıya açıldı. Bir soru açıkta kaldı — bütün bu makinelerin üzerinde koşan şeyin **verisi**
nerede duruyor. Yerel disk cevabı değildir: örnek kapandığında disk de gider, ölçekleme grubunda
hangi örneğin hangi veriyi tuttuğu bilinmez. Kiralanan katmanda verinin kendi yeri vardır ve o yer
seçildiğinde bir dizi karar sağlayıcıya geçer.

Bu kursun ölçüsü budur: her ders **hangi kararın devredildiğini, hangisinin elde kaldığını**, elde
kalanların hangisinin **geri alınamadığını** ve verinin **çıkarken** ne tuttuğunu sayar. İlk tür en
yaygın varsayılandır: nesne deposu (object storage). Ucuz olduğu doğrudur ve bu bir karar taşımaz;
karar taşıyan şey, nesne deposunun bir dosya sistemi **olmamasıdır**.

## Kova, Nesne ve Anahtar

Üç kavram vardır. **Kova** (bucket) bir ad alanıdır; içinde **nesne** (object) durur; her nesneye
bir **anahtar** (key) ile erişilir. Anahtar bir yoldur ama yol değildir: `sayac/2026/03/14/A118.json`
düz bir dizedir, içindeki eğik çizgilerin depo için bir anlamı yoktur. Depo bu dizeyi bir sözlükte
arar. Eğik çizgiler yalnız **önek** (prefix) sorgusunda işe yarar: verilen dizeyle başlayan
anahtarlar listelenebilir. Dizin diye bir nesne yoktur, dolayısıyla boş dizin de yoktur, dizin
silme de yoktur, dizinin boyutu diye okunacak bir alan da yoktur.

Bu tek farkın dört sonucu vardır ve dördü de sayılabilir: dizin yerine önek, yeniden adlandırma
yerine kopyalama, kısmi güncelleme yerine tam yeniden yazma, ve ücretsiz sanılan listelemenin
ücretli bir işlem olması. Aşağıdaki model bunları kurgu ölçüm ağının nesne kümesi üzerinde sayar.

- **DT1** — Bölgesel ölçüm ağı kurgudur: 4.000 sayaç, 310 günlük geçmiş, dört nesne ailesi. Adetler
  ve ortalama boyutlar modelde yazılıdır.
- **DT2** — Ücretler kurgu **birim** cinsindendir, gerçek bir sağlayıcının fiyatı değildir; saklama,
  istek ve çıkış oranları modelde açık yazılıdır.
- **DT3** — Bir listeleme isteği en çok 1.000 anahtar döndürür; modelde bir isteğin gidiş dönüş
  süresi 45 ms'dir ve istekler tek akışta sıralıdır.
- **DT4** — Kopyalama sunucu tarafındadır: çıkış ücreti doğmaz, istek ücreti doğar.

```js
// nesne/olcum-agi.mjs — bolgesel olcum agi KURGUDUR: nesne kumesi de ucret de modeldir.
// Butun ucretler kurgu "birim" cinsindendir; gercek bir saglayicinin fiyati degildir.
export const SAYAC = 4000, GUN = 310;             // kurgu ag: 4000 sayac, 310 gunluk gecmis
export const AILE = [
  { ad: "sayac-okumalari", adet: SAYAC * GUN, ort: 2400, yazim: "gunluk" },
  { ad: "fatura-belgeleri", adet: 86_000, ort: 380 * 1024, yazim: "aylik" },
  { ad: "saha-fotograflari", adet: 42_000, ort: Math.round(3.6 * 1024 * 1024), yazim: "bir kez" },
  { ad: "is-emri-kayitlari", adet: 310_000, ort: 11 * 1024, yazim: "gunluk" },
];
export const UCRET = {                            // kurgu birim: B
  saklama: 0.023,                                 // B / GiB / ay
  yazmaIstek: 0.0050 / 1000,                      // B / istek (koyma, kopyalama, listeleme)
  okumaIstek: 0.0004 / 1000,                      // B / istek (getirme, basliga bakma)
  cikisInternet: 0.085,                           // B / GiB
  cikisBolgelerArasi: 0.020,                      // B / GiB
};
export const SAYFA = 1000;                        // bir listeleme istegi en cok 1000 anahtar doner
export const TUR_MS = 45;                         // modelde bir istegin gidis donus suresi

export const GIB = (bayt) => bayt / 1024 ** 3;
export const toplamBayt = AILE.reduce((a, f) => a + f.adet * f.ort, 0);
export const toplamAdet = AILE.reduce((a, f) => a + f.adet, 0);
export const listeIstegi = (anahtar) => Math.ceil(anahtar / SAYFA);
```

## Dosya Sistemiyle Kalem Kalem Fark

- **DT5** — Fatura belgelerinde ayda 4.300 düzeltme yapılır; her düzeltme belgeye 2 KiB ekler.
- **DT6** — Aralık isteği desteklenir: bir nesnenin yalnız istenen bayt aralığı okunabilir.

```js
// nesne/model-farki.mjs — dosya sistemi islemleri ile nesne deposu karsiliklari kalem kalem
import { AILE, UCRET, SAYFA, TUR_MS, GIB, toplamBayt, toplamAdet, listeIstegi } from "./olcum-agi.mjs";

const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
const s = (x, n) => String(x).padStart(n);
console.log(`kurgu kova: ${toplamAdet.toLocaleString("tr")} nesne, ${g(GIB(toplamBayt), 0, 1)} GiB, ` +
  `sayfa basina ${SAYFA} anahtar, modelde tur suresi ${TUR_MS} ms`);
console.log("\naile               |     adet |    GiB | liste istegi | liste suresi (sn)");
console.log("-------------------|----------|--------|--------------|------------------");
for (const f of AILE) {
  const li = listeIstegi(f.adet);
  console.log(`${f.ad.padEnd(18)} | ${s(f.adet, 8)} | ${g(GIB(f.adet * f.ort), 6, 1)} | ` +
    `${s(li, 12)} | ${g(li * TUR_MS / 1000, 17, 1)}`);
}

// Dort islem: dosya sisteminde tek cagri olan is, nesne deposunda kaca cikiyor.
const fatura = AILE[1], foto = AILE[2], sayac = AILE[0];
const DUZELTME = 4300, EK = 2 * 1024, ARALIK = 64 * 1024;
const ISLEM = [
  { ad: "dizin boyutunu ogren", fsCagri: 1, fsBayt: 0,
    noIstek: listeIstegi(sayac.adet), noBayt: 0 },
  { ad: "dizini yeniden adlandir", fsCagri: 1, fsBayt: 0,
    noIstek: listeIstegi(sayac.adet) + 2 * sayac.adet, noBayt: sayac.adet * sayac.ort },
  { ad: "dosyaya 2 KiB ekle", fsCagri: 1, fsBayt: EK,
    noIstek: 1, noBayt: fatura.ort },
  { ad: "aylik duzeltmeler", fsCagri: DUZELTME, fsBayt: DUZELTME * EK,
    noIstek: DUZELTME, noBayt: DUZELTME * fatura.ort },
  { ad: "64 KiB araligi oku", fsCagri: 1, fsBayt: ARALIK, noIstek: 1, noBayt: ARALIK },
  { ad: "tum fotografi oku", fsCagri: 1, fsBayt: foto.ort, noIstek: 1, noBayt: foto.ort },
];
console.log("\nislem                   | dosya sisteminde |    nesne deposunda | bayt buyutmesi");
console.log("                        | cagri /     bayt |   istek /      bayt |");
console.log("------------------------|------------------|--------------------|---------------");
for (const i of ISLEM) {
  const kat = i.fsBayt === 0 ? (i.noBayt === 0 ? "1x" : "olcusuz") : (i.noBayt / i.fsBayt).toFixed(1) + "x";
  console.log(`${i.ad.padEnd(23)} | ${s(i.fsCagri, 5)} / ${s(i.fsBayt, 8)} | ` +
    `${s(i.noIstek, 7)} / ${s(i.noBayt, 10)} | ${kat.padStart(14)}`);
}

const ad = ISLEM[1];
const istekUcret = ad.noIstek * UCRET.yazmaIstek;
console.log(`\nyeniden adlandirma: ${ad.noIstek.toLocaleString("tr")} istek = ${g(istekUcret, 0, 2)} birim ` +
  `(kurgu), tasinan ${g(GIB(ad.noBayt), 0, 2)} GiB; dosya sisteminde 1 cagri, 0 bayt.`);
const duz = ISLEM[3];
console.log(`aylik duzeltmeler: degisen ${g(duz.fsBayt / 1024 ** 2, 0, 1)} MiB, yazilan ` +
  `${g(GIB(duz.noBayt), 0, 2)} GiB; kismi guncelleme olmadigi icin fark ${(duz.noBayt / duz.fsBayt).toFixed(0)} kat.`);
console.log(`aralik okuma calisir: ${ARALIK / 1024} KiB istenince ${ARALIK / 1024} KiB cikiyor — ` +
  `kismi okuma var, kismi yazma yok.`);
```

```
kurgu kova: 1.678.000 nesne, 184.8 GiB, sayfa basina 1000 anahtar, modelde tur suresi 45 ms

aile               |     adet |    GiB | liste istegi | liste suresi (sn)
-------------------|----------|--------|--------------|------------------
sayac-okumalari    |  1240000 |    2.8 |         1240 |              55.8
fatura-belgeleri   |    86000 |   31.2 |           86 |               3.9
saha-fotograflari  |    42000 |  147.7 |           42 |               1.9
is-emri-kayitlari  |   310000 |    3.3 |          310 |              13.9

islem                   | dosya sisteminde |    nesne deposunda | bayt buyutmesi
                        | cagri /     bayt |   istek /      bayt |
------------------------|------------------|--------------------|---------------
dizin boyutunu ogren    |     1 /        0 |    1240 /          0 |             1x
dizini yeniden adlandir |     1 /        0 | 2481240 / 2976000000 |        olcusuz
dosyaya 2 KiB ekle      |     1 /     2048 |       1 /     389120 |         190.0x
aylik duzeltmeler       |  4300 /  8806400 |    4300 / 1673216000 |         190.0x
64 KiB araligi oku      |     1 /    65536 |       1 /      65536 |           1.0x
tum fotografi oku       |     1 /  3774874 |       1 /    3774874 |           1.0x

yeniden adlandirma: 2.481.240 istek = 12.41 birim (kurgu), tasinan 2.77 GiB; dosya sisteminde 1 cagri, 0 bayt.
aylik duzeltmeler: degisen 8.4 MiB, yazilan 1.56 GiB; kismi guncelleme olmadigi icin fark 190 kat.
aralik okuma calisir: 64 KiB istenince 64 KiB cikiyor — kismi okuma var, kismi yazma yok.
```

Tablo dört farkı birbirinden ayırıyor. Dizin boyutunu öğrenmek dosya sisteminde tek çağrıdır; nesne
deposunda 1.240 listeleme isteğidir ve modelde 55,8 saniye sürer — sıfır bayt aktarılarak. Sayaç
ailesi kovanın **baytının yüzde 1,5'ini** tutar ama listeleme isteklerinin çoğunu üretir: listeleme
bayta değil **anahtar sayısına** bağlıdır. Dizini yeniden adlandırmak dosya sisteminde tek çağrı ve
sıfır bayttır; nesne deposunda 2.481.240 istektir ve 2,77 GiB'i baştan sona taşır. Karşılığı yoktur,
katı yoktur — işlem türü değişmiştir.

Kısmi güncelleme farkı en sinsi olanıdır çünkü hata vermez, yalnız faturayı büyütür: 380 KiB'lik bir
belgeye 2 KiB eklemek belgenin tamamını yeniden yazar, 190 kat. Ayda 4.300 düzeltmede değişen 8,4
MiB, yazılan 1,56 GiB olur. Son iki satır dengeyi kuruyor: kısmi **okuma** vardır. 64 KiB'lik aralık
istendiğinde 64 KiB çıkar. Nesne deposu parça okumaya izin verir, parça yazmaya vermez; bu
asimetri, sık güncellenen küçük kayıtların nesne deposunda tutulmamasının tek cümlelik gerekçesidir.

## Anahtar Düzeni Geri Alınamayan Kalemdir

Dizin olmadığı için erişim örüntüsünü belirleyen tek şey anahtarın **kendisidir**. Aynı veri iki
düzende tutulabilir ve ikisi de doğrudur; fark, hangi sorgunun önekle daralabildiğidir.

```js
// nesne/anahtar-duzeni.mjs — ayni veri, iki anahtar duzeni: sorgular kac listeleme istegi istiyor
import { SAYAC, GUN, AILE, UCRET, TUR_MS, GIB, listeIstegi } from "./olcum-agi.mjs";

const OKUMA = AILE[0], TOPLAM = OKUMA.adet;
// Onek agaci: bir sorgu ancak onekle daralabiliyorsa az anahtar okur, daralamiyorsa tam tarar.
const DUZEN = {
  "tarih-onde": { kalip: "sayac/<yil>/<ay>/<gun>/<sayac>.json", gun: SAYAC, sayac: TOPLAM },
  "sayac-onde": { kalip: "sayac/<sayac>/<yil>/<ay>/<gun>.json", gun: TOPLAM, sayac: GUN },
};
const SORGU = [
  { ad: "bir gunun tum okumalari", alan: "gun", aylik: 30 },
  { ad: "bir sayacin tum gecmisi", alan: "sayac", aylik: 900 },
];
const g = (x, n, d = 2) => x.toFixed(d).padStart(d === 0 ? n : n);
const s = (x, n) => String(x).padStart(n);

console.log(`${TOPLAM.toLocaleString("tr")} okuma nesnesi = ${SAYAC} sayac x ${GUN} gun. ` +
  `Veri ayni, degisen yalniz anahtarin ilk alani.`);
for (const [ad, d] of Object.entries(DUZEN)) console.log(`  ${ad.padEnd(11)} ${d.kalip}`);

console.log("\nsorgu                    | duzen       | okunan anahtar | liste istegi | sure (sn)");
console.log("-------------------------|-------------|----------------|--------------|----------");
const maliyet = {};
for (const q of SORGU)
  for (const [ad, d] of Object.entries(DUZEN)) {
    const anahtar = d[q.alan], li = listeIstegi(anahtar);
    maliyet[ad] = (maliyet[ad] ?? 0) + q.aylik * li;
    console.log(`${q.ad.padEnd(24)} | ${ad.padEnd(11)} | ${s(anahtar, 14)} | ` +
      `${s(li, 12)} | ${g(li * TUR_MS / 1000, 8, 1)}`);
  }

console.log("\naylik toplam (30 gun sorgusu + 900 sayac sorgusu):");
for (const [ad, istek] of Object.entries(maliyet))
  console.log(`  ${ad.padEnd(11)} ${s(istek.toLocaleString("tr"), 11)} liste istegi = ` +
    `${(istek * UCRET.yazmaIstek).toFixed(2).padStart(7)} birim (kurgu)`);
const [a, b] = Object.values(maliyet);
console.log(`  fark ${(Math.max(a, b) / Math.min(a, b)).toFixed(0)} kat; ikisi de dogru, ikisi de ayni veriyi tutuyor.`);

// Duzeni sonradan degistirmek: dizin yeniden adlandirma yok, her nesne kopyalanip silinir.
const gecis = listeIstegi(TOPLAM) + 2 * TOPLAM, bayt = TOPLAM * OKUMA.ort;
console.log(`\nduzeni degistirmenin bedeli: ${listeIstegi(TOPLAM)} listeleme + ${TOPLAM.toLocaleString("tr")} kopyalama + ` +
  `${TOPLAM.toLocaleString("tr")} silme = ${gecis.toLocaleString("tr")} istek`);
console.log(`  istek ucreti ${(gecis * UCRET.yazmaIstek).toFixed(2)} birim, tasinan ${GIB(bayt).toFixed(2)} GiB, ` +
  `modelde tek akista ${(gecis * TUR_MS / 3600000).toFixed(1)} saat`);
console.log(`  ayni bayt bolge disina cikarilsaydi: bolgeler arasi ${(GIB(bayt) * UCRET.cikisBolgelerArasi).toFixed(3)} birim, ` +
  `internete ${(GIB(bayt) * UCRET.cikisInternet).toFixed(3)} birim`);
console.log(`  gecis ucreti ${(gecis * UCRET.yazmaIstek / (GIB(bayt) * UCRET.saklama)).toFixed(0)} aylik saklama ucretine esit.`);
```

```
1.240.000 okuma nesnesi = 4000 sayac x 310 gun. Veri ayni, degisen yalniz anahtarin ilk alani.
  tarih-onde  sayac/<yil>/<ay>/<gun>/<sayac>.json
  sayac-onde  sayac/<sayac>/<yil>/<ay>/<gun>.json

sorgu                    | duzen       | okunan anahtar | liste istegi | sure (sn)
-------------------------|-------------|----------------|--------------|----------
bir gunun tum okumalari  | tarih-onde  |           4000 |            4 |      0.2
bir gunun tum okumalari  | sayac-onde  |        1240000 |         1240 |     55.8
bir sayacin tum gecmisi  | tarih-onde  |        1240000 |         1240 |     55.8
bir sayacin tum gecmisi  | sayac-onde  |            310 |            1 |      0.0

aylik toplam (30 gun sorgusu + 900 sayac sorgusu):
  tarih-onde    1.116.120 liste istegi =    5.58 birim (kurgu)
  sayac-onde       38.100 liste istegi =    0.19 birim (kurgu)
  fark 29 kat; ikisi de dogru, ikisi de ayni veriyi tutuyor.

duzeni degistirmenin bedeli: 1240 listeleme + 1.240.000 kopyalama + 1.240.000 silme = 2.481.240 istek
  istek ucreti 12.41 birim, tasinan 2.77 GiB, modelde tek akista 31.0 saat
  ayni bayt bolge disina cikarilsaydi: bolgeler arasi 0.055 birim, internete 0.236 birim
  gecis ucreti 195 aylik saklama ucretine esit.
```

İki düzen aynı baytı tutuyor, aynı nesneleri barındırıyor, aynı saklama ücretini ödüyor. Fark
sorgudadır: tarih önde olduğunda bir günün okumaları 4 istekle gelir, bir sayacın geçmişi 1.240
istekle taranır; sayaç önde olduğunda tam tersi olur. Bu iş yükünde ayda 900 sayaç sorgusu ve 30
günlük sorgu vardır, dolayısıyla yanlış düzen aylık listeleme isteğini 29 katına çıkarır.

Asıl kalem son bloktadır. Düzeni değiştirmek bir yapılandırma işi değildir: 2.481.240 istek, 2,77
GiB'in yeniden yazılması ve modelde tek akışta 31 saattir. Geçişin istek ücreti, aynı verinin **195
aylık saklama ücretine** eşittir — on altı yıllık saklama parası bir kerelik yeniden adlandırmaya
gider. **Anahtar düzeni bu kursun ilk geri alınamayan kalemidir:** teknik olarak dönülebilir,
pratikte veri taşımadan dönülemez. Çıkış tarafı ayrıca durur: geçiş bölge içinde kalırsa çıkış
ücreti doğmaz, aynı baytı bölge dışına taşımak 0,055 birim, internete indirmek 0,236 birim tutar.
Verinin girmesi ucuz, çıkması pahalıdır.

## Devredilen Karar ve Elde Kalan

Nesne deposu kiralandığında disk yerleşimi, çoğaltma sayısı, bozulmuş bloğun onarımı, disk
değişimi ve dayanıklılık hedefi sağlayıcıya geçer. Bunlar geri alınmaz kararlar değildir, çünkü
zaten karar değildir: görünürlükleri yoktur, bir kadranı yoktur.

Elde kalanlar dörttür ve hepsi bu kursun ilerleyen derslerinde ölçülür: **anahtar düzeni** (bu
derste), **depolama sınıfı**, **sürümleme** ve **erişim kapsamı**. Dördünün ortak yanı, seçildikten
sonra veriyi taşımadan değiştirilememeleridir. Kova adı beşincisidir ve en serttir: ad alanı
paylaşımlıdır, ad sonradan değiştirilemez, değiştirmek yeni kova açıp her nesneyi kopyalamak
demektir — yukarıdaki 2.481.240 isteğin aynısı.

## Özet

- Nesne deposu bir sözlüktür: kova bir ad alanı, anahtar düz bir dize, eğik çizgi yalnız önek
  sorgusunda anlamlıdır. Dizin, boş dizin ve dizin boyutu diye bir kavram yoktur.
- Dört fark sayıyla ayrılır: dizin boyutu 1 çağrı yerine 1.240 istek, yeniden adlandırma 1 çağrı
  yerine 2.481.240 istek, 2 KiB ekleme 190 kat yazma, aralık okuma ise birebir.
- Listeleme bayta değil anahtar sayısına bağlıdır: kovanın baytının yüzde 1,5'ini tutan sayaç
  ailesi, listeleme isteklerinin çoğunu üretir ve modelde tek tarama 55,8 saniye sürer.
- Anahtar düzeni erişim örüntüsünü sabitler: aynı veri iki düzende tutulduğunda aylık listeleme
  isteği 29 kat değişir, düzeni sonradan değiştirmek 195 aylık saklama ücreti tutar.
- Devredilen karar görünmez olanlardır (yerleşim, çoğaltma, onarım); elde kalanlar anahtar düzeni,
  depolama sınıfı, sürümleme ve erişim kapsamıdır — dördü de veri taşımadan geri alınamaz.

## Sonraki Adım

Bu dersin bütün sayıları tek bir saklama ücretiyle çıktı: her nesne aynı orandan faturalandı. Oysa
kurgu kovanın içindeki dört aile birbirine hiç benzemiyor — sayaç okumaları günlük yazılıp günlük
okunuyor, fatura belgeleri ayda bir yazılıp yılda birkaç kez açılıyor, saha fotoğrafları bir kez
yazılıp neredeyse hiç okunmuyor. Sonraki ders bu farkı fiyat tarafına geçirir: erişim sıklığına göre
depolama sınıfları vardır, saklama ücreti düştükçe erişim ücreti yükselir. Ölçülecek üç şey var —
her sınıfın başabaş erişim sıklığı, seyrek erişilen veriyi sık sınıfta tutmanın bedeli ve sık
erişilen veriyi seyrek sınıfa atmanın bedeli.
