Çoğu dışa aktarım özelliği gecelik bir iş olarak kurulur: Saat 02:00'de dünü yaz. Akla ilk gelen yapı budur, demoda iyi görünür ve yalnızca canlı ortamda ortaya çıkan dört açıdan yanlıştır.
- Başarısız olan bir bölüm bir sonraki denemesini 24 saat sonra alır.
- Birinin sabah 10'da istediği yeniden dışa aktarım ertesi güne kadar bekler.
- Tüm müşterilerin dışa aktarımları aynı saate denk gelir; dolayısıyla yük, tam da kimsenin izlemediği anda zirve yapar.
- Geriye dönük doldurma ayrı bir kod yoludur. Bu da hataların bulunduğu yolun o olduğu anlamına gelir, çünkü düzgün çalışan yoldan yüz kat daha seyrek çalışır.
Daha iyi bir düzenleyici fikir var ve geri kalan her şey ondan türüyor.
Bölüm, yeniden yapılabilen bir iş birimidir
Dışa aktarımı bir takvim olarak değil, (veri kümesi, gün) çiftlerinden oluşan bir defter olarak modelleyin. Her çiftin bir durumu vardır: hiç denenmedi, kuyrukta, çalışıyor, tamamlandı veya bir sonraki deneme zamanıyla birlikte başarısız oldu. Sık aralıklarla (örneğin on beş dakikada bir) çalışan bir tarama, hangi çiftlerin zamanının geldiğini sorar ve bunların sınırlı bir kısmını işler.
Böylece zamanlanmış dışa aktarım, doksan günlük bir geriye dönük doldurma, bir bucket kesintisinden sonraki yeniden deneme ve arayüzden elle kuyruğa alınan bir yeniden dışa aktarım, aynı satıra ulaşan aynı kod yolu hâline gelir. Hiçbirinin veri ambarındaki bir satırı ikiye katlayamamasını sağlayan şey budur ve özelliğe yapılacak her değişiklikte korunmaya değer.
Defteri dürüst tutan üç kural vardır:
- Tek bir bayt yazmadan önce satırı sahiplenin. Süresini aşan bir tarama, önceki bir taramanın hâlâ üzerinde çalıştığı bir bölümü başlatmamalıdır. Birkaç saatten eski bir sahiplenmenin ölü olduğu varsayılır ve satır yeniden sahiplenilir; bu, bir çalışanın yükleme ortasında sonlandırıldığı durumdur.
- Her taramada hesap başına iş miktarını sınırlayın. Üç aylık açığı kapatan tek bir müşteri, herkes beklerken hattı meşgul etmemelidir. Önce kuyruğa alınmış işleri, ardından en eski günü sıraya koyun; böylece geriye dönük doldurma ortada bir boşluk bırakmak yerine ileriye doğru dolar.
- Bugünü asla dışa aktarmayın. Bugünün bölümü kapanmamıştır. Onu yazmak, yarın değiştirilmesi gereken bir dosya üretir; bu arada birilerinin panelinde yarım bir gün gerçek bir günmüş gibi görünür.
Güvenilirliğin tüm hikâyesi commit işaretçisidir
Nesne depolamada işlem (transaction) yoktur. Yarıda kalan bir çalıştırma gerçek bir klasörde gerçek dosyalar bırakır ve o klasörü okuyan bir yükleyici bunları eksiksiz bir kümeden ayırt edemez.
Çözüm, en son yazılan bir işaretçi dosyasıdır. Veri parçalarını yazın, daha uzun süren önceki bir çalıştırmanın geride bıraktığı eski parçaları silin ve ancak bundan sonra bir manifest yazın. Artık okuyucunun tek ve ucuz bir testi vardır: Manifest varsa bölüm eksiksizdir ve yüklemek güvenlidir. Yoksa bir sonraki tarama oradakilerin üzerine yazacaktır.
Hazır başlamışken manifestin üzerine düşeni yapmasını sağlayın: şema, dosya başına satır sayıları, bayt sayıları ve sağlama toplamları (checksum) ile satırların nereden geldiğini belirten bir satır. Bu son alan, bir dışa aktarım hakkında herkesin sorduğu ilk soruyu yanıtlar: "Bu günde neden beklediğimden daha az satır var?"
Eski parçaların silinmesi göründüğünden daha önemlidir. Önceki çalıştırmanın beş parça ürettiği yerde üç parça üreten bir yeniden çalıştırma, geride iki yetim parça bırakır ve joker karakterli bir yükleme yedisini de seve seve okur. "Bölümü değiştir" ifadesi yaklaşık olarak değil, harfiyen doğru olmalıdır.
Kimsenin yükleyip yükleyemeyeceğini belirleyen düzen ayrıntıları
İki dosya adlandırma kuralı pazarlık konusu yapılmamalıdır.
Hive tarzı bölüm dizinleri kullanın. dt=2026-09-05 adlı bir klasör; BigQuery, Athena, Redshift Spectrum, Spark ve DuckDB tarafından hiçbir yapılandırma gerekmeden bir bölüm sütunu olarak tanınır. 2026-09-05 adlı bir klasör ise analistin her bölümü elle tanımlaması anlamına gelir.
Veri dosyalarına ve meta veri dosyalarına farklı ön ekler verin. Veriler part-* olarak, meta veriler ise başında alt çizgiyle adlandırılsın. Yükleyiciler .../dt=.../part-* yolunu okur; böylece aynı klasörde duran bir manifest ve bir SQL betiği asla veri olarak ayrıştırılamaz. Düz bir * glob deseniyle ayrıştırılırlar ve ortaya çıkan hata mesajı manifestten hiç bahsetmez.
Bir şey daha: Yolda sıralı bir tam sayı değil, opak bir hesap tanımlayıcısı kullanın. Tam sayı bir kimlik tahmin edilebilir ve onu üreten platformun dışında hiçbir anlam taşımaz.
Şemayı sabitleyin, sonra ona herkese açık bir API gibi davranın
Bir bölüm yüklendiğinde sütun adları artık birinin dbt modellerinde ve bir başkasının panelinde yer alır. Sona sütun eklemek güvenlidir. Bir sütunu yeniden adlandırmak, sırasını veya tipini değiştirmek ise her tüketici için geriye dönük uyumluluğu bozan bir değişikliktir ve haftalar sonra biraz yanlış görünen bir sayı sayesinde fark edilir.
İşin zor kısmı müşteriye özel alanlardır ve yapılması gereken, akla ilk gelen yaklaşıma direnmektir. Tabloyu her hesabın kendi nitelik adlarıyla genişletmeyin: Aksi hâlde her müşterinin farklı bir tablosu olur ve ortak bir şema imkânsız hâle gelir. Ucu açık kısımları tek bir JSON sütununa koyun. Bu sütun NDJSON ve Parquet'te erişilebilir kalır, veri ambarları onun içini sorgulayabilir ve yeni bir nitelik dünkü modeli asla bozmaz.
İki tip ayrıntısı sessizce zarar verir:
- Tarihleri zaman damgalarından ayrı tutun. Günlük bir sayacın tarihini bir saat diliminde gece yarısı olarak göstermek, bir istatistiğin bir saat batıdaki bir veri ambarında yanlış güne atfedilmesine yol açar.
- Her yerel yüklemede şemayı açıkça verin, asla otomatik algılamaya bırakmayın. Otomatik algılama tipleri dosya bazında çıkarır; bu yüzden bir sütunun tamamen null olduğu bir gün farklı bir tiple yüklenir ve yüklemeler haftalar sonra görünür bir neden olmadan başarısız olmaya başlar.
Bir bölümün ne anlama geldiğini açıkça belirtin
Her veri kümesi aynı şekilde bölümlenmez ve bu fark belgelenmelidir; aksi hâlde yanlış bir sayı sayesinde fark edilir.
- Olaylar (events), bir grubun arşivlendiği zamana göre değil, olayın kendisinden alınan gerçekleşme zamanına göre bölümlenir. Aksi hâlde geç gelen bir grup, bir günü iki bölüme dağıtır.
- Profiller ve ziyaretçiler günlük bir anlık görüntü değil, artımlı bir akıştır: Bir kayıt, aktif olduğu her bölümde yer alır ve en yenisi en güncel durumunu tutar. Bu durumda veri ambarındaki güncel durum, tanımlayıcı üzerinde son görülme zamanına göre sıralanan bir pencere fonksiyonudur ve bunu en baştan belirtmek koca bir destek yazışmasını önler.
- Günlük istatistikler, satırın istatistik tarihine göre bölümlenir.
Yükleme SQL'ini üretin; insanların kullandığı yarı odur
Analist sütun tiplerini, bölüm sütununu ve format seçeneklerini elle çözmek zorundaysa doğru Parquet dosyalarıyla dolu bir bucket bile yine bir destek talebidir. Bunları yanlış yapmak, bir zaman damgasının birinin modelinde sessizce metne dönüşmesinin yoludur.
Her bölümün yanına, dosyaların yazıldığı aynı şemadan üretilmiş, çalıştırılmaya hazır bir betik yazın: Snowflake için bir COPY INTO, BigQuery için bir LOAD DATA, Athena veya Trino için bir CREATE EXTERNAL TABLE. Veriyle aynı kaynaktan geldiği için ikisi birbiriyle çelişemez. Bu bir taşıma (migration) aracı değil, bir başlangıç noktasıdır: Bir tabloya ad verir, onu yönetmez.
Yerel yükleme sunulan yerlerde, yüklemenin bir günü sona eklemek yerine değiştirmesini sağlayın. Sona ekleme ilk yeniden denemede her satırı ikiye katlar ve ilk yeniden deneme her zaman gelir.
Kimin bucket'ı ve bunun ticari önemi
Son karar teknik değildir. Müşterinin kendi depolama alanına, onun kimlik bilgileriyle yazmak; depolama faturasının, saklama politikasının ve veri yerleşimi sorusunun tamamen müşteriye ait olması demektir. Bu yaklaşım, kurumsal anlaşmaları gerçekten belirleyen iki itirazı yanıtlar ("verimizi dışarı alamıyoruz" ve "verimizin bir kopyasının daha bir tedarikçinin hesabında durmasını istemiyoruz") ve tedarikçiye, depolama için ücret alabilme imkânı dışında hiçbir şeye mal olmaz.
Bunu siz geliştirecekseniz pratik bir not: Bağlantıyı küçük bir nesne yazıp silerek test edin. Salt okunur bir anahtar diğer tüm kontrollerden geçer, sonra saat 03:00'te kimsenin izlemediği bir bölümde başarısız olur.
Veri kümelerini, formatları ve bölüm defterini Veri Ambarı & Depolama Aktarımı sayfasında, veri ambarına hiç ihtiyaç duymadan yanıtlanan günlük soruları ise raporlama modülünde inceleyin.