Yükleniyor...

MongoDB Performans Optimizasyonu: 7 Adımda Kapsamlı 2026 Rehberi

Yazar: Burak Balkı | Kategori: Performance | Okuma Süresi: 37 dk

Bu kapsamlı 2026 rehberinde, MongoDB performans optimizasyonunun neden kritik olduğunu, indekslemeden sharding'e kadar 7 temel adımı ve gerçek dünya proje ör...

### BÖLÜM 1 - Giriş Paragrafı Uygulamanızın yavaşladığını fark ettiğinizde, genellikle ilk bakılan yerlerden biri veritabanıdır. Özellikle büyük veri setleriyle çalışan, yüksek trafikli modern uygulamalar için **MongoDB performans optimizasyonu** hayati öneme sahiptir. 10 yılı aşkın süredir NoSQL veritabanlarıyla çalışırken, yanlış yapılandırılmış bir MongoDB kurulumunun veya optimize edilmemiş sorguların tüm sistemi nasıl felç edebileceğine defalarca şahit oldum. Bu kapsamlı 2026 rehberinde, MongoDB veritabanlarınızın hızını ve verimliliğini artırmak için kanıtlanmış 7 adımı, pratik kod örnekleriyle birlikte öğreneceksiniz. Bu rehber sayesinde, veritabanı darboğazlarını ortadan kaldıracak, kullanıcı deneyimini iyileştirecek ve uygulamalarınızı geleceğe hazır hale getireceksiniz. Hazır mısınız? Başlayalım! ### BÖLÜM 2 - MongoDB Nedir? ## MongoDB Nedir? MongoDB, yüksek performanslı, belge tabanlı, ölçeklenebilir ve esnek bir NoSQL veritabanıdır. JSON benzeri BSON formatında verileri depolar, bu da geliştiricilerin karmaşık veri yapılarıyla doğal bir şekilde çalışmasını sağlar. Geniş bir veri hacmini ve yüksek eşzamanlılığı yönetmek üzere tasarlanmıştır, bu da onu modern web uygulamaları, gerçek zamanlı analitik ve büyük veri çözümleri için ideal kılar. Geleneksel ilişkisel veritabanlarının aksine şemasız yapısıyla hızlı geliştirme ve kolay adaptasyon imkanı sunar. MongoDB, 2026 itibarıyla dünya genelinde en popüler NoSQL veritabanlarından biri olmaya devam etmektedir. Esnek şema yapısı, yatay ölçeklenebilirlik (sharding) yetenekleri ve güçlü sorgu dili (MongoDB Query Language - MQL) sayesinde, geliştiricilere ve mimarlara büyük bir özgürlük sunar. Özellikle mikroservis mimarileri ve hızlı değişen iş gereksinimleri olan projelerde tercih edilmektedir. Resmi dökümantasyonuna [MongoDB Docs](https://www.mongodb.com/docs/) adresinden ulaşabilirsiniz. ### BÖLÜM 3 - Neden MongoDB Performans Optimizasyonu Yapmalısınız? ## Neden MongoDB Performans Optimizasyonu Yapmalısınız? MongoDB'nin sunduğu esneklik ve ölçeklenebilirlik avantajları, doğru kullanılmadığında kolayca performans sorunlarına dönüşebilir. Özellikle büyük veri setleri ve yüksek eşzamanlı kullanıcı trafiği ile karşılaşıldığında, optimize edilmemiş bir MongoDB kurulumu uygulamanızın yanıt sürelerini uzatabilir, sunucu kaynaklarını aşırı tüketebilir ve kullanıcı deneyimini olumsuz etkileyebilir. 10 yılı aşkın deneyimime dayanarak söyleyebilirim ki, performans optimizasyonu sadece bir lüks değil, aynı zamanda uygulamanızın sürdürülebilirliği ve kullanıcı memnuniyeti için bir zorunluluktur. * **Daha Hızlı Yanıt Süreleri**: Optimize edilmiş sorgular ve indeksleme stratejileri, kullanıcı isteklerine saniyeler yerine milisaniyeler içinde yanıt verilmesini sağlar. * **Daha Az Kaynak Tüketimi**: Verimli veritabanı işlemleri, CPU, RAM ve disk I/O kullanımını azaltarak altyapı maliyetlerinden tasarruf etmenizi sağlar. * **Yüksek Ölçeklenebilirlik**: Doğru sharding ve replikasyon stratejileriyle, uygulamanızın artan veri ve trafik yükünü kolayca karşılayabilirsiniz. * **Gelişmiş Kullanıcı Deneyimi**: Hızlı ve akıcı çalışan bir uygulama, kullanıcıların uygulamanızla daha uzun süre etkileşimde kalmasını ve memnuniyetlerini artırmasını sağlar. * **Rekabet Avantajı**: Hızlı ve güvenilir uygulamalar, sektörünüzdeki rakiplerinize karşı önemli bir avantaj sağlar. Performans optimizasyonu, özellikle e-ticaret, oyun, IoT ve finans gibi kritik iş yüklerine sahip sektörler için vazgeçilmezdir. Yanlış indeksleme, büyük dokümanlar veya aşırı sayıda `lookup` işlemi gibi anti-pattern'lar, MongoDB'nin en güçlü yanlarını bile zayıflatabilir. Bu nedenle, projenizin başlangıcından itibaren performans düşüncesiyle hareket etmek, ileride yaşanabilecek büyük sorunların önüne geçecektir. ### BÖLÜM 4 - MongoDB vs İlişkisel Veritabanları (2026 Karşılaştırması) ## MongoDB vs İlişkisel Veritabanları (2026 Karşılaştırması) MongoDB, ilişkisel veritabanlarından farklı bir veri modelleme ve depolama yaklaşımı sunar. Bu farklılıklar, performans ve kullanım senaryoları açısından önemli avantajlar veya dezavantajlar yaratabilir. Aşağıdaki tablo, 2026 itibarıyla MongoDB'yi popüler ilişkisel veritabanları olan PostgreSQL ve MySQL ile temel özellikler açısından karşılaştırmaktadır. | Özellik | MongoDB (NoSQL) | PostgreSQL (İlişkisel) | MySQL (İlişkisel) | | :----------------- | :---------------------------------------------------- | :---------------------------------------------------- | :---------------------------------------------------- | | **Veri Modeli** | Belge tabanlı (JSON/BSON) | Tablo tabanlı (İlişkisel) | Tablo tabanlı (İlişkisel) | | **Şema** | Esnek (Şemasız) | Katı (Önceden tanımlanmış) | Katı (Önceden tanımlanmış) | | **Ölçeklenebilirlik** | Yatay (Sharding ile kolay) | Dikey (Replikasyon ile sınırlı yatay) | Dikey (Replikasyon ile sınırlı yatay) | | **Performans** | Okuma/Yazma hızları yüksek (özellikle indeksli) | Karmaşık sorgularda optimize (JOIN'ler) | Basit sorgularda hızlı | | **Topluluk** | Çok büyük ve aktif | Çok büyük ve aktif | Çok büyük ve aktif | | **Kurumsal Destek** | MongoDB Atlas, kurumsal çözümler | PostgreSQL Global Development Group, ticari destek | Oracle, ticari destek | | **Kullanım Alanı** | Büyük veri, gerçek zamanlı analitik, içerik yönetim | Finans, e-ticaret, veri ambarları | Web uygulamaları, CMS, OLTP | | **Veri Bütünlüğü** | Uygulama katmanında yönetilir (ACID garantisi yok) | ACID garantileri (işlem bütünlüğü) | ACID garantileri (işlem bütünlüğü) | Bu karşılaştırma, MongoDB'nin özellikle esnek şema gerektiren, yüksek ölçeklenebilirlik beklenen ve doküman tabanlı verilerle çalışan uygulamalar için güçlü bir alternatif olduğunu göstermektedir. İlişkisel veritabanları ise, katı şema gereksinimleri ve karmaşık ilişkisel sorguların ön planda olduğu durumlarda hala vazgeçilmezdir. Her iki veritabanı türünün de kendine özgü avantajları vardır ve seçim, projenin özel ihtiyaçlarına bağlıdır. ### BÖLÜM 5 - MongoDB Kurulumu ve İlk Adımlar (2026) ## MongoDB Kurulumu ve İlk Adımlar (2026) MongoDB performans optimizasyonuna başlamadan önce, çalışan bir MongoDB sunucusuna ihtiyacımız var. Bu bölümde, MongoDB 7.0 Community Edition'ı yerel makinenize nasıl kuracağınızı ve temel bağlantı adımlarını göstereceğim. Kurulum adımları işletim sisteminize göre değişiklik gösterebilir, ancak genel prensipler aynıdır. Ben Ubuntu 22.04 LTS üzerinde kurulumu göstereceğim. **Ön Gereksinimler:** * Güncel bir Linux dağıtımı (Ubuntu, CentOS vb.) veya macOS/Windows işletim sistemi. * Yönetici (sudo) yetkileri. 1. **MongoDB GPG Anahtarını İçe Aktarma:** MongoDB paketlerini doğrulamak için GPG anahtarını içe aktarın: ```bash wget -qO - https://www.mongodb.org/static/pgp/server-7.0.asc | sudo apt-key add - ``` 2. **MongoDB Deposu Oluşturma:** MongoDB deposunu sisteminizin kaynak listesine ekleyin. Ubuntu 22.04 için: ```bash echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list ``` 3. **Paket Listesini Güncelleme:** Yeni eklenen depoyu sisteminize tanıtmak için paket listesini güncelleyin: ```bash sudo apt update ``` 4. **MongoDB Yükleme:** MongoDB 7.0 paketlerini yükleyin: ```bash sudo apt install -y mongodb-org ``` 5. **MongoDB Servisini Başlatma:** Yükleme tamamlandıktan sonra MongoDB servisini başlatın ve sistem başlangıcında otomatik başlaması için etkinleştirin: ```bash sudo systemctl start mongod sudo systemctl enable mongod sudo systemctl status mongod ``` `status` komutu çıktısında `active (running)` ibaresini görmelisiniz. 6. **MongoDB Kabuğuna Bağlanma:** `mongosh` komutu ile MongoDB kabuğuna bağlanarak kurulumun başarılı olduğunu doğrulayın: ```bash mongosh ``` Çıktı olarak `test` veritabanına bağlı olduğunuzu gösteren bir prompt görmelisiniz: ``` Current Mongosh Log ID: ... Connecting to: mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.11.1 ... test> ``` Tebrikler! MongoDB sunucunuz 2026 itibarıyla başarıyla kuruldu ve çalışır durumda. Şimdi performans optimizasyonu tekniklerine geçebiliriz. ### BÖLÜM 6 - Temel MongoDB Performans Teknikleri ## Temel MongoDB Performans Teknikleri MongoDB performansını artırmak için uygulayabileceğiniz en temel ve etkili tekniklerden biri doğru indeksleme stratejileridir. İndeksler, veritabanının sorguları daha hızlı bir şekilde bulmasını sağlar, tıpkı bir kitabın içindekiler dizini gibi. Ayrıca, sadece ihtiyaç duyulan alanları getirmek (projection) ve veri setini sınırlamak (limit/skip) da performansı önemli ölçüde etkiler. #### 6.1. İndeksleme (Indexing) İndeksler, sorgu performansını artırmanın en kritik yoludur. Sorgularınızda sıkça kullanılan alanlara indeks ekleyerek, MongoDB'nin tüm koleksiyonu taramasını engellersiniz. Bir üretim ortamında, yanlış indeksleme stratejilerinin ne kadar büyük performans sorunlarına yol açtığını bizzat deneyimledim. **Tek alanlı indeks oluşturma:** ```javascript // 'users' koleksiyonunda 'email' alanına tek alanlı indeks oluşturma db.users.createIndex({ email: 1 }); // 1 artan, -1 azalan sıra için ``` **Bileşik indeks oluşturma:** Sorgularınızda birden fazla alanı birlikte kullanıyorsanız, bileşik indeksler çok etkilidir. Örneğin, `status` ve `createdAt` alanlarına göre sorgulama yapıyorsanız: ```javascript // 'orders' koleksiyonunda 'status' ve 'createdAt' alanlarına bileşik indeks oluşturma db.orders.createIndex({ status: 1, createdAt: -1 }); ``` > **Pro Tip**: İndekslerin sırası önemlidir! Sorgularınızda en çok kullanılan veya eşitlik kontrolü yapılan alanı öne koyun (Equality, Sort, Range - ESR kuralı). #### 6.2. Sorgu Optimizasyonu (Projection) Sorgularınızda yalnızca ihtiyacınız olan alanları seçmek (projection), ağ trafiğini ve bellek kullanımını azaltarak performansı artırır. Bu, özellikle büyük dokümanlarla çalışırken çok önemlidir. **Örnek:** Sadece `name` ve `email` alanlarını getirme: ```javascript // 'users' koleksiyonundan sadece 'name' ve 'email' alanlarını seçme db.users.find({}, { name: 1, email: 1, _id: 0 }); // _id varsayılan olarak gelir, kapatmak için 0 ``` #### 6.3. Veri Setini Sınırlama (Limit ve Skip) Sayfalama (pagination) yaparken veya büyük sonuç kümelerinden sadece bir kısmını almak istediğinizde `limit()` ve `skip()` metodlarını kullanmak performansı artırır. Ancak, `skip()` metodunun büyük değerlerle kullanıldığında performansı düşürebileceğini unutmayın, çünkü MongoDB yine de atlanacak dokümanları taramak zorunda kalır. **Örnek:** İlk 10 kaydı atla, sonraki 5 kaydı getir (sayfa 3, her sayfada 5 kayıt): ```javascript // 'products' koleksiyonundan ilk 10 kaydı atlayıp sonraki 5 kaydı getirme db.products.find({}).skip(10).limit(5); ``` > **Uyarı**: Yüksek `skip` değerlerinden kaçının. Bunun yerine, `last_id` tabanlı sayfalama (cursor-based pagination) kullanmak daha verimlidir. Örneğin, son getirilen dokümanın `_id`'sini kullanarak bir sonraki sayfayı sorgulayın. ```javascript // Cursor tabanlı sayfalama örneği const lastId = "65f2b8e3a2b7c1d4e5f6a7b8"; // Son getirilen dokümanın _id'si db.products.find({ _id: { $gt: lastId } }).limit(5).sort({ _id: 1 }); ``` ### BÖLÜM 7 - İleri Seviye Performans Optimizasyonları (2026) ## İleri Seviye Performans Optimizasyonları (2026) MongoDB'nin temel performans tekniklerinin ötesine geçerek, daha karmaşık ve büyük ölçekli uygulamalar için kritik olan ileri seviye optimizasyon tekniklerine odaklanacağız. Bu teknikler, özellikle yüksek veri hacmi ve karmaşık sorgu gereksinimleri olan kurumsal uygulamalarda vazgeçilmezdir. #### 7.1. Aggregation Pipeline Optimizasyonu Aggregation pipeline, MongoDB'nin güçlü veri dönüşüm ve analiz aracıdır. Ancak, karmaşık pipeline'lar performans sorunlarına yol açabilir. Pipeline'ı optimize etmek için şu stratejileri izleyin: * **`$match` aşamasını öne almak**: Mümkün olduğunca erken `match` aşamasını kullanarak veri setini küçültün. * **`$project` aşamasını erken kullanmak**: İhtiyaç duyulmayan alanları baştan eleyin. * **İndeksleri kullanmak**: `$match`, `$sort` ve bazen `$group` aşamalarında indekslerden faydalanın. **Örnek:** `$match` ve `$project` ile optimize edilmiş aggregation pipeline: ```javascript // 'transactions' koleksiyonunda 2026 yılına ait, tutarı 100'den büyük, sadece 'amount' ve 'currency' alanlarını getiren optimize edilmiş pipeline db.transactions.aggregate([ { $match: { createdAt: { $gte: new Date('2026-01-01T00:00:00Z'), $lt: new Date('2027-01-01T00:00:00Z') }, amount: { $gt: 100 } } }, { $project: { amount: 1, currency: 1, _id: 0 } }, { $limit: 100 } ]); ``` #### 7.2. Sharding (Yatay Ölçeklendirme) Sharding, büyük veri setlerini ve yüksek yazma/okuma yüklerini dağıtarak yatay ölçeklenebilirlik sağlamanın anahtarıdır. Verilerinizi birden fazla sunucuya (shard) dağıtarak, her bir shard'ın kendi veri alt kümesini işlemesini sağlarsınız. * **Shard Anahtarı Seçimi**: Shard anahtarı, verilerin shard'lar arasında nasıl dağıtılacağını belirler. İyi bir shard anahtarı, veri dağılımını dengeler ve sıcak noktaları (hot spots) önler. Genellikle `_id` veya sıkça sorgulanan, kardinalitesi yüksek bir alan seçilir. * **Hashed Sharding vs Range Sharding**: Kullanım senaryosuna göre doğru shard stratejisini seçin. > **Tecrübe**: Kurumsal projelerimizde MongoDB'nin ölçeklenebilirlik yeteneklerini defalarca test ettik. Doğru shard anahtarı seçimi, sistemin genel performansını %50'ye varan oranlarda artırabilir. #### 7.3. Replikasyon Setleri (High Availability) Replikasyon setleri, veri yedekliliği ve yüksek erişilebilirlik sağlayarak sistemin hata toleransını artırır. Birincil (primary) sunucu çöktüğünde, ikincil (secondary) sunuculardan biri otomatik olarak primary rolünü üstlenir. Bu, performans optimizasyonu kadar, sistemin çalışma süresi (uptime) için de kritiktir. * **Okuma Tercihleri (Read Preferences)**: Uygulamanızın okuma işlemlerini secondary sunuculara yönlendirerek primary üzerindeki yükü azaltabilirsiniz. Bu, özellikle okuma yoğun uygulamalarda performansı iyileştirir. ```javascript // Node.js'te okuma tercihlerini ayarlama örneği (Mongoose ile) const mongoose = require('mongoose'); mongoose.connect('mongodb://host1:27017,host2:27017,host3:27017/mydb', { replicaSet: 'myReplicaSet', readPreference: 'secondaryPreferred' // Secondary sunuculardan okumayı tercih et }); ``` #### 7.4. Capped Collections Capped collections, sabit boyutlu koleksiyonlardır ve ekleme sırasını korurlar. Maksimum boyuta ulaştığında, en eski dokümanları otomatik olarak siler. Bu, özellikle loglama, anlık mesajlaşma veya son aktivite akışları gibi senaryolarda yüksek performanslı FIFO (First-In, First-Out) davranışı sağlar. **Örnek:** 10MB boyutunda bir `logs` capped collection oluşturma: ```javascript // 'logs' adında 10MB boyutunda bir capped collection oluşturma db.createCollection("logs", { capped: true, size: 10485760 }); ``` ### BÖLÜM 8 - MongoDB Performans Best Practices ve Anti-Patterns ## MongoDB Performans Best Practices ve Anti-Patterns MongoDB ile çalışırken, performans sorunlarından kaçınmak ve verimliliği artırmak için belirli kurallara uymak önemlidir. İşte 2026 itibarıyla geçerli olan bazı kritik best practices ve kaçınılması gereken anti-pattern'lar: * ✅ **Doğru İndeksleme Yapın**: Sorgularınızda `find()`, `sort()`, `$match`, `$group` gibi operatörlerde kullanılan alanlara indeks ekleyin. `explain()` metodunu kullanarak indeks kullanımını kontrol edin. * ❌ **Aşırı İndekslemeden Kaçının**: Her indeks yazma işlemlerinin maliyetini artırır ve disk alanı tüketir. Sadece gerçekten ihtiyaç duyulan indeksleri oluşturun. * ✅ **Veri Modellemenizi Optimize Edin**: Uygulamanızın sorgu desenlerine göre verilerinizi gömülü (embedded) veya referanslı (referenced) olarak modelleyin. Genellikle, ilişkisel veritabanlarındaki JOIN işlemlerinden kaçınmak için gömülü dokümanlar tercih edilir. * ❌ **Büyük Dokümanlardan Kaçının**: Tek bir dokümanın çok büyük olması (örneğin 16MB sınırı), okuma/yazma performansını düşürebilir ve bellek tüketimini artırabilir. Büyük ikili verileri (resim, video) GridFS veya harici bir depolama servisinde tutun. * ✅ **Projection Kullanın**: `find()` sorgularında sadece ihtiyacınız olan alanları seçerek ağ trafiğini ve bellek kullanımını azaltın. `_id: 0` ile gereksiz `_id` alanını kapatın. * ❌ **`skip()` ile Büyük Değerlerden Kaçının**: Sayfalama için `skip()` yerine cursor tabanlı (`_id` veya `createdAt` gibi alanlara göre) sayfalama kullanın. Büyük `skip` değerleri performans sorunlarına yol açar. * ✅ **Sharding'i Doğru Kullanın**: Veri dağılımını dengelemek ve sıcak noktaları önlemek için iyi bir shard anahtarı seçin. Uygulamanızın büyüme projeksiyonlarına uygun bir sharding stratejisi belirleyin. * ❌ **`$lookup` Kullanımını Sınırlayın**: `$lookup` (JOIN benzeri işlem), aggregation pipeline'ı yavaşlatabilir. Mümkünse veri modellemenizde gömülü dokümanları tercih ederek `$lookup` ihtiyacını azaltın. * ✅ **Replikasyon Setlerini Yapılandırın**: Yüksek erişilebilirlik ve veri yedekliliği için replikasyon setleri kullanın. Okuma yoğun uygulamalarda `readPreference` ayarlarını optimize edin. * ❌ **`$ne` ve `$nin` gibi Negatif Sorgulardan Kaçının**: Bu tür sorgular indeksleri verimli kullanamaz ve tüm koleksiyonu taramak zorunda kalabilir. Mümkünse pozitif sorgular (`$in`, `$eq`) kullanın. * ✅ **Yazma Concern ve Okuma Concern Ayarlarını Optimize Edin**: Uygulamanızın veri tutarlılığı ve performansı arasındaki dengeyi sağlamak için `writeConcern` ve `readConcern` ayarlarını doğru yapılandırın. * ❌ **Uzun Süren Sorguları İzleyin**: `db.currentOp()` ve `profiling` araçlarını kullanarak yavaş çalışan sorguları tespit edin ve optimize edin. ### BÖLÜM 9 - Yaygın MongoDB Performans Sorunları ve Çözümleri ## Yaygın MongoDB Performans Sorunları ve Çözümleri MongoDB ile çalışırken sıkça karşılaşılan performans sorunları vardır. Bu sorunları tanımak ve doğru çözümleri uygulamak, uygulamanızın istikrarlı ve hızlı çalışmasını sağlar. İşte 2026 itibarıyla en yaygın karşılaşılan sorunlar ve çözümleri: 1. **Problem: Yavaş Sorgular (Slow Queries)** * **Sebep**: İndekslenmemiş alanlar üzerinde sorgulama, yanlış bileşik indeksler, büyük koleksiyon taramaları (Collection Scans). * **Çözüm**: `db.collection.explain('executionStats')` kullanarak sorgu planını analiz edin. Sorgularda kullanılan alanlara uygun indeksler oluşturun. Bileşik indekslerde ESR kuralını (Equality, Sort, Range) uygulayın. * **Örnek `explain()` kullanımı:** ```javascript db.users.find({ age: { $gt: 30 }, city: 'Istanbul' }).explain('executionStats'); ``` 2. **Problem: Yüksek CPU Kullanımı** * **Sebep**: Yoğun aggregation pipeline işlemleri, yetersiz indeksleme nedeniyle fazla doküman işleme, çok sayıda eşzamanlı bağlantı. * **Çözüm**: Aggregation pipeline'ları optimize edin (`$match`'i öne almak, `$project` ile gereksiz alanları elemek). `mongotop` ve `mongostat` araçlarıyla hangi işlemlerin CPU'yu en çok kullandığını belirleyin. Sunucu kaynaklarını artırın veya sharding uygulayın. 3. **Problem: Yüksek Bellek (RAM) Kullanımı** * **Sebep**: Büyük indeksler, `sort()` veya `group()` gibi bellek içi işlemleri gerektiren sorgular, WiredTiger önbelleğinin aşırı kullanımı. * **Çözüm**: Gereksiz indeksleri silin. `allowDiskUse: true` seçeneğini kullanarak büyük aggregation işlemlerinin diski kullanmasına izin verin (ancak bu yavaşlatabilir). WiredTiger önbellek boyutunu optimize edin (varsayılan genellikle RAM'in %50'sidir). 4. **Problem: Disk I/O Bottleneck (Disk Okuma/Yazma Darboğazı)** * **Sebep**: Sık ve yoğun yazma işlemleri (örneğin, loglama), yetersiz depolama donanımı, WiredTiger journal'ın performansı. * **Çözüm**: Daha hızlı SSD depolama kullanın. Yazma işlemlerini toplu hale getirin (`bulkWrite`). `writeConcern` ayarlarını optimize edin. Loglama gibi yoğun yazma işlemleri için Capped Collections kullanın veya ayrı bir veritabanı/servis kullanmayı düşünün. 5. **Problem: Kilitlenmeler (Locks) ve Eşzamanlılık Sorunları** * **Sebep**: Uzun süren yazma işlemleri, büyük doküman güncellemeleri, indeks oluşturma gibi yönetimsel işlemler. * **Çözüm**: MongoDB 7.0 ile doküman seviyesi kilitleme sayesinde bu sorunlar azalmıştır, ancak yine de büyük doküman güncellemelerinden kaçının. İndeks oluşturmayı düşük trafikli zamanlara planlayın. `db.currentOp()` ile kilitlenmeye neden olan işlemleri izleyin. ### BÖLÜM 10 - MongoDB Performans İzleme ve Analiz Araçları ## MongoDB Performans İzleme ve Analiz Araçları Performans optimizasyonu sürekli bir süreçtir ve veritabanınızın sağlığını ve performansını düzenli olarak izlemek kritik öneme sahiptir. 2026 itibarıyla, MongoDB'nin kendi araçları ve üçüncü parti çözümlerle kapsamlı izleme yapabilirsiniz. #### 10.1. MongoDB Dahili Araçları * **`explain()`**: Sorgu planlarını analiz etmek ve indeks kullanımını anlamak için vazgeçilmezdir. Sorgunuzun nasıl çalıştığını, hangi indeksleri kullandığını ve ne kadar zaman aldığını gösterir. ```javascript // 'orders' koleksiyonunda 'status' alanına göre sorgunun performansını incele db.orders.find({ status: 'pending' }).explain('executionStats'); ``` > **Çıktı Analizi**: `winningPlan.stage` (sorgu aşaması), `totalDocsExamined` (taranan doküman sayısı), `totalKeysExamined` (taranan indeks anahtarı sayısı) ve `executionTimeMillis` (yürütme süresi) gibi metrikler kritik öneme sahiptir. `COLLSCAN` görüyorsanız, indeksleme sorunları var demektir. * **`db.currentOp()`**: Anlık olarak çalışan tüm işlemleri gösterir. Uzun süren sorguları, kilitlenmeleri ve aktif bağlantıları tespit etmek için kullanılır. ```javascript // Aktif işlemleri göster, 30 saniyeden uzun sürenleri filtrele db.currentOp({ "active": true, "secs_running": { "$gt": 30 } }); ``` * **`profiling`**: Yavaş çalışan sorguları kaydetmek için kullanılır. Belirli bir eşiğin üzerindeki tüm sorguları loglar. ```javascript // Profiling'i etkinleştir (seviye 2: tüm işlemleri kaydet) db.setProfilingLevel(2); // Profiling verilerini sorgula db.system.profile.find({ millis: { $gt: 100 } }).pretty(); // 100ms'den uzun süren sorgular // Profiling'i kapat db.setProfilingLevel(0); ``` * **`mongostat`**: Sunucunun anlık durumunu, okuma/yazma oranlarını, bellek kullanımını ve kilitlenme istatistiklerini gösterir. ```bash mongostat ``` * **`mongotop`**: Hangi koleksiyonların en çok okuma ve yazma aktivitesine sahip olduğunu gösterir. ```bash mongotop ``` #### 10.2. Harici ve Bulut Tabanlı Araçlar * **MongoDB Atlas Monitoring**: Eğer MongoDB Atlas kullanıyorsanız, yerleşik izleme panoları sayesinde CPU, RAM, disk I/O, sorgu performansı, replikasyon gecikmesi gibi birçok metriği gerçek zamanlı olarak takip edebilirsiniz. Anormallik tespiti ve uyarı sistemleri ile proaktif olmanızı sağlar. * **Prometheus & Grafana**: Kendi kendine barındırılan (self-hosted) çözümler için popüler bir kombinasyondur. MongoDB exporter'ı kullanarak metrikleri Prometheus'a çekip, Grafana panolarında görselleştirebilirsiniz. Bu, özellikle karmaşık altyapılarda merkezi izleme için idealdir. * **APM (Application Performance Monitoring) Araçları**: New Relic, Datadog gibi APM araçları, uygulamanızın kod seviyesinden veritabanına kadar tüm performans metriklerini izlemenize olanak tanır. MongoDB sürücüleri genellikle bu araçlarla entegrasyon sunar. ### BÖLÜM 11 - Gerçek Dünya Proje Örneği: Performans Odaklı API Geliştirme (Node.js & MongoDB) ## Gerçek Dünya Proje Örneği: Performans Odaklı API Geliştirme (Node.js & MongoDB) Bu bölümde, Node.js ve Express.js kullanarak basit bir REST API geliştireceğiz ve MongoDB performans optimizasyon tekniklerini bu API üzerinde uygulayacağız. Amacımız, ürün listeleme ve detaylarını getirme işlemlerini optimize etmektir. Bu proje, 2026'nın modern web geliştirme pratiklerini yansıtmaktadır. **Proje Yapısı:** ``` mongodb-perf-api/ ├── src/ │ ├── models/ │ │ └── Product.js │ ├── routes/ │ │ └── productRoutes.js │ ├── config/ │ │ └── db.js │ └── app.js ├── .env └── package.json ``` **1. `package.json`:** ```json { "name": "mongodb-perf-api", "version": "1.0.0", "description": "Performans odaklı Node.js MongoDB API örneği", "main": "src/app.js", "scripts": { "start": "node src/app.js", "dev": "nodemon src/app.js" }, "keywords": [], "author": "Burak Balkı", "license": "ISC", "dependencies": { "dotenv": "^16.4.5", "express": "^4.19.2", "mongoose": "^8.4.1" }, "devDependencies": { "nodemon": "^3.1.3" } } ``` **2. `.env`:** ```env PORT=3000 MONGO_URI=mongodb://localhost:27017/perfdb ``` **3. `src/config/db.js`:** ```javascript // src/config/db.js const mongoose = require('mongoose'); const connectDB = async () => { try { await mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true, // MongoDB 7.0 için recommended ayarlar serverSelectionTimeoutMS: 5000, // Sunucu seçim zaman aşımı socketTimeoutMS: 45000, // Soket zaman aşımı }); console.log('MongoDB 2026 bağlantısı başarılı!'); } catch (err) { console.error('MongoDB bağlantı hatası:', err.message); process.exit(1); } }; module.exports = connectDB; ``` **4. `src/models/Product.js`:** ```javascript // src/models/Product.js const mongoose = require('mongoose'); const productSchema = new mongoose.Schema({ name: { type: String, required: true, unique: true, }, description: { type: String, required: true, }, price: { type: Number, required: true, }, category: { type: String, required: true, index: true // 'category' alanına indeks ekledik }, brand: { type: String, required: true, index: true // 'brand' alanına indeks ekledik }, stock: { type: Number, default: 0, }, createdAt: { type: Date, default: Date.now, index: true // 'createdAt' alanına indeks ekledik (sıralama için) }, updatedAt: { type: Date, default: Date.now, }, }, { timestamps: true }); // Bileşik indeks: category ve price'a göre sıkça sorgulama yapıldığını varsayalım productSchema.index({ category: 1, price: -1 }); // Metin aramaları için metin indeksi (eğer metin araması yapılacaksa) // productSchema.index({ name: 'text', description: 'text' }); module.exports = mongoose.model('Product', productSchema); ``` **5. `src/routes/productRoutes.js`:** ```javascript // src/routes/productRoutes.js const express = require('express'); const Product = require('../models/Product'); const router = express.Router(); // Ürün ekleme (veri doldurmak için) router.post('/', async (req, res) => { try { const product = new Product(req.body); await product.save(); res.status(201).json(product); } catch (err) { res.status(400).json({ message: err.message }); } }); // Tüm ürünleri getirme (optimize edilmiş: sayfalama, sıralama, projection) router.get('/', async (req, res) => { const { page = 1, limit = 10, category, sort = 'createdAt', order = -1 } = req.query; const skip = (parseInt(page) - 1) * parseInt(limit); const query = {}; if (category) { query.category = category; } try { const products = await Product.find(query) .sort({ [sort]: parseInt(order) }) .skip(skip) .limit(parseInt(limit)) .select('name price category brand createdAt'); // Sadece gerekli alanları seç const totalProducts = await Product.countDocuments(query); res.json({ products, currentPage: parseInt(page), totalPages: Math.ceil(totalProducts / parseInt(limit)), totalProducts, }); } catch (err) { res.status(500).json({ message: err.message }); } }); // Belirli bir ürünü ID ile getirme router.get('/:id', async (req, res) => { try { const product = await Product.findById(req.params.id); if (!product) return res.status(404).json({ message: 'Ürün bulunamadı' }); res.json(product); } catch (err) { res.status(500).json({ message: err.message }); } }); module.exports = router; ``` **6. `src/app.js`:** ```javascript // src/app.js require('dotenv').config(); const express = require('express'); const connectDB = require('./config/db'); const productRoutes = require('./routes/productRoutes'); const app = express(); // Veritabanı bağlantısı connectDB(); // Middleware app.use(express.json()); // Rotalar app.use('/api/products', productRoutes); const PORT = process.env.PORT || 3000; app.listen(PORT, () => console.log(`Sunucu ${PORT} portunda çalışıyor (2026)`)); ``` **Çalıştırma Adımları:** 1. Projeyi klonlayın veya dosyaları oluşturun. 2. Terminalde projenin kök dizinine gidin. 3. `npm install` komutunu çalıştırarak bağımlılıkları yükleyin. 4. `npm run dev` veya `npm start` ile uygulamayı başlatın. **Test Etme:** * `POST /api/products` ile ürün ekleyin (örneğin, Postman veya Insomnia kullanarak): ```json { "name": "Kablosuz Oyuncu Faresi 2026", "description": "Yüksek hassasiyetli, ergonomik oyunc