MongoDB Kurulum ve Replica Set Yapılandırması

Üretim ortamında MongoDB kurarken “hızlıca çalıştırayım, sonra düzeltirim” yaklaşımı genellikle felaket senaryolarına kapı aralar. Tek node üzerinde çalışan bir MongoDB instance’ı, disk arızası ya da servis çöküşü durumunda tüm verinizi riske atar. Bu yüzden MongoDB’yi doğru kurmak ve Replica Set yapılandırmasını baştan düzgün yapmak, sağlıklı bir production ortamının temel taşlarından biridir. Bu yazıda Ubuntu 22.04 üzerinde MongoDB 7.0 kurulumunu, ardından 3 node’lu bir Replica Set yapılandırmasını adım adım ele alacağız.

Ortam Hazırlığı

Senaryo olarak elimizde üç sunucu olduğunu varsayalım:

  • mongo1: 192.168.10.11
  • mongo2: 192.168.10.12
  • mongo3: 192.168.10.13

Her üç sunucu da Ubuntu 22.04 LTS çalıştırıyor. Kuruluma başlamadan önce bazı ön hazırlıklar yapmak gerekiyor.

Hostname Ayarları

Her sunucuda /etc/hosts dosyasını güncelliyoruz. Bu adım DNS yoksa kritik öneme sahiptir:

sudo tee -a /etc/hosts <<EOF
192.168.10.11 mongo1
192.168.10.12 mongo2
192.168.10.13 mongo3
EOF

Her sunucunun kendi hostname’ini de ayarlayın:

# mongo1 sunucusunda:
sudo hostnamectl set-hostname mongo1

# mongo2 sunucusunda:
sudo hostnamectl set-hostname mongo2

# mongo3 sunucusunda:
sudo hostnamectl set-hostname mongo3

Sistem Parametreleri

MongoDB, yüksek performans için bazı kernel parametrelerinin optimize edilmesini gerektirir. vm.swappiness değeri gereksiz swap kullanımını engeller, ulimit değerleri ise yeterli dosya tanımlayıcı açmasına izin verir:

# Swap kullanımını minimize et
echo "vm.swappiness=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# Transparent Huge Pages kapat (MongoDB bunu önerir)
echo 'never' | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
echo 'never' | sudo tee /sys/kernel/mm/transparent_hugepage/defrag

# Kalıcı hale getirmek için rc.local veya systemd-tmpfiles kullanabilirsiniz

ulimit değerlerini MongoDB kullanıcısı için ayarlayın:

sudo tee /etc/security/limits.d/mongodb.conf <<EOF
mongod soft nofile 64000
mongod hard nofile 64000
mongod soft nproc 64000
mongod hard nproc 64000
EOF

MongoDB Kurulumu

Her üç sunucuda da aynı adımları uyguluyoruz. Önce MongoDB’nin resmi GPG anahtarını ve repository’yi ekliyoruz:

# Gerekli paketleri yükle
sudo apt-get update
sudo apt-get install -y gnupg curl

# MongoDB GPG anahtarını ekle
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | 
  sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor

# Repository ekle
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] 
  https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | 
  sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list

# Paketleri güncelle ve MongoDB kur
sudo apt-get update
sudo apt-get install -y mongodb-org

Kurulum sonrası mongod servisini başlatmadan önce yapılandırma dosyasını düzenlememiz gerekiyor. Ama önce veri ve log dizinleri için doğru izinlerin olduğunu kontrol edelim:

sudo mkdir -p /var/lib/mongodb
sudo mkdir -p /var/log/mongodb
sudo chown -R mongod:mongod /var/lib/mongodb
sudo chown -R mongod:mongod /var/log/mongodb

MongoDB Yapılandırması

MongoDB’nin ana yapılandırma dosyası /etc/mongod.conf YAML formatındadır. Her sunucu için bu dosyayı aşağıdaki gibi düzenliyoruz. Dikkat: bindIp ve replSetName kısımları kritik:

sudo tee /etc/mongod.conf <<EOF
# MongoDB Yapılandırması - Replica Set için

storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 2

systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

net:
  port: 27017
  bindIp: 127.0.0.1,192.168.10.11  # Her sunucuda kendi IP'si

processManagement:
  timeZoneInfo: /usr/share/zoneinfo
  fork: false

replication:
  replSetName: "rs0"
EOF

Önemli: net.bindIp kısmındaki IP adresini her sunucuda o sunucunun IP’si ile değiştirin. cacheSizeGB değerini sunucunuzun RAM kapasitesine göre ayarlayın; genellikle toplam RAM’in %50’si önerilen değerdir.

wiredTiger.engineConfig.cacheSizeGB parametresi özellikle önemlidir. 16 GB RAM’li bir sunucu için bu değeri 7-8 GB olarak ayarlamak mantıklıdır. Çok düşük bırakmak performansı düşürür, çok yüksek ayarlamak ise OS’un disk cache’i için yer bırakmaz.

Şimdi servisi başlatıp enable edelim:

sudo systemctl start mongod
sudo systemctl enable mongod
sudo systemctl status mongod

Firewall Kuralları

Replica Set node’larının birbirleriyle iletişim kurabilmesi için 27017 portunu açmanız gerekiyor. Her sunucuda diğer MongoDB node’larından gelen bağlantılara izin verin:

# UFW kullanıyorsanız
sudo ufw allow from 192.168.10.11 to any port 27017
sudo ufw allow from 192.168.10.12 to any port 27017
sudo ufw allow from 192.168.10.13 to any port 27017

# Uygulama sunucularından erişim için (örnek)
sudo ufw allow from 192.168.10.0/24 to any port 27017
sudo ufw reload

Replica Set Başlatma

Üç sunucuya da MongoDB kurulup yapılandırıldıktan sonra Replica Set’i başlatma zamanı geldi. Bu işlemi sadece bir kere ve sadece mongo1 üzerinde yapıyoruz:

# mongo1 üzerinde mongosh'a bağlan
mongosh --host 127.0.0.1 --port 27017

Bağlandıktan sonra Replica Set’i başlatıyoruz:

rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "mongo1:27017", priority: 2 },
    { _id: 1, host: "mongo2:27017", priority: 1 },
    { _id: 2, host: "mongo3:27017", priority: 1 }
  ]
})

priority değeri Primary seçimini etkiler. Daha yüksek priority değerine sahip node, Primary olmaya daha elverişlidir. Bu sayede genellikle mongo1’in Primary olmasını sağlamış oluyoruz.

Başarılı bir çıktı şöyle görünmeli:

{ ok: 1 }

Ardından Replica Set durumunu kontrol edin:

rs.status()

Birkaç saniye sonra çıktıda stateStr: "PRIMARY" ve stateStr: "SECONDARY" değerlerini görmeniz gerekir. İlk başlatmada tüm node’lar STARTUP durumunda olur, kısa süre sonra election gerçekleşir ve Primary belirlenir.

Yönetici Kullanıcı Oluşturma

Replica Set ayağa kalktıktan sonra authentication’ı etkinleştirmelisiniz. Önce admin kullanıcısını oluşturun:

# Primary node'da (mongo1) mongosh ile bağlan
mongosh --host mongo1:27017

# admin veritabanına geç
use admin

# Admin kullanıcısı oluştur
db.createUser({
  user: "mongoAdmin",
  pwd: "GucluBirSifre123!",
  roles: [
    { role: "userAdminAnyDatabase", db: "admin" },
    { role: "readWriteAnyDatabase", db: "admin" },
    { role: "dbAdminAnyDatabase", db: "admin" },
    { role: "clusterAdmin", db: "admin" }
  ]
})

Keyfile Authentication

Replica Set node’larının birbirleriyle güvenli iletişimi için keyfile kullanıyoruz. Bu adım production ortamında atlanamazlar:

# mongo1 üzerinde keyfile oluştur
openssl rand -base64 756 > /etc/mongodb-keyfile
chmod 400 /etc/mongodb-keyfile
sudo chown mongod:mongod /etc/mongodb-keyfile

# Keyfile içeriğini diğer sunuculara kopyala
sudo scp /etc/mongodb-keyfile mongo2:/etc/mongodb-keyfile
sudo scp /etc/mongodb-keyfile mongo3:/etc/mongodb-keyfile

# Her sunucuda izinleri ayarla
sudo chown mongod:mongod /etc/mongodb-keyfile
sudo chmod 400 /etc/mongodb-keyfile

Şimdi /etc/mongod.conf dosyasına security bölümünü ekleyin (her üç sunucuda):

sudo tee -a /etc/mongod.conf <<EOF

security:
  keyFile: /etc/mongodb-keyfile
  authorization: enabled
EOF

Ardından her üç sunucuda da MongoDB’yi yeniden başlatın:

sudo systemctl restart mongod

Artık mongosh’a bağlanırken kimlik doğrulaması gerekecek:

mongosh --host mongo1:27017 -u mongoAdmin -p GucluBirSifre123! --authenticationDatabase admin

Replica Set İzleme ve Yönetim

Temel Durum Komutları

Günlük operasyonlarda sık kullanacağınız komutlar şunlardır:

# Replica Set genel durumu
rs.status()

# Replica Set konfigürasyonunu görüntüle
rs.conf()

# Hangi node Primary?
rs.isMaster()

# Replica Set lag bilgisi (Secondary gecikmesi)
rs.printSecondaryReplicationInfo()

rs.status() çıktısında dikkat etmeniz gereken alanlar:

  • stateStr: Node’un mevcut durumu (PRIMARY, SECONDARY, ARBITER, RECOVERING)
  • health: 1 ise node sağlıklı
  • optimeDate: Son uygulanan oplog zamanı
  • lastHeartbeat: Son heartbeat zamanı

Failover Testi

Üretim ortamına almadan önce failover senaryosunu test etmek zorunludur. Bunu yapmak için Primary node’u geçici olarak kapatıp Secondary’lerin Primary’ye yükseldiğini gözlemleyebilirsiniz:

# Primary node'da (mongo1) graceful stepdown
mongosh --host mongo1:27017 -u mongoAdmin -p GucluBirSifre123! --authenticationDatabase admin --eval "rs.stepDown()"

rs.stepDown() çalıştırıldıktan sonra mongo2 veya mongo3 kısa süre içinde Primary olacaktır. Birkaç saniye bekleyip rs.status() ile kontrol edin. Eski Primary artık Secondary olarak görünmelidir.

Secondary Node’dan Okuma

Varsayılan olarak okuma işlemleri Primary’den yapılır. Ancak yük dengeleme için Secondary’lerden okuma yapmak mümkündür. Uygulama tarafında connection string’i şu şekilde ayarlarsınız:

mongodb://mongoAdmin:GucluBirSifre123!@mongo1:27017,mongo2:27017,mongo3:27017/veritabaniadi?replicaSet=rs0&readPreference=secondaryPreferred&authSource=admin

readPreference seçenekleri:

  • primary: Sadece Primary’den oku (varsayılan)
  • primaryPreferred: Önce Primary, yoksa Secondary
  • secondary: Sadece Secondary’den oku
  • secondaryPreferred: Önce Secondary, yoksa Primary
  • nearest: Gecikme bazlı en yakın node

Oplog Boyutunu Yönetme

Oplog, Replica Set’in replication mekanizmasının temelidir. Boyutu ne kadar büyük olursa, recovery penceresi de o kadar geniş olur:

# Oplog durumunu kontrol et
mongosh --host mongo1:27017 -u mongoAdmin -p GucluBirSifre123! --authenticationDatabase admin --eval "rs.printReplicationInfo()"

Oplog boyutunu değiştirmek için (mongod 4.4+):

use admin
db.adminCommand({ replSetResizeOplog: 1, size: 51200 })  # 50 GB

Yeni Node Ekleme

Replica Set büyüdükçe yeni node eklemek gerekebilir. Yeni sunucuyu (mongo4: 192.168.10.14) yukarıdaki adımlarla kurduğunuzu varsayalım. Primary node üzerinden ekleyebilirsiniz:

mongosh --host mongo1:27017 -u mongoAdmin -p GucluBirSifre123! --authenticationDatabase admin

rs.add({ host: "mongo4:27017", priority: 1 })

Yeni node eklendiğinde önce STARTUP ardından RECOVERING durumuna geçecek ve oplog’u senkronize edecektir. Veri boyutuna göre bu işlem birkaç dakika ila birkaç saat sürebilir.

Backup Stratejisi

Replica Set ortamında backup için en temiz yöntem Secondary bir node’u kullanmaktır. Böylece Primary’yi yormadan backup alırsınız:

# Secondary node üzerinde mongodump
mongodump 
  --host mongo2:27017 
  --username mongoAdmin 
  --password GucluBirSifre123! 
  --authenticationDatabase admin 
  --oplog 
  --out /backup/mongodb/$(date +%Y%m%d_%H%M%S)

# Backup'ı sıkıştır
tar -czf /backup/mongodb_$(date +%Y%m%d).tar.gz /backup/mongodb/

--oplog parametresi, dump sırasında gerçekleşen değişiklikleri de yakalamanızı sağlar. Bu sayede consistent bir backup elde edersiniz.

Alternatif olarak filesystem level snapshot alabilirsiniz. LVM veya bulut sağlayıcısının snapshot özelliği bu iş için idealdir:

# Secondary node'da önce flush ve lock
mongosh --host mongo2:27017 -u mongoAdmin -p GucluBirSifre123! --authenticationDatabase admin --eval "db.fsyncLock()"

# LVM snapshot al
sudo lvcreate -L 50G -s -n mongodb_snap /dev/vg0/mongodb_data

# Lock'u kaldır
mongosh --host mongo2:27017 -u mongoAdmin -p GucluBirSifre123! --authenticationDatabase admin --eval "db.fsyncUnlock()"

Monitoring Kurulumu

MongoDB’nin built-in monitoring araçlarından biri mongostat‘tır. Gerçek zamanlı performans verisi için:

mongostat 
  --host mongo1:27017 
  --username mongoAdmin 
  --password GucluBirSifre123! 
  --authenticationDatabase admin 
  --discover 
  --rowcount 0

--discover parametresi tüm Replica Set node’larını otomatik keşfeder.

Uzun vadeli izleme için MongoDB Cloud Manager veya Ops Manager kullanılabilir. Alternatif olarak Prometheus ve MongoDB Exporter kombinasyonu açık kaynak bir çözüm sunar:

# MongoDB Exporter kur (mongo1 üzerinde)
wget https://github.com/percona/mongodb_exporter/releases/download/v0.40.0/mongodb_exporter-0.40.0.linux-amd64.tar.gz
tar xzf mongodb_exporter-0.40.0.linux-amd64.tar.gz
sudo mv mongodb_exporter-0.40.0.linux-amd64/mongodb_exporter /usr/local/bin/

# Systemd servis dosyası oluştur
sudo tee /etc/systemd/system/mongodb-exporter.service <<EOF
[Unit]
Description=MongoDB Exporter
After=network.target

[Service]
User=nobody
ExecStart=/usr/local/bin/mongodb_exporter 
  --mongodb.uri="mongodb://mongoAdmin:GucluBirSifre123!@localhost:27017/admin?replicaSet=rs0" 
  --web.listen-address=":9216"
Restart=always

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now mongodb-exporter

Sık Karşılaşılan Sorunlar

Node RECOVERING durumunda takılı kalıyor: Genellikle ağ gecikmesi veya disk I/O sorunundan kaynaklanır. rs.status() çıktısındaki lastHeartbeatMessage alanını inceleyin.

Election döngüsü: Tüm node’lar birbirini Primary yapmaya çalışıyorsa priority değerlerini kontrol edin. Priority 0 olan node Primary olamaz, bu Arbiter’lar için tercih edilir.

Oplog tükeniyor: rs.printReplicationInfo() çıktısında log length start to end değeri çok düşükse oplog boyutunu artırın. Oplog dolduğunda Secondary node recovering durumuna geçer ve tam resync gerektirir.

Authentication hatası: Keyfile’ın her sunucuda aynı içeriğe ve doğru izinlere sahip olduğundan emin olun. chmod 400 ve chown mongod:mongod kombinasyonu şarttır.

Sonuç

MongoDB Replica Set kurulumu ilk bakışta karmaşık görünse de aşamaları tek tek takip ettiğinizde oldukça sistematik bir süreçtir. Bu yazıda ele aldığımız konuları özetlemek gerekirse; önce sistem hazırlığı ve kernel parametrelerini optimize ettik, ardından her node’a MongoDB’yi kurarak Replica Set için yapılandırdık. Keyfile tabanlı authentication ile node’lar arasındaki iletişimi güvence altına aldık. Failover testleri ve oplog yönetimiyle operasyonel hazırlığı sağladık. Son olarak backup stratejisi ve monitoring altyapısını kurarak prodüksiyon ortamına hazır bir yapı elde ettik.

Unutmayın, Replica Set’in değeri gerçek bir felaket anında ortaya çıkar. Bu yüzden failover testlerini düzenli aralıklarla tekrarlamak, oplog boyutunu ve replication lag’ini sürekli izlemek iyi bir sysadmin alışkanlığıdır. Ortamınızda bir şeyler ters gitmeden önce senaryoları test edin; o gün geldiğinde panik yerine hazırlıklı olmanın farkını net biçimde hissedeceksiniz.

Yorum yapın