<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://sonsuzus.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://sonsuzus.github.io/" rel="alternate" type="text/html" /><updated>2026-08-02T07:13:24+00:00</updated><id>https://sonsuzus.github.io/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">Algoritmik Önyargıyı Satranç Metaforuyla Anlamak: Kurallar Adil, Sonuç Neden Değil?</title><link href="https://sonsuzus.github.io/posts/algoritmik-onyargiyi-satranc-metaforuyla-anlamak-kurallar-adil-sonuc-neden-degil/" rel="alternate" type="text/html" title="Algoritmik Önyargıyı Satranç Metaforuyla Anlamak: Kurallar Adil, Sonuç Neden Değil?" /><published>2026-08-02T00:00:00+00:00</published><updated>2026-08-02T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/algoritmik-onyargiyi-satranc-metaforuyla-anlamak-kurallar-adil-sonuc-neden-degil</id><content type="html" xml:base="https://sonsuzus.github.io/posts/algoritmik-onyargiyi-satranc-metaforuyla-anlamak-kurallar-adil-sonuc-neden-degil/"><![CDATA[<p>Satrançta kurallar herkes için aynıdır: Piyon bir kare ilerler, fil çapraz gider, şah tehdit altındaysa korunmalıdır. Yine de bir oyuncuya vezir, diğerine yalnızca birkaç piyon vererek oyunu başlatırsak kuralların eşit olması karşılaşmayı adil yapmaz. Kural tabanlı yazılımlarda algoritmik önyargı da çoğu zaman böyle doğar. Kod herkese aynı koşulları uygulayabilir; fakat başlangıç koşulları, kullanılan göstergeler ve geçmişten alınan veriler eşit değilse sonuçlar sistematik biçimde bazı grupları dezavantajlı hâle getirebilir.</p>

<p>``</p>

<h2 id="tahta-aynı-başlangıç-konumları-farklı">Tahta Aynı, Başlangıç Konumları Farklı</h2>

<p>Kural tabanlı sistemler, önceden belirlenen koşullara göre karar verir. Örneğin bir kredi sistemi şöyle çalışabilir: “Geliri belirli bir sınırın altında olan ve son iki yılda düzenli ödeme geçmişi bulunmayan başvuruyu reddet.” Bu kuralda cinsiyet, yaş veya etnik köken açıkça yazmıyor olabilir. Dolayısıyla sistem ilk bakışta tarafsız görünür.</p>

<p>Ancak ödeme geçmişi oluşturma fırsatı herkese eşit dağılmamışsa kural, geçmişteki eşitsizlikleri yeniden üretir. Satranç metaforuyla söylersek hakem taşların rengini önemsemiyordur; fakat oyunculardan biri oyuna zaten eksik taşlarla başlamıştır.</p>

<p>Bir grubun olumlu karar alma oranını şöyle gösterebiliriz:</p>

\[P(\hat{Y}=1 \mid G=g)\]

<p>Burada $\hat{Y}=1$ olumlu kararı, $G=g$ ise belirli bir gruba üyeliği ifade eder. İki grup için bu olasılıklar ciddi biçimde farklıysa açıkça ayrımcı bir kural bulunmasa bile sonuçlarda önyargı olabilir.</p>

<h2 id="önyargı-hangi-hamlelerde-gizlenir">Önyargı Hangi Hamlelerde Gizlenir?</h2>

<table>
  <thead>
    <tr>
      <th>Satranç unsuru</th>
      <th>Algoritmik karşılığı</th>
      <th>Olası adaletsizlik</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Başlangıç dizilimi</td>
      <td>Geçmiş veri ve koşullar</td>
      <td>Eski eşitsizliklerin devralınması</td>
    </tr>
    <tr>
      <td>Hamle kuralları</td>
      <td>İş kuralları ve eşikler</td>
      <td>Herkese aynı görünen katı ölçütler</td>
    </tr>
    <tr>
      <td>Taşın değeri</td>
      <td>Özelliklere verilen önem</td>
      <td>Bazı göstergelerin abartılması</td>
    </tr>
    <tr>
      <td>Hakemin kararı</td>
      <td>Denetim ve itiraz süreci</td>
      <td>Hataların düzeltilememesi</td>
    </tr>
    <tr>
      <td>Oyun sonucu</td>
      <td>Kabul, ret veya sıralama</td>
      <td>Belirli grupların sürekli geride kalması</td>
    </tr>
  </tbody>
</table>

<p>Özellikle <strong>vekil değişkenler</strong> önemlidir. Sistem mahalle kodunu kullanıyor ama etnik kökeni kullanmıyor olabilir. Ne var ki mahalle kodu toplumsal ayrışma nedeniyle etnik köken veya gelir düzeyiyle güçlü biçimde ilişkiliyse yasaklanan bilgi arka kapıdan oyuna döner. Fil yerine “çapraz ilerleyen uzun taş” demek, onun fil olduğu gerçeğini değiştirmez.</p>

<h2 id="basit-bir-kural-nasıl-sorun-üretir">Basit Bir Kural Nasıl Sorun Üretir?</h2>

<p>Aşağıdaki örnek, başvuruları gelir ve kredi geçmişine göre değerlendirir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">kredi_karari</span><span class="p">(</span><span class="n">gelir</span><span class="p">,</span> <span class="n">kredi_gecmisi_ayi</span><span class="p">):</span>
    <span class="n">puan</span> <span class="o">=</span> <span class="mi">0</span>

    <span class="k">if</span> <span class="n">gelir</span> <span class="o">&gt;=</span> <span class="mi">30_000</span><span class="p">:</span>
        <span class="n">puan</span> <span class="o">+=</span> <span class="mi">1</span>
    <span class="k">if</span> <span class="n">kredi_gecmisi_ayi</span> <span class="o">&gt;=</span> <span class="mi">24</span><span class="p">:</span>
        <span class="n">puan</span> <span class="o">+=</span> <span class="mi">1</span>

    <span class="k">return</span> <span class="sh">"</span><span class="s">Kabul</span><span class="sh">"</span> <span class="k">if</span> <span class="n">puan</span> <span class="o">==</span> <span class="mi">2</span> <span class="k">else</span> <span class="sh">"</span><span class="s">Ret</span><span class="sh">"</span>
</code></pre></div></div>

<p>Kod kısa, anlaşılır ve herkese aynı şekilde uygulanır. Fakat düzenli finansal hizmetlere erişemeyen kişiler 24 aylık geçmiş koşulunu karşılayamaz. Böylece teknik olarak “eşit” kural, fırsat eşitsizliğini cezaya dönüştürür.</p>

<p>Sonuçları incelemek için seçim oranları karşılaştırılabilir:</p>

\[\text{Oran} = \frac{P(\hat{Y}=1 \mid G=A)}{P(\hat{Y}=1 \mid G=B)}\]

<p>Bu değerin $1$’den belirgin biçimde uzaklaşması araştırılması gereken bir dengesizliğe işaret eder. Ancak tek bir matematiksel ölçü adaletin tamamını açıklamaz; yanlış ret oranları, ekonomik koşullar ve kararın insanlar üzerindeki etkisi de değerlendirilmelidir.</p>

<h2 id="daha-adil-bir-oyun-kurmak">Daha Adil Bir Oyun Kurmak</h2>

<p>İlk adım, yalnızca kodu değil oyunun tamamını denetlemektir. Kurallar farklı gruplara ait örnek verilerle test edilmeli, vekil değişkenler araştırılmalı ve eşik değerlerinin etkisi ölçülmelidir. İnsanlara karar gerekçesi sunmak ve itiraz kanalı açmak da kritiktir.</p>

<p>Ayrıca “herkese aynı kural” ile “herkese adil fırsat” arasındaki fark unutulmamalıdır. Bazen geçmişi daha kısa olan başvurular için alternatif güvenilirlik göstergeleri kullanmak gerekir. Amaç bir gruba bedava vezir vermek değil, kimsenin oyuna şahı eksik başlamadığından emin olmaktır.</p>

<p>Algoritmik adalet, yalnızca tarafsız görünen kurallar yazma işi değildir. Asıl soru şudur: Tahtayı kim kurdu, taşların değerini kim belirledi ve oyun bittiğinde kaybedenler neden hep aynı tarafta kaldı?</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="algoritmik önyargı" /><category term="etik" /><category term="kural tabanlı sistemler" /><summary type="html"><![CDATA[Satrançta kurallar herkes için aynıdır: Piyon bir kare ilerler, fil çapraz gider, şah tehdit altındaysa korunmalıdır. Yine de bir oyuncuya vezir, diğerine yalnızca birkaç piyon vererek oyunu başlatırsak kuralların eşit olması karşılaşmayı adil yapmaz. Kural tabanlı yazılımlarda algoritmik önyargı da çoğu zaman böyle doğar. Kod herkese aynı koşulları uygulayabilir; fakat başlangıç koşulları, kullanılan göstergeler ve geçmişten alınan veriler eşit değilse sonuçlar sistematik biçimde bazı grupları dezavantajlı hâle getirebilir.]]></summary></entry><entry><title type="html">Apache Spark ile Dağıtık ve Bellek İçi Veri İşleme</title><link href="https://sonsuzus.github.io/posts/apache-spark-ile-dagitik-ve-bellek-ici-veri-isleme/" rel="alternate" type="text/html" title="Apache Spark ile Dağıtık ve Bellek İçi Veri İşleme" /><published>2026-08-02T00:00:00+00:00</published><updated>2026-08-02T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/apache-spark-ile-dagitik-ve-bellek-ici-veri-isleme</id><content type="html" xml:base="https://sonsuzus.github.io/posts/apache-spark-ile-dagitik-ve-bellek-ici-veri-isleme/"><![CDATA[<p>Devasa bir veri setini tek bilgisayarda işlemeye çalışmak, taşınma günü bütün kolileri küçük bir otomobile doldurmaya benzer: Bir noktadan sonra ne bagaj kapanır ne de süreç ilerler. Apache Spark, verileri kümeye dağıtarak ve ara sonuçları mümkün olduğunca bellekte tutarak bu sorunu çözer. Böylece haritalama, filtreleme ve indirgeme gibi işlemler, her aşamada diske yazma zorunluluğuna takılmadan çok daha hızlı gerçekleştirilebilir.</p>

<p>``</p>

<h2 id="spark-neden-hızlıdır">Spark neden hızlıdır?</h2>

<p>Geleneksel Hadoop MapReduce modelinde bir işin çıktısı çoğunlukla diske yazılır ve sonraki aşama bu veriyi yeniden diskten okur. Disk erişimi, özellikle yinelemeli algoritmalarda önemli bir darboğazdır. Spark ise çalışma verilerini RAM üzerinde saklayabilir ve aynı veri tekrar kullanılacaksa <code class="language-plaintext highlighter-rouge">cache()</code> veya <code class="language-plaintext highlighter-rouge">persist()</code> ile bellekte tutabilir.</p>

<p>Basitleştirilmiş toplam çalışma süresini şöyle düşünebiliriz:</p>

\[T_{toplam} = T_{okuma} + T_{hesaplama} + T_{iletisim} + T_{yazma}\]

<p>Spark, özellikle $T_{okuma}$ ve $T_{yazma}$ bileşenlerini azaltmaya çalışır. Ancak “Spark her şeyi RAM’de yapar” demek doğru değildir. Bellek yetersiz kalırsa bazı bölümler diske taşabilir; ayrıca shuffle sırasında ağ ve disk kullanılabilir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Geleneksel MapReduce</th>
      <th>Apache Spark</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ara sonuçlar</td>
      <td>Genellikle diske yazılır</td>
      <td>Bellekte tutulabilir</td>
    </tr>
    <tr>
      <td>Yinelemeli işler</td>
      <td>Daha yavaş</td>
      <td>Cache sayesinde hızlı</td>
    </tr>
    <tr>
      <td>İşlem modeli</td>
      <td>Map ve Reduce aşamaları</td>
      <td>DAG tabanlı esnek aşamalar</td>
    </tr>
    <tr>
      <td>Gerçek zamanlı kullanım</td>
      <td>Sınırlı</td>
      <td>Structured Streaming desteği</td>
    </tr>
    <tr>
      <td>API seçenekleri</td>
      <td>Daha düşük seviyeli</td>
      <td>Python, Scala, Java ve R</td>
    </tr>
  </tbody>
</table>

<h2 id="dağıtık-işlem-mantığı">Dağıtık işlem mantığı</h2>

<p>Spark uygulamasında <strong>driver</strong>, yapılacak işi planlar; <strong>executor</strong> süreçleri ise verinin parçaları üzerinde hesaplama yapar. Veri, partition adı verilen bölümlere ayrılır. Her partition farklı bir executor tarafından işlenebildiği için paralellik elde edilir.</p>

<p>Teorik olarak $N$ kayıt, eşit güçte $P$ işlemciye kusursuz biçimde dağıtılırsa işlem yükü yaklaşık olarak şöyledir:</p>

\[W_{birim} \approx \frac{N}{P}\]

<p>Gerçekte ağ iletişimi, görev planlama ve dengesiz partition dağılımı nedeniyle doğrusal hızlanma her zaman mümkün değildir. Örneğin kayıtların büyük kısmı tek bir anahtara aitse <strong>data skew</strong> oluşur ve bir executor diğerleri kahvesini bitirmişken hâlâ çalışıyor olabilir.</p>

<h2 id="pyspark-ile-mapreduce-benzeri-analiz">PySpark ile MapReduce benzeri analiz</h2>

<p>Aşağıdaki örnek, bir metindeki kelimeleri sayar. <code class="language-plaintext highlighter-rouge">flatMap</code> satırları kelimelere ayırır, <code class="language-plaintext highlighter-rouge">map</code> her kelimeyi <code class="language-plaintext highlighter-rouge">(kelime, 1)</code> çiftine dönüştürür ve <code class="language-plaintext highlighter-rouge">reduceByKey</code> aynı kelimelerin sayılarını toplar.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">pyspark.sql</span> <span class="kn">import</span> <span class="n">SparkSession</span>

<span class="n">spark</span> <span class="o">=</span> <span class="n">SparkSession</span><span class="p">.</span><span class="n">builder</span> \
    <span class="p">.</span><span class="nf">appName</span><span class="p">(</span><span class="sh">"</span><span class="s">KelimeSayaci</span><span class="sh">"</span><span class="p">)</span> \
    <span class="p">.</span><span class="nf">getOrCreate</span><span class="p">()</span>

<span class="n">satirlar</span> <span class="o">=</span> <span class="n">spark</span><span class="p">.</span><span class="n">sparkContext</span><span class="p">.</span><span class="nf">textFile</span><span class="p">(</span><span class="sh">"</span><span class="s">veri/metinler.txt</span><span class="sh">"</span><span class="p">)</span>

<span class="n">sonuclar</span> <span class="o">=</span> <span class="p">(</span>
    <span class="n">satirlar</span>
    <span class="p">.</span><span class="nf">flatMap</span><span class="p">(</span><span class="k">lambda</span> <span class="n">satir</span><span class="p">:</span> <span class="n">satir</span><span class="p">.</span><span class="nf">lower</span><span class="p">().</span><span class="nf">split</span><span class="p">())</span>
    <span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">kelime</span><span class="p">:</span> <span class="p">(</span><span class="n">kelime</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
    <span class="p">.</span><span class="nf">reduceByKey</span><span class="p">(</span><span class="k">lambda</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="p">)</span>
<span class="p">)</span>

<span class="k">for</span> <span class="n">kelime</span><span class="p">,</span> <span class="n">adet</span> <span class="ow">in</span> <span class="n">sonuclar</span><span class="p">.</span><span class="nf">take</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">kelime</span><span class="p">,</span> <span class="n">adet</span><span class="p">)</span>

<span class="n">spark</span><span class="p">.</span><span class="nf">stop</span><span class="p">()</span>
</code></pre></div></div>

<p>Buradaki dönüşümler hemen çalışmaz. Spark, <strong>lazy evaluation</strong> yaklaşımıyla işlemleri bir DAG üzerinde biriktirir. <code class="language-plaintext highlighter-rouge">take(10)</code> gibi bir action çağrıldığında plan optimize edilir ve görevler executorlara gönderilir. Bu sayede gereksiz hesaplamalar azaltılabilir.</p>

<h2 id="rdd-mi-dataframe-mi">RDD mi, DataFrame mi?</h2>

<table>
  <thead>
    <tr>
      <th>Yapı</th>
      <th>Avantajı</th>
      <th>Uygun kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>RDD</td>
      <td>Düşük seviyeli kontrol</td>
      <td>Özel veri dönüşümleri</td>
    </tr>
    <tr>
      <td>DataFrame</td>
      <td>Catalyst optimizasyonu</td>
      <td>Analiz ve ETL süreçleri</td>
    </tr>
    <tr>
      <td>Dataset</td>
      <td>Tip güvenliği</td>
      <td>Scala ve Java uygulamaları</td>
    </tr>
  </tbody>
</table>

<p>Modern projelerde çoğunlukla DataFrame API tercih edilir. Çünkü Spark’ın Catalyst optimizer bileşeni sorgu planını inceleyerek filtreleri erkene alma ve gereksiz sütunları okumama gibi iyileştirmeler yapabilir.</p>

<p>Spark sihirli bir hızlandırma düğmesi değildir; doğru partition sayısı, uygun cache kullanımı ve shuffle maliyetlerinin izlenmesi gerekir. Yine de büyük veri setlerinde tekrarlı analiz, makine öğrenmesi, ETL ve akış işleme ihtiyaçları söz konusu olduğunda bellek içi yaklaşımı, klasik disk merkezli modellere karşı son derece güçlü bir avantaj sağlar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Apache Spark" /><category term="Büyük Veri" /><category term="PySpark" /><summary type="html"><![CDATA[Devasa bir veri setini tek bilgisayarda işlemeye çalışmak, taşınma günü bütün kolileri küçük bir otomobile doldurmaya benzer: Bir noktadan sonra ne bagaj kapanır ne de süreç ilerler. Apache Spark, verileri kümeye dağıtarak ve ara sonuçları mümkün olduğunca bellekte tutarak bu sorunu çözer. Böylece haritalama, filtreleme ve indirgeme gibi işlemler, her aşamada diske yazma zorunluluğuna takılmadan çok daha hızlı gerçekleştirilebilir.]]></summary></entry><entry><title type="html">Büyük Verinin Temelleri: 3V Kuralıyla Verinin Yeni Dünyası</title><link href="https://sonsuzus.github.io/posts/buyuk-verinin-temelleri-3v-kuraliyla-verinin-yeni-dunyasi/" rel="alternate" type="text/html" title="Büyük Verinin Temelleri: 3V Kuralıyla Verinin Yeni Dünyası" /><published>2026-08-02T00:00:00+00:00</published><updated>2026-08-02T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/buyuk-verinin-temelleri-3v-kuraliyla-verinin-yeni-dunyasi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/buyuk-verinin-temelleri-3v-kuraliyla-verinin-yeni-dunyasi/"><![CDATA[<p>Bir e-ticaret sitesindeki tıklamalar, akıllı saatlerin ölçtüğü nabız değerleri, sosyal medya paylaşımları ve fabrikalardaki sensör kayıtları… Modern dünyada veri yalnızca çoğalmıyor; hızlanıyor ve biçim değiştiriyor. <strong>Büyük Veri (Big Data)</strong>, tek başına “çok fazla veri” anlamına gelmez. Geleneksel sistemlerin makul süre ve maliyetle saklamakta, işleyip analiz etmekte zorlandığı veri kümelerini ve bu sorunu çözmek için geliştirilen yöntemleri ifade eder.
``</p>
<h2 id="büyük-veri-neden-büyüktür">Büyük Veri Neden “Büyük”tür?</h2>

<p>Bir veri kümesinin büyüklüğü mutlak değildir. Dün büyük sayılan birkaç terabayt, bugün sıradan bir şirketin günlük üretimi olabilir. Bu nedenle Büyük Veri’yi yalnızca gigabayt veya petabayt üzerinden tanımlamak yanıltıcıdır. Asıl soru şudur: <strong>Mevcut altyapı, veriyi kabul edilebilir sürede ve maliyetle işleyebiliyor mu?</strong></p>

<p>Basitleştirilmiş biçimde işleme süresini şöyle düşünebiliriz:</p>

\[T \approx \frac{D}{R \times N} + O\]

<p>Burada $D$ veri miktarını, $R$ tek bir düğümün işleme hızını, $N$ paralel çalışan düğüm sayısını, $O$ ise ağ iletişimi ve koordinasyon maliyetini temsil eder. Daha fazla makine eklemek teoride süreyi azaltır; ancak dağıtık sistemlerde koordinasyon bedeli nedeniyle kazanç doğrusal değildir.</p>

<h2 id="3v-kuralı">3V Kuralı</h2>

<p>Büyük Verinin doğasını açıklayan klasik model üç temel özelliğe dayanır: <strong>Volume, Velocity ve Variety</strong>.</p>

<table>
  <thead>
    <tr>
      <th>Boyut</th>
      <th>Temel soru</th>
      <th>Örnek</th>
      <th>Oluşturduğu ihtiyaç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Volume</td>
      <td>Ne kadar veri var?</td>
      <td>Milyarlarca işlem kaydı</td>
      <td>Dağıtık depolama ve paralel hesaplama</td>
    </tr>
    <tr>
      <td>Velocity</td>
      <td>Veri ne hızla geliyor?</td>
      <td>Canlı ödeme hareketleri</td>
      <td>Akış işleme ve düşük gecikme</td>
    </tr>
    <tr>
      <td>Variety</td>
      <td>Veri hangi biçimlerde?</td>
      <td>JSON, video, tablo, metin</td>
      <td>Esnek şema ve farklı veri modelleri</td>
    </tr>
  </tbody>
</table>

<h3 id="volume-hacim">Volume: Hacim</h3>

<p>Hacim, tek bir sunucunun disk ve işlem kapasitesini aşan veri miktarıdır. Geleneksel yaklaşım daha güçlü bir makine satın almak, yani <strong>dikey ölçekleme</strong> yapmaktır. Büyük Veri sistemleri ise çoğunlukla yeni makineler ekleyerek <strong>yatay ölçekleme</strong> uygular. Veriler parçalara ayrılır, farklı düğümlerde saklanır ve hata ihtimaline karşı çoğaltılır.</p>

<h3 id="velocity-hız">Velocity: Hız</h3>

<p>Bazı verilerin değeri zamanla hızla azalır. Bir kredi kartı dolandırıcılığını ertesi gün bulmak faydalıdır; işlemi gerçekleşirken yakalamak ise çok daha değerlidir. Bu nedenle toplu işleme yerine Kafka veya Pulsar gibi mesajlaşma altyapılarıyla beslenen gerçek zamanlı veri akışları kullanılır.</p>

<p>Saniyede gelen olay sayısı $\lambda$, sistemin işleyebildiği olay sayısı $\mu$ ise sürdürülebilir bir akış için genel beklenti şöyledir:</p>

\[\lambda &lt; \mu\]

<p>Aksi durumda kuyruk sürekli büyür; gecikme artar ve sistem sonunda nefessiz kalır.</p>

<h3 id="variety-çeşitlilik">Variety: Çeşitlilik</h3>

<p>İlişkisel veritabanları düzenli satır ve sütunları sever. Oysa gerçek dünya CSV dosyaları, iç içe JSON belgeleri, fotoğraflar, loglar ve ses kayıtları üretir. Bu çeşitlilik; belge veritabanları, nesne depoları ve veri gölleri gibi esnek çözümleri gerekli kılar.</p>

<p>Aşağıdaki Python örneği, farklı yapıdaki olayları ortak bir işleme adımında normalize eder:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>

<span class="k">def</span> <span class="nf">normalize</span><span class="p">(</span><span class="n">event</span><span class="p">):</span>
    <span class="k">return</span> <span class="p">{</span>
        <span class="sh">"</span><span class="s">user_id</span><span class="sh">"</span><span class="p">:</span> <span class="n">event</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="sh">"</span><span class="s">user_id</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">anonymous</span><span class="sh">"</span><span class="p">),</span>
        <span class="sh">"</span><span class="s">event_type</span><span class="sh">"</span><span class="p">:</span> <span class="n">event</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="sh">"</span><span class="s">type</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">unknown</span><span class="sh">"</span><span class="p">),</span>
        <span class="sh">"</span><span class="s">timestamp</span><span class="sh">"</span><span class="p">:</span> <span class="n">event</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="sh">"</span><span class="s">timestamp</span><span class="sh">"</span><span class="p">,</span> <span class="n">datetime</span><span class="p">.</span><span class="nf">now</span><span class="p">().</span><span class="nf">isoformat</span><span class="p">()),</span>
        <span class="sh">"</span><span class="s">payload</span><span class="sh">"</span><span class="p">:</span> <span class="n">event</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="sh">"</span><span class="s">payload</span><span class="sh">"</span><span class="p">,</span> <span class="p">{})</span>
    <span class="p">}</span>
</code></pre></div></div>

<p>Bu fonksiyon eksik alanlara varsayılan değerler atar ve değişken kaynaklardan gelen kayıtları ortak bir biçime yaklaştırır. Gerçek sistemlerde buna doğrulama, şema sürümleme ve hatalı kayıt yönetimi de eklenir.</p>

<h2 id="geleneksel-sistemden-yeni-nesil-mimariye">Geleneksel Sistemden Yeni Nesil Mimariye</h2>

<table>
  <thead>
    <tr>
      <th>Geleneksel yaklaşım</th>
      <th>Büyük Veri yaklaşımı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tek ve güçlü sunucu</td>
      <td>Dağıtık makine kümesi</td>
    </tr>
    <tr>
      <td>Önceden tanımlı katı şema</td>
      <td>Gerektiğinde yorumlanan esnek şema</td>
    </tr>
    <tr>
      <td>Periyodik toplu sorgular</td>
      <td>Toplu ve gerçek zamanlı işleme</td>
    </tr>
    <tr>
      <td>Merkezi hata noktası</td>
      <td>Çoğaltma ve hata toleransı</td>
    </tr>
  </tbody>
</table>

<p>Hadoop, Spark, Kafka ve NoSQL sistemleri birer moda sözcük değil; 3V’nin oluşturduğu teknik baskılara verilmiş farklı cevaplardır. Bununla birlikte her proje Büyük Veri projesi değildir. Küçük bir veri kümesini karmaşık kümelerde çalıştırmak, roketle markete gitmeye benzer. Doğru yaklaşım; hacmi, gecikme beklentisini, veri biçimlerini ve maliyeti ölçerek en sade yeterli mimariyi seçmektir. Büyük Verinin özü teknoloji yığını değil, verinin doğasına uygun ölçeklenebilir düşünme biçimidir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Büyük Veri" /><category term="3V Kuralı" /><category term="Veri Mühendisliği" /><summary type="html"><![CDATA[Bir e-ticaret sitesindeki tıklamalar, akıllı saatlerin ölçtüğü nabız değerleri, sosyal medya paylaşımları ve fabrikalardaki sensör kayıtları… Modern dünyada veri yalnızca çoğalmıyor; hızlanıyor ve biçim değiştiriyor. Büyük Veri (Big Data), tek başına “çok fazla veri” anlamına gelmez. Geleneksel sistemlerin makul süre ve maliyetle saklamakta, işleyip analiz etmekte zorlandığı veri kümelerini ve bu sorunu çözmek için geliştirilen yöntemleri ifade eder.]]></summary></entry><entry><title type="html">Dağıtık Ekiplerde Ortak Bir “Şimdi” Nasıl Yaratılır?</title><link href="https://sonsuzus.github.io/posts/dagitik-ekiplerde-ortak-bir-simdi-nasil-yaratilir/" rel="alternate" type="text/html" title="Dağıtık Ekiplerde Ortak Bir “Şimdi” Nasıl Yaratılır?" /><published>2026-08-02T00:00:00+00:00</published><updated>2026-08-02T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/dagitik-ekiplerde-ortak-bir-simdi-nasil-yaratilir</id><content type="html" xml:base="https://sonsuzus.github.io/posts/dagitik-ekiplerde-ortak-bir-simdi-nasil-yaratilir/"><![CDATA[<p>Uzaktan çalışma ofisi ortadan kaldırırken zamanı da görünmez biçimde yeniden tasarladı. İstanbul’daki bir geliştirici güne başlarken San Francisco’daki ekip arkadaşı uyuyor, Tokyo’daki tasarımcı ise bilgisayarını kapatıyor olabilir. Böyle bir ekipte “hemen konuşalım” masum bir öneri değil, coğrafi bir ayrıcalıktır. Ortak bir “şimdi” yaratmak, herkesi aynı anda çevrim içi tutmak değil; eşzamanlı ve eşzamansız çalışmayı bilinçli biçimde dengelemektir.
``</p>

<h2 id="saat-aynı-deneyim-farklı">Saat aynı, deneyim farklı</h2>

<p>Saat dilimleri teknik olarak UTC’ye göre tanımlanan ofsetlerdir. Bir kişinin yerel zamanı basitçe şöyle gösterilebilir:</p>

\[T_{yerel} = T_{UTC} + O\]

<p>Burada $O$, saat dilimi ofsetidir. Ancak insan deneyimi bu formülden daha karmaşıktır. Saat 09.00’da yapılan bir toplantı bir çalışan için kahveyle başlayan sakin bir sabah, diğeri için aile yemeğinin ortası olabilir. Üstelik yaz saati uygulamaları nedeniyle ofsetler yıl boyunca sabit kalmayabilir.</p>

<p>Dağıtık ekiplerde zamanın üç farklı biçimi vardır:</p>

<table>
  <thead>
    <tr>
      <th>Zaman biçimi</th>
      <th>Anlamı</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kronolojik zaman</td>
      <td>Takvim ve saatle ölçülen zaman</td>
      <td>Sprint pazartesi başlar</td>
    </tr>
    <tr>
      <td>Biyolojik zaman</td>
      <td>Bedenin uyku ve enerji ritmi</td>
      <td>Gece toplantısında odak düşer</td>
    </tr>
    <tr>
      <td>Sosyal zaman</td>
      <td>Aile ve toplum düzeni</td>
      <td>Akşam yemeği, okul çıkışı</td>
    </tr>
  </tbody>
</table>

<p>İyi bir çalışma düzeni yalnızca kronolojik zamanı optimize etmez; diğer iki katmanı da hesaba katar.</p>

<h2 id="eşzamanlılık-bir-spektrumdur">Eşzamanlılık bir spektrumdur</h2>

<p>Ofis kültürü çoğu zaman üretkenliği aynı anda bulunmakla eşleştirir. Oysa yazılım ekiplerinde işlerin önemli bir bölümü eşzamansız yürütülebilir. Kod incelemesi, teknik karar kaydı ve durum güncellemesi için herkesin aynı görüntülü görüşmede bulunması gerekmez.</p>

<table>
  <thead>
    <tr>
      <th>Eşzamanlı çalışma</th>
      <th>Eşzamansız çalışma</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Hızlı geri bildirim sağlar</td>
      <td>Derin çalışmayı destekler</td>
    </tr>
    <tr>
      <td>Belirsiz konuları çözmekte etkilidir</td>
      <td>Saat dilimlerinden bağımsızdır</td>
    </tr>
    <tr>
      <td>Toplantı yorgunluğu yaratabilir</td>
      <td>Yanıt gecikmesi oluşturabilir</td>
    </tr>
    <tr>
      <td>Beyin fırtınasına uygundur</td>
      <td>Kalıcı ve aranabilir kayıt üretir</td>
    </tr>
  </tbody>
</table>

<p>Buradaki amaç yöntemlerden birini seçmek değil, iletişimin gecikme maliyetine göre seçim yapmaktır. Bir mesajın bekleme süresi $L$, ekip üyeleri arasındaki saat farkı $D$ ve günlük ortak çalışma penceresi $W$ ile ilişkili düşünülebilir:</p>

\[L \approx \max(0, D - W)\]

<p>Ortak pencere küçüldükçe soruların bir sonraki güne taşınma ihtimali artar. Bu nedenle iyi yazılmış bir mesaj; bağlamı, beklenen çıktıyı ve son tarihi birlikte içermelidir.</p>

<h2 id="ortak-pencereyi-adil-biçimde-bulmak">Ortak pencereyi adil biçimde bulmak</h2>

<p>Aşağıdaki Python örneği, ekip üyelerinin UTC cinsinden çalışma aralıklarının kesişimini hesaplar:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">typing</span> <span class="kn">import</span> <span class="n">List</span><span class="p">,</span> <span class="n">Tuple</span>

<span class="k">def</span> <span class="nf">ortak_pencere</span><span class="p">(</span><span class="n">araliklar</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Tuple</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">int</span><span class="p">]])</span> <span class="o">-&gt;</span> <span class="n">Tuple</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">int</span><span class="p">]</span> <span class="o">|</span> <span class="bp">None</span><span class="p">:</span>
    <span class="n">baslangic</span> <span class="o">=</span> <span class="nf">max</span><span class="p">(</span><span class="n">aralik</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">aralik</span> <span class="ow">in</span> <span class="n">araliklar</span><span class="p">)</span>
    <span class="n">bitis</span> <span class="o">=</span> <span class="nf">min</span><span class="p">(</span><span class="n">aralik</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">aralik</span> <span class="ow">in</span> <span class="n">araliklar</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">baslangic</span> <span class="o">&gt;=</span> <span class="n">bitis</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">None</span>
    <span class="k">return</span> <span class="n">baslangic</span><span class="p">,</span> <span class="n">bitis</span>

<span class="n">calisma_saatleri</span> <span class="o">=</span> <span class="p">[(</span><span class="mi">6</span><span class="p">,</span> <span class="mi">14</span><span class="p">),</span> <span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">16</span><span class="p">),</span> <span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">20</span><span class="p">)]</span>
<span class="nf">print</span><span class="p">(</span><span class="nf">ortak_pencere</span><span class="p">(</span><span class="n">calisma_saatleri</span><span class="p">))</span>  <span class="c1"># (12, 14)
</span></code></pre></div></div>

<p>Fonksiyon en geç başlangıç ile en erken bitişi karşılaştırır. Sonuç <code class="language-plaintext highlighter-rouge">(12, 14)</code> ise ekip UTC 12.00–14.00 arasında buluşabilir. Ancak matematiksel kesişim otomatik olarak adalet anlamına gelmez. Sürekli aynı kişinin sabahın köründe toplantıya katılması, zaman yükünü görünmez biçimde ona aktarır. Kritik toplantı saatlerini dönüşümlü planlamak daha adildir.</p>

<h2 id="şimdiyi-bir-protokole-dönüştürmek">“Şimdi”yi bir protokole dönüştürmek</h2>

<p>Sağlıklı bir dağıtık ekip şu pratikleri benimseyebilir:</p>

<ul>
  <li>Tarih ve saatleri yerel kısaltmalar yerine UTC ile belirtmek.</li>
  <li>Kararları toplantı sonrasında yazılı olarak kaydetmek.</li>
  <li>Mesajlarda “acil”, “bugün” ve “bu hafta” seviyelerini ayırmak.</li>
  <li>Çevrim içi durumunu anında yanıt zorunluluğu saymamak.</li>
  <li>Ortak saatleri kararlar için, bireysel saatleri üretim için korumak.</li>
  <li>Toplantı yükünü ve uygunsuz saatleri ekip içinde dönüşümlü dağıtmak.</li>
</ul>

<p>Sonuçta ortak bir “şimdi”, duvardaki saatlerin eşitlenmesi değildir. Ekibin ne zaman birlikte düşünmesi, ne zaman bağımsız ilerlemesi ve ne kadar gecikmeyi kabul etmesi gerektiğine dair paylaşılan bir protokoldür. Dağıtık ekipler zamanı yönetmekten çok, zaman hakkında güven inşa eder. İyi tasarlanmış bir düzende iş güneşi takip eder; çalışanlar ise onu kovalamak zorunda kalmaz.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="uzaktan çalışma" /><category term="dağıtık ekipler" /><category term="saat dilimleri" /><summary type="html"><![CDATA[Uzaktan çalışma ofisi ortadan kaldırırken zamanı da görünmez biçimde yeniden tasarladı. İstanbul’daki bir geliştirici güne başlarken San Francisco’daki ekip arkadaşı uyuyor, Tokyo’daki tasarımcı ise bilgisayarını kapatıyor olabilir. Böyle bir ekipte “hemen konuşalım” masum bir öneri değil, coğrafi bir ayrıcalıktır. Ortak bir “şimdi” yaratmak, herkesi aynı anda çevrim içi tutmak değil; eşzamanlı ve eşzamansız çalışmayı bilinçli biçimde dengelemektir.]]></summary></entry><entry><title type="html">ETL Süreçleriyle Ham Veriden Güvenilir Veri Boru Hatlarına</title><link href="https://sonsuzus.github.io/posts/etl-surecleriyle-ham-veriden-guvenilir-veri-boru-hatlarina/" rel="alternate" type="text/html" title="ETL Süreçleriyle Ham Veriden Güvenilir Veri Boru Hatlarına" /><published>2026-08-02T00:00:00+00:00</published><updated>2026-08-02T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/etl-surecleriyle-ham-veriden-guvenilir-veri-boru-hatlarina</id><content type="html" xml:base="https://sonsuzus.github.io/posts/etl-surecleriyle-ham-veriden-guvenilir-veri-boru-hatlarina/"><![CDATA[<p>Bir e-ticaret şirketinde siparişler PostgreSQL’de, reklam verileri bir API’de, müşteri yorumları JSON dosyalarında tutulabilir. Analiz ekibinin bütün bunları tek tek toplaması hem zaman kaybettirir hem de hata üretir. ETL süreçleri, dağınık ham veriyi otomatik biçimde çekip temizleyerek analiz edilmeye hazır, güvenilir bir veri kaynağına dönüştürür.</p>

<p>``</p>

<h2 id="etl-nedir">ETL nedir?</h2>

<p>ETL; <strong>Extract, Transform, Load</strong> kelimelerinin baş harflerinden oluşur. Bir veri boru hattı ise verinin kaynaktan hedefe düzenli, izlenebilir ve mümkünse hatalara dayanıklı biçimde akmasını sağlayan daha geniş otomasyon sistemidir.</p>

<table>
  <thead>
    <tr>
      <th>Aşama</th>
      <th>Temel soru</th>
      <th>Örnek işlem</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Extract</td>
      <td>Veri nereden alınacak?</td>
      <td>API, veritabanı veya CSV okuma</td>
    </tr>
    <tr>
      <td>Transform</td>
      <td>Veri nasıl kullanılabilir hâle gelecek?</td>
      <td>Temizleme, birleştirme, doğrulama</td>
    </tr>
    <tr>
      <td>Load</td>
      <td>Veri nereye yazılacak?</td>
      <td>Veri ambarına veya data lake’e yükleme</td>
    </tr>
  </tbody>
</table>

<h3 id="1-extract-veriyi-kaynağından-çekmek">1. Extract: Veriyi kaynağından çekmek</h3>

<p>Çıkarma aşamasında ilişkisel veritabanları, uygulama günlükleri, sensörler, bulut depoları ve harici API’ler gibi farklı kaynaklara bağlanılır. Buradaki önemli karar, verinin tamamının mı yoksa yalnızca değişen bölümünün mü alınacağıdır.</p>

<p>Tam yükte her çalıştırmada $N$ kayıt okunur. Artımlı yükte yalnızca değişen $\Delta N$ kayıt işlenir. Genellikle $\Delta N \ll N$ olduğundan artımlı yaklaşım ağ ve işlem maliyetini ciddi ölçüde azaltır. Bunun için zaman damgası, artan kimlik veya CDC (Change Data Capture) kullanılabilir.</p>

<h3 id="2-transform-ham-veriyi-anlamlı-hâle-getirmek">2. Transform: Ham veriyi anlamlı hâle getirmek</h3>

<p>Dönüştürme, ETL’in mutfağıdır. Eksik alanlar ele alınır, tarih biçimleri standartlaştırılır, tekrar eden kayıtlar silinir ve iş kuralları uygulanır. Örneğin toplam sipariş geliri şu şekilde hesaplanabilir:</p>

\[Gelir = \sum_{i=1}^{n} adet_i \times birim\_fiyat_i\]

<p>Ancak matematik doğru olsa bile para birimleri farklıysa sonuç yanıltıcıdır. Bu nedenle dönüşüm yalnızca kod yazmak değil, verinin iş bağlamını anlamaktır.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">pandas</span> <span class="k">as</span> <span class="n">pd</span>

<span class="k">def</span> <span class="nf">transform_orders</span><span class="p">(</span><span class="n">df</span><span class="p">:</span> <span class="n">pd</span><span class="p">.</span><span class="n">DataFrame</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">pd</span><span class="p">.</span><span class="n">DataFrame</span><span class="p">:</span>
    <span class="c1"># Kimliği olmayan kayıtlar güvenilir biçimde eşleştirilemez.
</span>    <span class="n">df</span> <span class="o">=</span> <span class="n">df</span><span class="p">.</span><span class="nf">dropna</span><span class="p">(</span><span class="n">subset</span><span class="o">=</span><span class="p">[</span><span class="sh">"</span><span class="s">order_id</span><span class="sh">"</span><span class="p">])</span>
    <span class="n">df</span> <span class="o">=</span> <span class="n">df</span><span class="p">.</span><span class="nf">drop_duplicates</span><span class="p">(</span><span class="n">subset</span><span class="o">=</span><span class="p">[</span><span class="sh">"</span><span class="s">order_id</span><span class="sh">"</span><span class="p">])</span>

    <span class="c1"># Farklı tarih gösterimlerini ortak tipe dönüştürür.
</span>    <span class="n">df</span><span class="p">[</span><span class="sh">"</span><span class="s">order_date</span><span class="sh">"</span><span class="p">]</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nf">to_datetime</span><span class="p">(</span><span class="n">df</span><span class="p">[</span><span class="sh">"</span><span class="s">order_date</span><span class="sh">"</span><span class="p">],</span> <span class="n">errors</span><span class="o">=</span><span class="sh">"</span><span class="s">coerce</span><span class="sh">"</span><span class="p">)</span>
    <span class="n">df</span><span class="p">[</span><span class="sh">"</span><span class="s">total_amount</span><span class="sh">"</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="sh">"</span><span class="s">quantity</span><span class="sh">"</span><span class="p">]</span> <span class="o">*</span> <span class="n">df</span><span class="p">[</span><span class="sh">"</span><span class="s">unit_price</span><span class="sh">"</span><span class="p">]</span>

    <span class="c1"># Geçersiz veya negatif tutarları dışarıda bırakır.
</span>    <span class="k">return</span> <span class="n">df</span><span class="p">[</span><span class="n">df</span><span class="p">[</span><span class="sh">"</span><span class="s">total_amount</span><span class="sh">"</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">]</span>
</code></pre></div></div>

<p>Bu fonksiyon temel temizlik, tip dönüşümü ve gelir hesaplamasını tek adımda gerçekleştirir. Gerçek sistemlerde kurallar testlerle desteklenmelidir.</p>

<h3 id="3-load-sonucu-hedefe-taşımak">3. Load: Sonucu hedefe taşımak</h3>

<p>Temizlenen veri; Snowflake, BigQuery, Redshift gibi veri ambarlarına veya bir data lake’e yüklenebilir. Yükleme tam yenileme, ekleme ya da <strong>upsert</strong> yöntemiyle yapılabilir. Upsert, mevcut kaydı günceller; yoksa yeni kayıt ekler.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Avantaj</th>
      <th>Dezavantaj</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Batch</td>
      <td>Basit ve ekonomik</td>
      <td>Veri gecikmeli gelir</td>
    </tr>
    <tr>
      <td>Streaming</td>
      <td>Düşük gecikme</td>
      <td>İşletmesi daha karmaşıktır</td>
    </tr>
    <tr>
      <td>ETL</td>
      <td>Hedefe temiz veri gider</td>
      <td>Dönüşüm altyapısı gerekir</td>
    </tr>
    <tr>
      <td>ELT</td>
      <td>Ham veri korunur, esnektir</td>
      <td>Güçlü hedef sistem ister</td>
    </tr>
  </tbody>
</table>

<h2 id="sağlam-bir-pipeline-nasıl-tasarlanır">Sağlam bir pipeline nasıl tasarlanır?</h2>

<p>İyi bir veri boru hattı yalnızca başarılı durumda çalışmamalıdır. Aynı işlem tekrar çalıştırıldığında sonucu bozmayan <strong>idempotent</strong> adımlar tasarlanmalı; başarısız kayıtlar ayrı bir hata kuyruğuna gönderilmelidir. Loglama, veri kalite kontrolleri, şema doğrulama ve uyarılar da sistemin vazgeçilmez parçalarıdır.</p>

<p>Airflow, Dagster veya Prefect görevlerin sırasını ve zamanlamasını yönetebilir. Kafka gerçek zamanlı veri akışında, dbt ise SQL tabanlı dönüşümlerde öne çıkar. Araç seçiminden önce veri hacmi, gecikme beklentisi, maliyet ve ekip deneyimi değerlendirilmelidir.</p>

<p>Sonuç olarak ETL, veriyi A noktasından B noktasına taşıyan basit bir kargo hizmeti değildir. Kaynakları uzlaştıran, kaliteyi koruyan ve analitik kararların güvenilir temelini oluşturan otomatik bir üretim hattıdır. Boru hattı görünmez çalıştığında herkes mutludur; durduğunda ise neden veri mühendislerine ihtiyaç duyulduğu hemen anlaşılır!</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="ETL" /><category term="veri mühendisliği" /><category term="data pipeline" /><summary type="html"><![CDATA[Bir e-ticaret şirketinde siparişler PostgreSQL’de, reklam verileri bir API’de, müşteri yorumları JSON dosyalarında tutulabilir. Analiz ekibinin bütün bunları tek tek toplaması hem zaman kaybettirir hem de hata üretir. ETL süreçleri, dağınık ham veriyi otomatik biçimde çekip temizleyerek analiz edilmeye hazır, güvenilir bir veri kaynağına dönüştürür.]]></summary></entry><entry><title type="html">Gerçek Zamanlı Veri Akışı ve Apache Kafka ile Kayıpsız İşleme</title><link href="https://sonsuzus.github.io/posts/gercek-zamanli-veri-akisi-ve-apache-kafka-ile-kayipsiz-isleme/" rel="alternate" type="text/html" title="Gerçek Zamanlı Veri Akışı ve Apache Kafka ile Kayıpsız İşleme" /><published>2026-08-02T00:00:00+00:00</published><updated>2026-08-02T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/gercek-zamanli-veri-akisi-ve-apache-kafka-ile-kayipsiz-isleme</id><content type="html" xml:base="https://sonsuzus.github.io/posts/gercek-zamanli-veri-akisi-ve-apache-kafka-ile-kayipsiz-isleme/"><![CDATA[<p>Bir web sitesindeki tıklamalar, sunucu logları veya fabrikadaki sıcaklık sensörleri kimsenin “Kaydet” düğmesine basmasını beklemez. Veriler saniyede yüzlerce, hatta milyonlarca olay hâlinde kesintisiz akar. Gerçek zamanlı veri akışı, bu olayları oluştukları anda yakalayıp güvenilir biçimde taşıma ve gecikmeyi mümkün olduğunca düşük tutarak işleme yaklaşımıdır. Apache Kafka ise bu yoğun veri trafiğinin ortasında çalışan dayanıklı bir dijital konveyör bandı gibidir.</p>

<p>``</p>

<h2 id="streaming-neden-farklıdır">Streaming neden farklıdır?</h2>

<p>Geleneksel toplu işlemede veriler önce biriktirilir, ardından belirli aralıklarla işlenir. Streaming sistemlerinde ise teorik olarak sonu bulunmayan bir olay dizisi vardır:</p>

\[S = \{e_1, e_2, e_3, \ldots\}\]

<p>Her olayın bir değeri, zaman damgası ve çoğunlukla anahtarı bulunur. Sistem, olayları bekletmeden işlerken ani trafik artışlarına da dayanmalıdır. Üretim hızı $P$, tüketim hızı $C$ ile gösterilirse sürdürülebilir çalışma için genel beklenti şudur:</p>

\[C \geq P\]

<p>Eğer $P &gt; C$ olursa olaylar hemen kaybolmak zorunda değildir; Kafka bunları diskte tutar. Ancak tüketicinin geride kaldığı miktar, yani <strong>consumer lag</strong>, büyür. Bu tamponlama yeteneği üreticilerle tüketicilerin birbirinden bağımsız ölçeklenmesini sağlar.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Batch işleme</th>
      <th>Streaming işleme</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Veri yapısı</td>
      <td>Sonlu veri kümesi</td>
      <td>Sürekli olay dizisi</td>
    </tr>
    <tr>
      <td>Gecikme</td>
      <td>Dakika veya saat</td>
      <td>Milisaniye veya saniye</td>
    </tr>
    <tr>
      <td>Kullanım</td>
      <td>Günlük rapor</td>
      <td>Anlık alarm, dolandırıcılık tespiti</td>
    </tr>
    <tr>
      <td>Zorluk</td>
      <td>Büyük hacimli hesaplama</td>
      <td>Sıralama, tekrar ve gecikmiş olaylar</td>
    </tr>
  </tbody>
</table>

<h2 id="kafkanın-temel-parçaları">Kafka’nın temel parçaları</h2>

<p>Kafka’da üreticiler (<strong>producer</strong>) olayları <strong>topic</strong> adı verilen mantıksal kanallara gönderir. Topic’ler ölçeklenebilmek için <strong>partition</strong> bölümlerine ayrılır. Her partition yalnızca sonuna ekleme yapılan sıralı bir kayıttır. Olaylar silinmek yerine yapılandırılmış saklama süresi boyunca diskte korunur.</p>

<p>Bir olayın anahtarı aynı kaldığında genellikle aynı partition seçilir. Böylece örneğin aynı sensöre ait ölçümlerin sırası korunabilir. Fakat Kafka tüm topic genelinde mutlak sıra garantisi vermez; garanti partition düzeyindedir.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Görevi</th>
      <th>Benzetme</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Producer</td>
      <td>Olay yayımlar</td>
      <td>Kargo gönderen kişi</td>
    </tr>
    <tr>
      <td>Topic</td>
      <td>Olayları sınıflandırır</td>
      <td>Kargo hattı</td>
    </tr>
    <tr>
      <td>Partition</td>
      <td>Paralellik ve sıralama sağlar</td>
      <td>Ayrı taşıma şeridi</td>
    </tr>
    <tr>
      <td>Broker</td>
      <td>Veriyi saklayan Kafka sunucusudur</td>
      <td>Dağıtım merkezi</td>
    </tr>
    <tr>
      <td>Consumer group</td>
      <td>İş yükünü paylaşır</td>
      <td>Teslimat ekibi</td>
    </tr>
    <tr>
      <td>Offset</td>
      <td>Okuma konumunu belirtir</td>
      <td>Kitap ayracı</td>
    </tr>
  </tbody>
</table>

<h2 id="basit-bir-sensör-üreticisi">Basit bir sensör üreticisi</h2>

<p>Aşağıdaki Python kodu, sıcaklık ölçümlerini JSON olarak Kafka’ya yollar. <code class="language-plaintext highlighter-rouge">sensor_id</code> anahtar olarak kullanıldığı için aynı sensörün olayları aynı partition’da sıralanabilir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">json</span>
<span class="kn">import</span> <span class="n">random</span>
<span class="kn">import</span> <span class="n">time</span>
<span class="kn">from</span> <span class="n">kafka</span> <span class="kn">import</span> <span class="n">KafkaProducer</span>

<span class="n">producer</span> <span class="o">=</span> <span class="nc">KafkaProducer</span><span class="p">(</span>
    <span class="n">bootstrap_servers</span><span class="o">=</span><span class="sh">"</span><span class="s">localhost:9092</span><span class="sh">"</span><span class="p">,</span>
    <span class="n">value_serializer</span><span class="o">=</span><span class="k">lambda</span> <span class="n">value</span><span class="p">:</span> <span class="n">json</span><span class="p">.</span><span class="nf">dumps</span><span class="p">(</span><span class="n">value</span><span class="p">).</span><span class="nf">encode</span><span class="p">(</span><span class="sh">"</span><span class="s">utf-8</span><span class="sh">"</span><span class="p">)</span>
<span class="p">)</span>

<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
    <span class="n">event</span> <span class="o">=</span> <span class="p">{</span>
        <span class="sh">"</span><span class="s">sensor_id</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">sensor-42</span><span class="sh">"</span><span class="p">,</span>
        <span class="sh">"</span><span class="s">temperature</span><span class="sh">"</span><span class="p">:</span> <span class="nf">round</span><span class="p">(</span><span class="n">random</span><span class="p">.</span><span class="nf">uniform</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="mi">35</span><span class="p">),</span> <span class="mi">2</span><span class="p">),</span>
        <span class="sh">"</span><span class="s">timestamp</span><span class="sh">"</span><span class="p">:</span> <span class="n">time</span><span class="p">.</span><span class="nf">time</span><span class="p">()</span>
    <span class="p">}</span>
    <span class="n">producer</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span>
        <span class="sh">"</span><span class="s">temperature-events</span><span class="sh">"</span><span class="p">,</span>
        <span class="n">key</span><span class="o">=</span><span class="n">event</span><span class="p">[</span><span class="sh">"</span><span class="s">sensor_id</span><span class="sh">"</span><span class="p">].</span><span class="nf">encode</span><span class="p">(</span><span class="sh">"</span><span class="s">utf-8</span><span class="sh">"</span><span class="p">),</span>
        <span class="n">value</span><span class="o">=</span><span class="n">event</span>
    <span class="p">)</span>
    <span class="n">time</span><span class="p">.</span><span class="nf">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">send</code> işlemi asenkrondur; yüksek performans için olaylar paketlenebilir. Kritik sistemlerde <code class="language-plaintext highlighter-rouge">acks="all"</code> kullanmak, lider ve gerekli replikalar doğrulamadan gönderimi başarılı saymamak açısından önemlidir.</p>

<h2 id="kayıpsızlık-gerçekten-ne-demek">Kayıpsızlık gerçekten ne demek?</h2>

<p>Kafka veriyi çoğaltarak broker arızalarına karşı korur, fakat uçtan uca güvenilirlik yalnızca Kafka ayarı değildir. Üretici tekrar denemeleri, <code class="language-plaintext highlighter-rouge">acks</code>, replikasyon faktörü ve tüketicinin offset yönetimi birlikte tasarlanmalıdır.</p>

<ul>
  <li><strong>At-most-once:</strong> Olay en fazla bir kez işlenir; kayıp mümkündür.</li>
  <li><strong>At-least-once:</strong> Kayıp önlenir, fakat tekrar işleme olabilir.</li>
  <li><strong>Exactly-once:</strong> İşlem sonucu mantıksal olarak yalnızca bir kez uygulanır.</li>
</ul>

<p>Pratikte <code class="language-plaintext highlighter-rouge">at-least-once</code> ve <strong>idempotent</strong> tüketiciler güçlü bir çözümdür. Aynı <code class="language-plaintext highlighter-rouge">event_id</code> ikinci kez geldiğinde veritabanı işlemi sonucu değiştirmiyorsa tekrarlar zararsızlaşır. Kafka Transactions ve Kafka Streams ise uygun senaryolarda exactly-once semantiğini destekler.</p>

<p>Sonuç olarak Kafka yalnızca hızlı bir mesaj kuyruğu değil; olayları kalıcı biçimde saklayan, yeniden oynatılabilir ve dağıtık bir olay günlüğüdür. Web loglarından sensör alarmlarına kadar sağlam bir streaming mimarisi; partition planı, lag takibi, replikasyon, şema yönetimi ve idempotent işleme birlikte düşünüldüğünde gerçekten güvenilir hâle gelir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Apache Kafka" /><category term="streaming" /><category term="gerçek zamanlı veri" /><summary type="html"><![CDATA[Bir web sitesindeki tıklamalar, sunucu logları veya fabrikadaki sıcaklık sensörleri kimsenin “Kaydet” düğmesine basmasını beklemez. Veriler saniyede yüzlerce, hatta milyonlarca olay hâlinde kesintisiz akar. Gerçek zamanlı veri akışı, bu olayları oluştukları anda yakalayıp güvenilir biçimde taşıma ve gecikmeyi mümkün olduğunca düşük tutarak işleme yaklaşımıdır. Apache Kafka ise bu yoğun veri trafiğinin ortasında çalışan dayanıklı bir dijital konveyör bandı gibidir.]]></summary></entry><entry><title type="html">Petabaytları Parçalara Bölmek: HDFS ve Hadoop Mimarisi</title><link href="https://sonsuzus.github.io/posts/petabaytlari-parcalara-bolmek-hdfs-ve-hadoop-mimarisi/" rel="alternate" type="text/html" title="Petabaytları Parçalara Bölmek: HDFS ve Hadoop Mimarisi" /><published>2026-08-02T00:00:00+00:00</published><updated>2026-08-02T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/petabaytlari-parcalara-bolmek-hdfs-ve-hadoop-mimarisi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/petabaytlari-parcalara-bolmek-hdfs-ve-hadoop-mimarisi/"><![CDATA[<p>Bir petabayt veriyi dizüstü bilgisayarınıza kopyalamaya çalıştığınızı düşünün. Diskin itiraz etmesi bir yana, işlem tamamlanmadan bilgisayarınız emekli olabilir! Hadoop Dağıtık Dosya Sistemi, yani HDFS, bu problemi devasa ve pahalı bir sunucu almak yerine veriyi yüzlerce sıradan makineye dağıtarak çözer. Üstelik disk arızalarını istisna değil, sistemin doğal bir parçası kabul eder.
``</p>
<h2 id="hdfs-neden-ortaya-çıktı">HDFS neden ortaya çıktı?</h2>

<p>Geleneksel dosya sistemleri, çoğunlukla tek makinenin disklerini yönetir. Veri büyüklüğü terabaytlardan petabaytlara çıktığında kapasite, aktarım hızı ve hata toleransı ciddi sorunlara dönüşür. HDFS’nin temel düşüncesi basittir: <strong>Veriyi hesaplamaya taşımak yerine hesaplamayı veriye taşı.</strong></p>

<p>Bir dosya küçük bloklara ayrılır ve farklı bilgisayarlarda saklanır. Toplam kullanılabilir kapasite kabaca şöyle düşünülebilir:</p>

\[C_{toplam} = \frac{N \times D}{R}\]

<p>Burada $N$ düğüm sayısını, $D$ her düğümün disk kapasitesini, $R$ ise çoğaltma faktörünü gösterir. Örneğin 100 makinenin her birinde 10 TB alan ve çoğaltma faktörü 3 ise kullanılabilir kapasite yaklaşık $333$ TB olur.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Geleneksel dosya sistemi</th>
      <th>HDFS</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Depolama</td>
      <td>Tek sunucu ağırlıklı</td>
      <td>Çok sayıda düğüme dağıtılmış</td>
    </tr>
    <tr>
      <td>Hata yaklaşımı</td>
      <td>Arıza olağan dışıdır</td>
      <td>Arıza beklenen bir durumdur</td>
    </tr>
    <tr>
      <td>Dosya tipi</td>
      <td>Küçük ve büyük dosyalar</td>
      <td>Büyük dosyalar için ideal</td>
    </tr>
    <tr>
      <td>Erişim modeli</td>
      <td>Düşük gecikme</td>
      <td>Yüksek aktarım kapasitesi</td>
    </tr>
    <tr>
      <td>Ölçekleme</td>
      <td>Daha güçlü sunucu</td>
      <td>Daha fazla sıradan sunucu</td>
    </tr>
  </tbody>
</table>

<h2 id="namenode-ve-datanode-rolleri">NameNode ve DataNode rolleri</h2>

<p>HDFS mimarisinin koordinatörü <strong>NameNode</strong>‘dur. Dosya adlarını, klasörleri, izinleri ve hangi bloğun hangi makinede bulunduğunu takip eder. Ancak gerçek dosya içeriğini saklamaz. Onu, işçiler gibi çalışan <strong>DataNode</strong> düğümleri depolar.</p>

<p>Bir istemci dosya okumak istediğinde önce NameNode’a başvurur. NameNode uygun DataNode adreslerini bildirir; veri daha sonra doğrudan DataNode’lardan alınır. Böylece NameNode, bütün verinin içinden geçtiği bir darboğaza dönüşmez.</p>

<p>DataNode’lar düzenli olarak <strong>heartbeat</strong> mesajları göndererek hayatta olduklarını bildirir. Bir düğüm uzun süre sessiz kalırsa NameNode onu arızalı sayar ve eksilen kopyaların başka düğümlerde oluşturulmasını ister.</p>

<h2 id="bloklar-ve-çoğaltma">Bloklar ve çoğaltma</h2>

<p>HDFS dosyaları genellikle 128 MB gibi büyük bloklara böler. Diyelim ki 300 MB büyüklüğünde bir dosyamız var. Bu dosya 128 MB, 128 MB ve 44 MB olmak üzere üç bloğa ayrılır. Çoğaltma faktörü 3 olduğunda her blok üç farklı DataNode üzerinde tutulur.</p>

<p>Bir bloğun kullanılabilir olma olasılığı, bağımsız düğüm arızası varsayımıyla şu şekilde ifade edilebilir:</p>

\[P_{erişim} = 1 - p^R\]

<p>$p$ tek düğümün arıza olasılığıdır. $p=0.1$ ve $R=3$ için bloğun bütün kopyalarını kaybetme olasılığı yalnızca $0.001$ olur. Elbette gerçek sistemlerde aynı rack veya ağ anahtarının çökmesi gibi ilişkili arızalar da vardır. Bu nedenle HDFS, kopyaları farklı rack’lere dağıtan <strong>rack awareness</strong> yaklaşımını kullanır.</p>

<h2 id="dosya-yükleme-akışı">Dosya yükleme akışı</h2>

<p>Aşağıdaki komut yerel bir dosyayı HDFS’ye gönderir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>hdfs dfs <span class="nt">-mkdir</span> <span class="nt">-p</span> /veri/loglar
hdfs dfs <span class="nt">-put</span> uygulama.log /veri/loglar/
hdfs dfs <span class="nt">-ls</span> /veri/loglar
</code></pre></div></div>

<p>İlk komut hedef klasörü oluşturur, ikincisi dosyayı HDFS’ye yükler, üçüncüsü sonucu listeler. Arka plandaki süreç ise şöyledir:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1. İstemci, NameNode'dan dosya oluşturma izni ister.
2. NameNode uygun DataNode zincirini belirler.
3. İstemci bloğu ilk DataNode'a yollar.
4. Blok zincirdeki diğer DataNode'lara aktarılır.
5. Onaylar ters yönde istemciye döner.
</code></pre></div></div>

<p>Bu aktarım zinciri, istemcinin her kopyayı ayrı ayrı göndermesini önleyerek ağ kullanımını dengeler.</p>

<h2 id="güçlü-olduğu-ve-olmadığı-yerler">Güçlü olduğu ve olmadığı yerler</h2>

<p>HDFS; günlük kayıtları, video arşivleri, sensör verileri ve toplu analitik işlemler için mükemmeldir. Buna karşılık milyonlarca küçük dosya NameNode belleğini tüketebilir. Sürekli rastgele güncelleme isteyen işlemler ve milisaniyelik yanıt bekleyen uygulamalar da HDFS’nin uzmanlık alanı değildir.</p>

<p>Kısacası HDFS, tek bir süper bilgisayar yerine birlikte çalışan sıradan makinelerden güvenilir bir depolama ordusu kurar. Hadoop ekosistemindeki MapReduce veya Spark gibi araçlar da hesaplamayı ilgili blokların bulunduğu düğümlere yaklaştırarak petabaytların ağda gereksiz yere dolaşmasını engeller.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="HDFS" /><category term="Hadoop" /><category term="Dağıtık Sistemler" /><summary type="html"><![CDATA[Bir petabayt veriyi dizüstü bilgisayarınıza kopyalamaya çalıştığınızı düşünün. Diskin itiraz etmesi bir yana, işlem tamamlanmadan bilgisayarınız emekli olabilir! Hadoop Dağıtık Dosya Sistemi, yani HDFS, bu problemi devasa ve pahalı bir sunucu almak yerine veriyi yüzlerce sıradan makineye dağıtarak çözer. Üstelik disk arızalarını istisna değil, sistemin doğal bir parçası kabul eder.]]></summary></entry><entry><title type="html">Veri Ambarı ve Yıldız Şeması: Operasyonel Veriden İş Zekâsına</title><link href="https://sonsuzus.github.io/posts/veri-ambari-ve-yildiz-semasi-operasyonel-veriden-is-zekasina/" rel="alternate" type="text/html" title="Veri Ambarı ve Yıldız Şeması: Operasyonel Veriden İş Zekâsına" /><published>2026-08-02T00:00:00+00:00</published><updated>2026-08-02T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/veri-ambari-ve-yildiz-semasi-operasyonel-veriden-is-zekasina</id><content type="html" xml:base="https://sonsuzus.github.io/posts/veri-ambari-ve-yildiz-semasi-operasyonel-veriden-is-zekasina/"><![CDATA[<p>Bir e-ticaret sisteminde sipariş vermek saniyeler sürerken, “Son üç yılda hangi şehirde, hangi ürün kategorisi daha kârlıydı?” sorusunun yanıtı milyonlarca kaydın incelenmesini gerektirebilir. Veri ambarı, günlük operasyonları yavaşlatmadan bu tür geriye dönük analizleri gerçekleştirmek için tasarlanmış merkezi veri yapısıdır.</p>

<p>``</p>

<h2 id="oltp-ve-olap-dünyaları">OLTP ve OLAP dünyaları</h2>

<p>Operasyonel sistemler, yani <strong>OLTP</strong> uygulamaları; sipariş oluşturma, ödeme alma veya stok güncelleme gibi anlık işlemlere odaklanır. Veri ambarlarının temelini oluşturan <strong>OLAP</strong> yaklaşımı ise veriyi farklı açılardan inceleyerek karar desteği sağlar.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>OLTP sistemi</th>
      <th>Veri ambarı / OLAP</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Temel amaç</td>
      <td>Günlük işlemleri yürütmek</td>
      <td>Analiz ve raporlama yapmak</td>
    </tr>
    <tr>
      <td>Veri kapsamı</td>
      <td>Güncel ve ayrıntılı</td>
      <td>Tarihsel ve bütünleşik</td>
    </tr>
    <tr>
      <td>Sorgu türü</td>
      <td>Kısa ekleme ve güncelleme</td>
      <td>Büyük tarama ve toplulaştırma</td>
    </tr>
    <tr>
      <td>Modelleme</td>
      <td>Genellikle normalize</td>
      <td>Genellikle boyutsal</td>
    </tr>
    <tr>
      <td>Kullanıcı</td>
      <td>Uygulama ve operasyon ekibi</td>
      <td>Analist ve yöneticiler</td>
    </tr>
  </tbody>
</table>

<p>Normalize edilmiş operasyonel veritabanlarında tekrar azaltılır. Ancak raporlama sırasında çok sayıda tabloyu birleştirmek gerekebilir. Veri ambarı, kontrollü veri tekrarını kabul ederek sorguları anlaşılır ve hızlı hâle getirir. Kısacası biri kasadaki kuyruğu hızlandırır, diğeri geçen yıl kasadan ne kadar kazandığımızı araştırır.</p>

<h2 id="yıldız-şemasının-anatomisi">Yıldız şemasının anatomisi</h2>

<p>Yıldız şemasının merkezinde ölçülebilir olayları saklayan bir <strong>fact (olgu) tablosu</strong> bulunur. Bu tabloyu ürün, müşteri, mağaza ve tarih gibi <strong>dimension (boyut) tabloları</strong> çevreler. Şema çizildiğinde ortaya yıldızı andıran bir görüntü çıkar.</p>

<p>Bir satış olgu tablosunda şu ölçüler bulunabilir:</p>

<ul>
  <li>Satılan adet</li>
  <li>Birim fiyat</li>
  <li>İndirim tutarı</li>
  <li>Maliyet</li>
  <li>Net satış tutarı</li>
</ul>

<p>Boyut tabloları ise bu sayıların bağlamını açıklar. Örneğin tarih boyutu yıl, çeyrek ve ay; ürün boyutu marka ve kategori bilgilerini taşır. Böylece toplam gelir şu şekilde ifade edilebilir:</p>

\[NetGelir = \sum_{i=1}^{n}(Adet_i \times BirimFiyat_i - Indirim_i)\]

<p>Buradaki en kritik karar <strong>grain</strong>, yani olgu tablosundaki bir satırın neyi temsil ettiğidir. “Her sipariş”, “siparişteki her ürün satırı” ve “ürünün günlük toplam satışı” birbirinden farklı ayrıntı seviyeleridir. Grain belirsizse aynı satışın iki kez sayılması gibi tatsız sürprizler kaçınılmazdır.</p>

<h2 id="örnek-tablo-tasarımı">Örnek tablo tasarımı</h2>

<p>Aşağıdaki SQL, her satırın bir sipariş kalemini temsil ettiği sade bir model kurar:</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">dim_product</span> <span class="p">(</span>
    <span class="n">product_key</span> <span class="nb">INT</span> <span class="k">PRIMARY</span> <span class="k">KEY</span><span class="p">,</span>
    <span class="n">product_id</span> <span class="nb">INT</span><span class="p">,</span>
    <span class="n">product_name</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">150</span><span class="p">),</span>
    <span class="n">category</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">100</span><span class="p">),</span>
    <span class="n">brand</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
<span class="p">);</span>

<span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">dim_date</span> <span class="p">(</span>
    <span class="n">date_key</span> <span class="nb">INT</span> <span class="k">PRIMARY</span> <span class="k">KEY</span><span class="p">,</span>
    <span class="n">full_date</span> <span class="nb">DATE</span><span class="p">,</span>
    <span class="n">year_number</span> <span class="nb">INT</span><span class="p">,</span>
    <span class="n">quarter_number</span> <span class="nb">INT</span><span class="p">,</span>
    <span class="n">month_name</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">20</span><span class="p">)</span>
<span class="p">);</span>

<span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">fact_sales</span> <span class="p">(</span>
    <span class="n">date_key</span> <span class="nb">INT</span> <span class="k">REFERENCES</span> <span class="n">dim_date</span><span class="p">(</span><span class="n">date_key</span><span class="p">),</span>
    <span class="n">product_key</span> <span class="nb">INT</span> <span class="k">REFERENCES</span> <span class="n">dim_product</span><span class="p">(</span><span class="n">product_key</span><span class="p">),</span>
    <span class="n">order_id</span> <span class="nb">INT</span><span class="p">,</span>
    <span class="n">quantity</span> <span class="nb">INT</span><span class="p">,</span>
    <span class="n">unit_price</span> <span class="nb">DECIMAL</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span>
    <span class="n">discount_amount</span> <span class="nb">DECIMAL</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span>
    <span class="n">cost_amount</span> <span class="nb">DECIMAL</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span>
<span class="p">);</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">product_key</code> gibi ambar tarafından üretilen alanlara <strong>surrogate key</strong> denir. Kaynak sistemdeki kimlikler değişse bile tarihsel kayıtların tutarlı kalmasını sağlarlar.</p>

<h2 id="tarihsel-değişiklikler-ve-veri-akışı">Tarihsel değişiklikler ve veri akışı</h2>

<p>Bir müşteri şehir değiştirdiğinde eski satışlar hangi şehre bağlanmalıdır? <strong>Slowly Changing Dimension (SCD)</strong> yaklaşımı bu problemi çözer. SCD Tip 1 eski değeri günceller ve geçmişi korumaz. SCD Tip 2 ise yeni bir boyut satırı açarak başlangıç ve bitiş tarihleriyle geçmişi muhafaza eder.</p>

<p>Veriler genellikle <strong>ETL</strong> sürecinden geçer: Kaynaklardan çıkarılır, temizlenip dönüştürülür ve ambara yüklenir. Modern bulut platformlarında önce yükleyip sonra dönüştüren <strong>ELT</strong> yaklaşımı da yaygındır.</p>

<p>İyi tasarlanmış bir yıldız şeması yalnızca hızlı sorgu üretmez; iş kullanıcılarının veriyi ortak bir dille konuşmasını sağlar. Sağlam bir grain, doğru ölçüler ve tarihsel boyut yönetimi birleştiğinde dağınık operasyon kayıtları güvenilir karar mekanizmasına dönüşür.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="veri ambarı" /><category term="yıldız şeması" /><category term="iş zekâsı" /><summary type="html"><![CDATA[Bir e-ticaret sisteminde sipariş vermek saniyeler sürerken, “Son üç yılda hangi şehirde, hangi ürün kategorisi daha kârlıydı?” sorusunun yanıtı milyonlarca kaydın incelenmesini gerektirebilir. Veri ambarı, günlük operasyonları yavaşlatmadan bu tür geriye dönük analizleri gerçekleştirmek için tasarlanmış merkezi veri yapısıdır.]]></summary></entry><entry><title type="html">Veri Gölleri: Yapay Zekânın Geleceği İçin Ham Veriyi Saklamak</title><link href="https://sonsuzus.github.io/posts/veri-golleri-yapay-zekanin-gelecegi-icin-ham-veriyi-saklamak/" rel="alternate" type="text/html" title="Veri Gölleri: Yapay Zekânın Geleceği İçin Ham Veriyi Saklamak" /><published>2026-08-02T00:00:00+00:00</published><updated>2026-08-02T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/veri-golleri-yapay-zekanin-gelecegi-icin-ham-veriyi-saklamak</id><content type="html" xml:base="https://sonsuzus.github.io/posts/veri-golleri-yapay-zekanin-gelecegi-icin-ham-veriyi-saklamak/"><![CDATA[<p>Bir şirketin ürettiği metinleri, görselleri, sensör kayıtlarını, uygulama loglarını ve ses dosyalarını henüz nasıl kullanacağını bilmeden sakladığını düşünün. İlk bakışta bu yaklaşım dijital istifçilik gibi görünebilir. Oysa doğru yönetilen bir <strong>veri gölü (data lake)</strong>, gelecekte geliştirilecek yapay zekâ modellerine zengin ve yeniden işlenebilir bir veri kaynağı sunar.</p>

<p>``</p>

<h2 id="veri-gölü-tam-olarak-nedir">Veri gölü tam olarak nedir?</h2>

<p>Veri gölü; yapılandırılmış, yarı yapılandırılmış ve yapılandırılmamış verilerin özgün biçimleriyle merkezi bir depoda tutulduğu mimaridir. Bir ilişkisel veritabanına veri yazmadan önce tablo ve sütunları belirlemek gerekirken veri gölünde ham veri önce saklanabilir, kullanım şeması daha sonra oluşturulabilir. Bu yaklaşıma <strong>schema-on-read</strong>, yani “okuma sırasında şema” denir.</p>

<p>Örneğin aynı gölde şu veriler bulunabilir:</p>

<ul>
  <li>JSON biçimindeki uygulama olayları,</li>
  <li>CSV satış kayıtları,</li>
  <li>Müşteri destek konuşmaları,</li>
  <li>Ürün ve güvenlik kamerası görselleri,</li>
  <li>IoT sensörlerinin zaman serileri,</li>
  <li>Sunucuların sıkıştırılmış log dosyaları.</li>
</ul>

<p>Temel fikir basittir: Bugün gereksiz görünen bir kayıt, yarın dolandırıcılık tespiti veya talep tahmini modelinin en değerli özelliğine dönüşebilir.</p>

<h2 id="veri-ambarından-farkı">Veri ambarından farkı</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Veri Gölü</th>
      <th>Veri Ambarı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Veri biçimi</td>
      <td>Ham ve çok çeşitli</td>
      <td>Temizlenmiş, yapılandırılmış</td>
    </tr>
    <tr>
      <td>Şema</td>
      <td>Okuma sırasında</td>
      <td>Yazma sırasında</td>
    </tr>
    <tr>
      <td>Ana kullanıcı</td>
      <td>Veri bilimci, ML mühendisi</td>
      <td>Analist, yönetici</td>
    </tr>
    <tr>
      <td>Tipik kullanım</td>
      <td>Keşif, model eğitimi</td>
      <td>Raporlama, iş zekâsı</td>
    </tr>
    <tr>
      <td>Maliyet</td>
      <td>Büyük ölçekte görece düşük</td>
      <td>İşleme ve modelleme nedeniyle daha yüksek</td>
    </tr>
  </tbody>
</table>

<p>Bu iki sistem rakip olmak zorunda değildir. Veri gölü geniş bir hammadde alanı, veri ambarı ise düzenli rafları bulunan bir mağaza gibi düşünülebilir.</p>

<h2 id="yapay-zekâ-hazırlığı-neden-önemlidir">Yapay zekâ hazırlığı neden önemlidir?</h2>

<p>Bir modelin başarısı yalnızca algoritmaya bağlı değildir. Basitleştirilmiş biçimde model kalitesini şöyle düşünebiliriz:</p>

\[Q \approx f(V, D, C, G)\]

<p>Burada $V$ veri hacmini, $D$ çeşitliliği, $C$ veri doğruluğunu ve $G$ yönetişim kalitesini temsil eder. Milyarlarca kayıt toplamak tek başına yeterli değildir; hatalı etiketler, eksik zaman damgaları ve belirsiz erişim izinleri model performansını düşürür.</p>

<p>Yapay zekâya hazır bir veri gölünde veri kataloglama, sürümleme, köken takibi ve kalite ölçümü bulunmalıdır. Böylece bir özelliğin hangi kaynaktan geldiği ve hangi işlemlerden geçtiği izlenebilir. Özellikle kişisel veriler için maskeleme, şifreleme ve rol tabanlı erişim uygulanmalıdır.</p>

<h2 id="basit-bir-veri-alma-örneği">Basit bir veri alma örneği</h2>

<p>Aşağıdaki Python kodu, JSON satırlarından oluşan ham olay dosyasını okuyup tarih bazlı Parquet dosyalarına dönüştürür. Parquet sütun tabanlı olduğu için analitik sorgularda daha az veri okunmasını sağlar.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">pandas</span> <span class="k">as</span> <span class="n">pd</span>

<span class="n">logs</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nf">read_json</span><span class="p">(</span><span class="sh">'</span><span class="s">events.jsonl</span><span class="sh">'</span><span class="p">,</span> <span class="n">lines</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">logs</span><span class="p">[</span><span class="sh">'</span><span class="s">event_time</span><span class="sh">'</span><span class="p">]</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nf">to_datetime</span><span class="p">(</span><span class="n">logs</span><span class="p">[</span><span class="sh">'</span><span class="s">event_time</span><span class="sh">'</span><span class="p">])</span>
<span class="n">logs</span><span class="p">[</span><span class="sh">'</span><span class="s">event_date</span><span class="sh">'</span><span class="p">]</span> <span class="o">=</span> <span class="n">logs</span><span class="p">[</span><span class="sh">'</span><span class="s">event_time</span><span class="sh">'</span><span class="p">].</span><span class="n">dt</span><span class="p">.</span><span class="n">date</span>

<span class="k">for</span> <span class="n">date</span><span class="p">,</span> <span class="n">partition</span> <span class="ow">in</span> <span class="n">logs</span><span class="p">.</span><span class="nf">groupby</span><span class="p">(</span><span class="sh">'</span><span class="s">event_date</span><span class="sh">'</span><span class="p">):</span>
    <span class="n">path</span> <span class="o">=</span> <span class="sa">f</span><span class="sh">'</span><span class="s">lake/events/date=</span><span class="si">{</span><span class="n">date</span><span class="si">}</span><span class="s">/events.parquet</span><span class="sh">'</span>
    <span class="n">partition</span><span class="p">.</span><span class="nf">to_parquet</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu işlem ham dosyayı tamamen silmek yerine genellikle ayrı bir <strong>işlenmiş katmana</strong> yazar. Böylece gerektiğinde özgün veriye dönülebilir.</p>

<h2 id="gölü-bataklığa-çevirmemek">Gölü bataklığa çevirmemek</h2>

<p>Katalogsuz, sahipsiz ve kalitesi ölçülmeyen bir veri gölü kısa sürede <strong>data swamp</strong>, yani veri bataklığı olur. Bunu önlemek için ham, temizlenmiş ve kullanıma hazır veriler ayrı katmanlarda tutulmalıdır. Her veri kümesine sahip, açıklama, saklama süresi ve kalite puanı atanmalıdır.</p>

<p>Sonuç olarak veri gölü, “her şeyi atalım, bir gün kullanırız” deposu değildir. Doğru mimari ve yönetişimle kurumun deney yapma hızını artıran stratejik bir yapay zekâ altyapısıdır. İyi korunan bir göl model ekiplerini besler; bakımsız bırakılan gölde ise en cesur veri bilimci bile yönünü kaybedebilir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="veri gölü" /><category term="yapay zeka" /><category term="makine öğrenmesi" /><summary type="html"><![CDATA[Bir şirketin ürettiği metinleri, görselleri, sensör kayıtlarını, uygulama loglarını ve ses dosyalarını henüz nasıl kullanacağını bilmeden sakladığını düşünün. İlk bakışta bu yaklaşım dijital istifçilik gibi görünebilir. Oysa doğru yönetilen bir veri gölü (data lake), gelecekte geliştirilecek yapay zekâ modellerine zengin ve yeniden işlenebilir bir veri kaynağı sunar.]]></summary></entry><entry><title type="html">Yazılımda Teknik Borcun Ahlakı: Bugünün Kolaycılığı Yarının Kimin Sorumluluğu?</title><link href="https://sonsuzus.github.io/posts/yazilimda-teknik-borcun-ahlaki-bugunun-kolayciligi-yarinin-kimin-sorumlulugu/" rel="alternate" type="text/html" title="Yazılımda Teknik Borcun Ahlakı: Bugünün Kolaycılığı Yarının Kimin Sorumluluğu?" /><published>2026-08-02T00:00:00+00:00</published><updated>2026-08-02T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/yazilimda-teknik-borcun-ahlaki-bugunun-kolayciligi-yarinin-kimin-sorumlulugu</id><content type="html" xml:base="https://sonsuzus.github.io/posts/yazilimda-teknik-borcun-ahlaki-bugunun-kolayciligi-yarinin-kimin-sorumlulugu/"><![CDATA[<p>Teknik borç çoğu zaman eski kod, eksik test veya aceleyle verilmiş mimari kararlar şeklinde tanımlanır. Ancak mesele yalnızca kod kalitesi değildir. Bugün birkaç saat kazanmak için seçtiğimiz kestirme yol, aylar sonra sistemi devralan başka bir geliştiricinin gecesini, dikkatini ve hatta sağlığını tüketebilir. Bu nedenle teknik borç, ekonomik bir metafor olmanın ötesinde, yazılım ekiplerinin farklı kuşakları arasında aktarılan etik bir yükümlülüktür.
``</p>

<h2 id="borç-metaforu-bize-ne-anlatır">Borç metaforu bize ne anlatır?</h2>

<p>Ward Cunningham’ın popülerleştirdiği teknik borç kavramı, hızlı teslimat uğruna gelecekte ek maliyet doğuracak kararları anlatır. Finansal borçta olduğu gibi burada da bir <strong>ana para</strong> ve <strong>faiz</strong> vardır. Ana para, sorunu bugün düzgün biçimde çözmek için gereken emektir. Faiz ise kötü karar nedeniyle her değişiklikte ödediğimiz ek süredir.</p>

<p>Basitleştirilmiş bir model şöyle kurulabilir:</p>

\[B(t) = B_0 + \sum_{i=1}^{t} F_i\]

<p>Burada $B_0$ başlangıçtaki teknik borcu, $F_i$ ise her geliştirme döneminde ödenen faiz maliyetini temsil eder. Kod tabanı büyüdükçe bağımlılıklar çoğalır ve faiz doğrusal olmaktan çıkabilir:</p>

\[B(t) = B_0(1+r)^t\]

<p>Yani küçük görünen bir kestirme, yeterince uzun süre görmezden gelindiğinde minik bir TODO’dan kurumsal bir korku filmine dönüşebilir.</p>

<h2 id="her-teknik-borç-ahlaksızlık-mıdır">Her teknik borç ahlaksızlık mıdır?</h2>

<p>Hayır. Bazen pazara çıkmak, kritik bir hatayı durdurmak veya belirsizliği test etmek için bilinçli borç almak mantıklıdır. Etik sorun, borcun varlığından çok <strong>gizlenmesi</strong>, <strong>kaydının tutulmaması</strong> ve bedelinin karar sürecine katılmayan insanlara aktarılmasıdır.</p>

<table>
  <thead>
    <tr>
      <th>Karar türü</th>
      <th>Etik açıdan kabul edilebilir yaklaşım</th>
      <th>Sorunlu yaklaşım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Hızlı geçici çözüm</td>
      <td>Riskleri belgelemek ve düzeltme tarihi belirlemek</td>
      <td>Geçici çözümü kalıcıymış gibi sunmak</td>
    </tr>
    <tr>
      <td>Testleri ertelemek</td>
      <td>Kapsamı ve olası etkileri ekiple paylaşmak</td>
      <td>Başarı ölçümlerini korumak için eksikleri saklamak</td>
    </tr>
    <tr>
      <td>Eski sistemi kullanmak</td>
      <td>Göç maliyetini gerçekçi biçimde planlamak</td>
      <td>Bakım yükünü yeni çalışanlara bırakmak</td>
    </tr>
    <tr>
      <td>Teslim baskısı</td>
      <td>Ürün, yönetim ve teknik ekibin ortak karar vermesi</td>
      <td>Geliştiriciyi sessizce kaliteyi düşürmeye zorlamak</td>
    </tr>
  </tbody>
</table>

<p>Bu ayrım niyet kadar yönetişimle de ilgilidir. Kim karar verdi, kim fayda sağladı ve faturayı kim ödeyecek? Etik değerlendirme bu üç soruyu birlikte sormalıdır.</p>

<h2 id="kodda-görünmeyen-sorumluluk">Kodda görünmeyen sorumluluk</h2>

<p>Aşağıdaki örnek çalışır, fakat hatayı sessizce yutarak gelecekteki geliştiriciye belirsizlik bırakır:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">kullaniciyi_getir</span><span class="p">(</span><span class="n">veritabani</span><span class="p">,</span> <span class="n">kullanici_id</span><span class="p">):</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">veritabani</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="n">kullanici_id</span><span class="p">)</span>
    <span class="k">except</span> <span class="nb">Exception</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">None</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">None</code> sonucunun kullanıcının bulunamadığı mı, bağlantının koptuğu mu, yoksa programlama hatası mı olduğu bilinmez. Daha sorumlu yaklaşım, beklenen durumları ayırır ve beklenmeyen hataları görünür kılar:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">KullaniciBulunamadi</span><span class="p">(</span><span class="nb">Exception</span><span class="p">):</span>
    <span class="k">pass</span>

<span class="k">def</span> <span class="nf">kullaniciyi_getir</span><span class="p">(</span><span class="n">veritabani</span><span class="p">,</span> <span class="n">kullanici_id</span><span class="p">):</span>
    <span class="n">kayit</span> <span class="o">=</span> <span class="n">veritabani</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="n">kullanici_id</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">kayit</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
        <span class="k">raise</span> <span class="nc">KullaniciBulunamadi</span><span class="p">(</span><span class="n">kullanici_id</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">kayit</span>
</code></pre></div></div>

<p>Bu sürüm biraz daha fazla kod içerir; fakat davranışın anlamını açıklar. Temiz kod yalnızca estetik değildir: Başka insanların zamanı üzerinde kurduğumuz etkinin sınırlandırılmasıdır.</p>

<h2 id="nesiller-arası-adalet-için-pratikler">Nesiller arası adalet için pratikler</h2>

<p>Teknik borcu etik biçimde yönetmek için borç kayıtları tutulmalı, mimari kararlar gerekçeleriyle belgelenmeli ve refaktör çalışmaları planlamada görünür olmalıdır. Kod incelemelerinde yalnızca “çalışıyor mu?” değil, “bunu altı ay sonra devralan kişi anlayabilecek mi?” sorusu da sorulmalıdır. Ayrıca bakım işi görünmez kahramanlık olarak değil, ürün geliştirme faaliyetinin parçası olarak değerlendirilmelidir.</p>

<p>Sonuçta hiçbir kod sonsuza kadar temiz kalmaz. Etik sorumluluk kusursuz sistemler üretmek değil; aldığımız kestirmelerin bedelini dürüstçe göstermek, faydayı bugün toplarken maliyeti yarının isimsiz geliştiricilerine bırakmamaktır. Git geçmişi unutabilir, ekip değişebilir; fakat kötü kararların faizi düzenli çalışır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="teknik borç" /><category term="yazılım etiği" /><category term="sürdürülebilir yazılım" /><summary type="html"><![CDATA[Teknik borç çoğu zaman eski kod, eksik test veya aceleyle verilmiş mimari kararlar şeklinde tanımlanır. Ancak mesele yalnızca kod kalitesi değildir. Bugün birkaç saat kazanmak için seçtiğimiz kestirme yol, aylar sonra sistemi devralan başka bir geliştiricinin gecesini, dikkatini ve hatta sağlığını tüketebilir. Bu nedenle teknik borç, ekonomik bir metafor olmanın ötesinde, yazılım ekiplerinin farklı kuşakları arasında aktarılan etik bir yükümlülüktür.]]></summary></entry></feed>