Önceki bölümde: Iceberg’in neden süper olduğunu konuştuk.
Bölüm 1: Apache Iceberg nedir ? – https://www.oguzerdogan.com/apache-iceberg-nedir/
Bugün yine lakehouse dünyasına dalıyor elleri sıvıyor ve Iceberg’in kaputunu kaldırıyoruz. Hani şu eski dostumuz Hive’ın “aman abi klasörlere direkt bakıver” mantığı başımıza neler açtı, değil mi? Kayıp dosyalar, tutarsızlıklar, “bu veri nereden geldi yahu?” anları… Neyse ki ufukta bir kahraman belirmişti: Apache Iceberg!
Şimdi ise bu arkadaşın içini dışını bir açalım, “kaputun altına” bakalım dedik. Yani, Iceberg tablosu dediğimiz şey tam olarak ne menem bir yapı? Hangi parçalardan oluşuyor ve bu parçalar ne işe yarıyor?

Gelin incelemeye en alt kısımdan başlayalım
1. Data Layer

Burası işin başladığı yer, yani verinin bizzat kendisinin bulunduğu katman. Tablomuzdaki o cicili bicili satırlar var ya, işte onlar burada takılıyor.
Bu katmanda temelde iki tip elemanımız var:
datafiles
(asıl veri dosyaları)delete files
(silme dosyaları – bunlara geleceğiz).
Bir sorgu attığınızda, cevap büyük ihtimalle buradan geliyor.
Bu katman, Iceberg ağacının en uç dalları gibi düşünün. Genelde nerede mi yaşarlar? HDFS gibi dağıtık dosya sistemlerinde ya da S3, ADLS, GCS gibi afili nesne depolama hizmetlerinde. Neden? Çünkü buralar hem ucuz hem de istediğiniz kadar büyüyebiliyor (scaling dedikleri). Yani lakehouse
hayallerimiz için biçilmiş kaftan!
Datafiles:
- İşte burası satır satır verinin depolandığı yer. Bildiğimiz veri dosyaları yani.
- Güzelliği ne biliyor musunuz? Iceberg “illa şu format olacak” diye tutturmuyor. İster
Apache Parquet
, isterApache ORC
, isterApache Avro
kullan. Bu ne demek? Elinizdeki farklı formatlı veriyi rahatça kullanın, iş yükünüze göre en performanslısını seçin demek! Gelecekte çıkacak yeni formatlara da kapısı açık (future-proofing diye havalı bir lafı var bunun). - İpucu: Genelde herkes
Apache Parquet
kullanıyor. Neden? Çünkü sütun bazlı (columnar) yapısı sayesinde OLAP sorgularında coşuyor, satır bazlılara göre ÇOK daha hızlı. Hem sıkıştırması daha iyi, hem paralelliği artırıyor, hem de dosya/grup bazında min/max gibi istatistikler tutarak sorguları hızlandırıyor. YaniParquet
candır, gerisi heyecandır! 😉
Delete Files:
- Şimdi, veri gölü depolaması genelde “ben değişmem abi” modunda takılır (
immutable
). Yani bir satırı gidip direkt dosyanın içinden silemezsin (genellikle). E peki, UPDATE veya DELETE yapınca ne oluyor? İştedelete files
burada devreye giriyor! - Bu dosyalar, hangi kayıtların mantıksal olarak silindiğini veya değiştiğini takip ediyor. Özellikle
Merge-on-Read
(MOR) denen stratejide çok işe yarıyorlar.Copy-on-Write
(COW) stratejisinde bir satır değişince KOCA VERİ DOSYASI yeniden yazılırken (biraz müsrifçe, kabul edelim), MOR’da sadece “şu satırı sil” veya “şu satırın yeni hali bu” bilgisi ayrı birdelete file
‘a yazılıyor. Okuma sırasında bu bilgiler birleştiriliyor. Hangisi daha iyi? Duruma göre değişir, o ayrı bir tartışma konusu! - Not: Bu
delete files
olayı Iceberg v2 ile geldi, aklınızda bulunsun.

İki çeşit delete file
var:
Positional Delete Files:
Bunlar çok net konuşur: “Şu dosyanın içindeki 5. satırı sil!”. Dosya yolunu ve satır numarasını (pozisyonunu) verir. Okurken motor neyi atlayacağını şak diye bilir (hızlı okuma), ama yazarken “acaba o satır hangi dosyadaydı, kaçıncı sıradaydı?” diye bulmak için ilgili datafile
‘ı okumak gerekebilir (yazması biraz maliyetli).

Equality Delete Files:
Bunlar daha çok “ID’si 123 olan kaydı sil” der gibi çalışır. Yani silinecek satırı, bir veya daha fazla alanının değeriyle (genelde primary key
gibi) tanımlar. Yazarken pozisyon bulma derdi yok (hızlı yazma), ama okurken motor her satırı alıp “acaba bu silineceklerden biri mi?” diye delete file
‘daki değerlerle karşılaştırmak zorunda kalabilir (okuması biraz maliyetli). Bir de silinen ID ile aynı ID’ye sahip yeni bir kayıt eklenirse ne olacak? İşte orada da sequence number
gibi numaralandırma mekanizmaları devreye giriyor ki işler karışmasın.

2. Metadata Layer:

İşte burası Iceberg mimarisinin kalbi, beyni, her şeyi! Tüm metadata
dosyaları bu katmanda bulunur. Aslında burası, aşağıdaki datafiles
‘ları ve onlar hakkındaki bilgileri (ve bu dosyaları yaratan işlemleri!) takip eden zeki bir ağaç yapısı gibi.
Üç ana dosya türümüz var: manifest files
, manifest lists
ve metadata files
. Iceberg’in o meşhur time travel
, schema evolution
gibi havalı özelliklerini mümkün kılan yer tam da burası!
2.1 Manifest Files:

- Bunlar,
Data Layer
‘daki dosyaların (datafiles
vedelete files
) belirli alt kümelerini takip eder. Sadece takip etmekle kalmaz, her dosya hakkında ek detaylar ve istatistikler de tutar: “Bu dosyadaki şu sütunun minimum/maksimum değeri nedir?”, “Kaç tane null var?”, “Toplam kaç kayıt içeriyor?” gibi. - İşte Hive’dan en büyük farklardan biri! Hive gibi klasör bazında değil, dosya bazında takip yapıyor bu arkadaşlar. Bu sayede çok daha akıllıca işler yapabiliyor.
- Bu istatistikler ne işe mi yarıyor? Sorgu motorları bu bilgilere bakıp, işlemesi gerekmeyen
datafiles
‘ları daha en başından “sen gelme ulan ayı!” diye eleyebiliyor (pruning
deniyor buna). Bu da demek oluyor ki: DAHA HIZLI SORGULAR! 🚀 - Peki bu istatistikler ne zaman hesaplanıyor? Veriyi yazan motor, yazma işlemi sırasında hesaplayıp
manifest file
‘a ekliyor. Yani Hive’ın sonradan “dur bi’ tüm bölümü/tabloyu tarayayım da istatistik çıkarayım” şeklindeki pahalı ve genelde bayatlamış yaklaşımına göre kat kat daha verimli ve güncel! - Teknik Detay: Bu dosyalar Avro formatında saklanıyor.
2.2 Manifest Lists:

- Bir Iceberg tablosunun belirli bir zamandaki durumunu, yani bir “anlık görüntüsünü” (
snapshot
) temsil eder. Hani şutime travel
dediğimiz şeyin anahtarı işte bu! - İçinde ne var? O anlık görüntüye ait TÜM
manifest files
‘ların bir listesi. Hermanifest file
için konumunu, hangi bölüme ait olduğunu ve takip ettiğidatafiles
‘lardaki bölüm sütunlarının min/max değerlerini falan tutuyor. - Bu bilgi de yine sorgu motorlarının işine yarıyor. Sadece ilgili
manifest files
‘ları okuyarak performansı artırıyorlar. Akıllıca, değil mi? - Teknik Detay: Bunlar da Avro formatında. İçinde
manifest file
‘ları tanımlayan bir sürü yapı (struct) var.
2.3 Metadata Files (Metadata Dosyaları):

- İşte zincirin en tepesindeki eleman (bu katman için konuşuyorum).
Manifest List
‘lerini takip eder ve tablonun genel yapısını tanımlar. Neler mi var içinde?- Tablonun şeması (
schema
) - Bölümleme bilgisi (
partitioning spec
) - Mevcut tüm
snapshot
‘ların listesi (geçmişe yolculuk buradan başlıyor!) - Ve en önemlisi: Hangi
snapshot
‘ın şu anki GÜNCEL (current
)snapshot
olduğu bilgisi.
- Tablonun şeması (
- Tabloda herhangi bir değişiklik (yazma, güncelleme, silme vs.) yapıldığında, YEPYENİ bir
metadata file
oluşturulur. Sonra da Katalog Katmanı (ona da geleceğiz) aracılığıyla bu yeni dosya, atomik bir şekilde güncel sürüm olarak işaretlenir. - Atomiklik dedik mi akan sular durur! Bu atomik işlem sayesinde tablonun geçmişi düzgün, çizgisel bir sıra (
linear history
) izler. Özellikle aynı anda birden fazla kişinin veya işlemin tabloya yazmaya çalıştığı (concurrent writes
) durumlarda hayat kurtarır. Kimse kimsenin değişikliğinin üzerine yazamaz, veri kaybı olmaz ve okuyucular her zaman tablonun tutarlı bir versiyonunu görür. Hive’da bu işler ne kadar karışıktı, hatırlayanlar? 😉
2.4 Puffin Files:
- Bazen
manifest files
‘daki temel istatistikler yetmez. İşte o zamanPuffin files
devreye girebilir. Bunlar, belirli sorgu tiplerini hızlandırmak için tasarlanmış daha gelişmiş istatistikler ve indeksler (meselabloom filters
veyaApache DataSketches
ile yaklaşık benzersiz değer sayıları –approximate distinct counts
) depolayan isteğe bağlı dosyalardır. - Ne zaman işe yarar? Mesela tam sayım yapmanın ÇOK pahalı olduğu devasa tablolarda veya “yaklaşık sonuç da olur abi” dediğimiz BI dashboard’larında falan kullanışlı olabilir.
3. Catalog Layer:

Geldik en üste! Bir tabloyla etkileşime geçmek isteyen (sorgu motoru olur, kullanıcı olur) herkesin ilk uğradığı yer burası. Temel görevi ne? Çok basit aslında: Gelen tablo adını (mesela veritabanim.super_tablom
) alır ve o tablonun şu anki güncel durumunu gösteren EN SON metadata file
‘ının konumunu söyler. “Buyurun, güncel harita burada!” der gibi.
- Atomik Güncelleme ŞART! (BU ÇOK ÖNEMLİ!)
- Bir Iceberg kataloğunun gerçekten işe yarar olması için sağlaması gereken EN KRİTİK şey, bu
metadata file
işaretçisini atomik olarak güncelleyebilmesidir. Yani, birisi yeni birmetadata file
oluşturduğunda, katalog bu yeni dosyayı “işte güncel olan bu!” diye işaretlerken, bu işlemin bölünemez, tek bir adımda yapılması gerekir. - Neden bu kadar önemli? Çünkü eğer atomik olmasa, iki kişi aynı anda tabloya yazmaya çalıştığında, biri diğerinin yaptığı değişikliği fark etmeden üzerine yazabilir (eyvah!). Ya da bir okuyucu tam güncelleme anında eskiyle yeni arasında kalıp tutarsız bir durum görebilir (daha da eyvah!). Atomiklik sayesinde herkes her zaman aynı, tutarlı tablo durumunu görür. Concurrency sorunlarına elveda! 👋
- Bir Iceberg kataloğunun gerçekten işe yarar olması için sağlaması gereken EN KRİTİK şey, bu
- Çeşit Çeşit Katalog:
- Bu atomik güncelleme işini yapabilen birçok farklı sistem, Iceberg kataloğu olarak kullanılabilir. Seçenek bol:
Hive Metastore
(Eski dostumuz, ama burada işe yarıyor!)AWS Glue Data Catalog
Project Nessie
(Git gibi versiyonlama sunan havalı bir seçenek)JDBC
veritabanları (PostgreSQL, MySQL vb.)REST
tabanlı özel servisler- Hatta
Hadoop
veya dosya sistemi tabanlı kataloglar (ama dikkat, her dosya sistemi atomikliği garanti etmez, S3 mesela etmez, ek numara gerekir!)
- Her biri bu “en güncel
metadata file
hangisi?” bilgisini farklı yerde tutar:Hadoop Catalog
: Genelde metadata klasöründeversion-hint.text
diye bir dosyada sürüm numarası tutar. Atomiklik dosya sistemine bağlı.Hive Catalog
:Hive Metastore
‘daki tablo kaydındametadata_location
veyalocation
diye bir özellikte dosya yolunu saklar.AWS Glue Catalog
:Glue Data Catalog
‘daki tablo kaydındametadata_location
özelliğinde yolu saklar.Nessie Catalog
: Nessie’deki kayıttametadataLocation
özelliğinde yolu saklar.
- Bu atomik güncelleme işini yapabilen birçok farklı sistem, Iceberg kataloğu olarak kullanılabilir. Seçenek bol:
Sonuç: Ee, Ne Anladık Bu İşten?
Olay şu arkadaşlar: Apache Iceberg dediğimiz yapı, akıllıca tasarlanmış üç katmandan oluşuyor: Data Layer
(verinin kendisi), Metadata Layer
(verinin künyesi, geçmişi, istatistikleri) ve Catalog Layer
(herkesin doğru ve güncel bilgiye ulaşmasını sağlayan danışma).
- Veri Katmanı (Data Layer): Asıl yükü çeker, veriyi farklı formatlarda tutar, silme/güncelleme işlemlerini
delete files
ile çözer. - Metadata Katmanı (Metadata Layer): İşin beynidir.
Manifest
‘ler vemetadata file
‘lar ile dosyaları, istatistikleri, tablo geçmişini (snapshot
) takip eder.Pruning
,time travel
,schema evolution
gibi güzellikleri mümkün kılar. - Katalog Katmanı (Catalog Layer): En güncel
metadata file
‘ı gösterir ve atomik güncellemelerle tüm sistemin tutarlılığını, özellikle eş zamanlı işlemlerde, garanti altına alır.
İşte bu katmanlı yapı sayesinde Iceberg, Hive’ın o eski ve yorucu sorunlarına (tutarsızlık, yavaş metadata işlemleri, ALTER TABLE
kabusları vb.) çözüm getiriyor ve bize ACID
işlemleri, zamanda yolculuk, güvenli şema değişiklikleri gibi süper güçler veriyor!
Umarım bu “kaput altı” turu hoşunuza gitmiştir ve Iceberg’in neden bu kadar popülerleştiğini biraz daha iyi anlamışsınızdır. Bir sonraki yazımda görüşmek üzere, kodunuz bug’sız, veriniz tutarlı olsun!
Kaynaklar: Apache Iceberg: The Definitive Guide