← Kursa Dön
📄 Text · 30 min

Index Optimizasyonu — Shard Stratejisi ve Routing

Giriş — Shard Stratejisi, Routing ve ILM

Bir kütüphane düşün. Kitapları tek bir rafta tutarsan, bir süre sonra o raf çöker — hem fiziksel olarak hem de aradığını bulmak imkansız hale gelir. Ama kitapları türlerine göre farklı raflara dağıtırsan, her raf makul boyutta kalır ve arama kolaylaşır. Şimdi bir de şunu düşün: her gün yüzlerce yeni kitap geliyor. Eski kitaplar okunmuyor ama yer kaplıyor. Bir sistem kurup "6 aydan eski kitaplar arka depoya, 1 yıldan eskiler arşive" desen işler düzene girer.

Elasticsearch'te index optimizasyonu tam olarak bu. Shard'larını doğru boyutlandır, veriyi akıllıca yönlendir (routing), ve zamanla verinin yaşam döngüsünü yönet (ILM). Bu üç kavram, Elasticsearch'ünüzün "günde 100 request'lik dev tool oyuncağı" ile "günde 1 milyar event'lik production canavarı" arasındaki farkı yaratır.


1. Shard Stratejisi — Kaç Shard, Ne Kadar Büyük?

Shard Nedir? (Hızlı Hatırlatma)

Her Elasticsearch index'i bir veya daha fazla shard'a bölünür. Her shard aslında bağımsız bir Lucene index'idir. Shard'lar cluster'daki node'lara dağıtılır — bu sayede paralel arama ve yatay ölçekleme mümkün olur.

Shard Boyutu: Altın Kural

Elasticsearch topluluğunda ve resmi dokümantasyonda önerilen shard boyutu: 10GB ile 50GB arası.

Neden bu aralık?

  • Çok küçük shard'lar (< 1GB): Her shard'ın overhead'i var. Cluster state'te yer kaplar, segment merge yapar, file handle tutar. 1000 tane 100MB'lık shard, 20 tane 5GB'lık shard'dan çok daha fazla kaynak tüketir.

  • Çok büyük shard'lar (> 50GB): Recovery süresi uzar. Bir node düşerse, o devasa shard'ı başka bir node'a taşımak dakikalar hatta saatler sürebilir. Ayrıca segment merge işlemleri disk ve CPU'yu boğar.

# Mevcut shard boyutlarını kontrol et
GET _cat/shards?v&h=index,shard,prirep,store,node&s=store:desc

# Çıktı örneği:
# index              shard prirep store   node
# logs-2024.01       0     p      45.2gb  node-1
# logs-2024.01       1     p      43.8gb  node-2
# logs-2024.01       0     r      45.2gb  node-3
# users              0     p      2.1gb   node-1

Shard Sayısı Hesaplama

Formül basit:

Toplam Shard Sayısı = Toplam Veri Boyutu / Hedef Shard Boyutu

Örnek: 500GB log veriniz var, hedef shard boyutu 25GB → 20 primary shard.

Ama dikkat — shard sayısını index oluşturduktan sonra değiştiremezsiniz (split/shrink API'leri hariç, ama bunlar pahalı operasyonlar). Bu yüzden baştan doğru planlamak kritik.

// 500GB veri için index oluşturma
PUT logs-2024.01
{
  "settings": {
    "number_of_shards": 20,
    "number_of_replicas": 1
  }
}

Node Başına Shard Limiti

Elasticsearch 7.x'ten itibaren varsayılan olarak node başına 1000 shard limiti var. Bu limite ulaşmak, cluster'ınızda bir tasarım problemi olduğunun işareti:

# Cluster-wide shard sayısını kontrol et
GET _cluster/health?filter_path=active_primary_shards,active_shards

# Node başına shard dağılımı
GET _cat/allocation?v&h=node,shards,disk.used,disk.avail

Shard Başına Document Sayısı

Lucene'in hard limiti: shard başına ~2.1 milyar document. Pratikte bu limiti zorlamamalısınız — 200-500 milyon document/shard ideal aralık.

Over-Sharding Sorunu

Yeni başlayanların en sık hatası: "Daha fazla shard = daha hızlı arama" sanmak. Gerçekte her shard:

  • ~50MB heap memory kullanır (metadata için)

  • Segment merge için CPU ve I/O harcar

  • Arama sırasında coordinating node'da birleştirilmesi gerekir

// ❌ YANLIŞ — Küçük index için aşırı shard
PUT small-index
{
  "settings": {
    "number_of_shards": 20,
    "number_of_replicas": 1
  }
}

// ✅ DOĞRU — Küçük index için az shard
PUT small-index
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  }
}

💡 İpucu: 1GB'dan küçük index'ler için 1 shard yeterlidir. Shard sayısını artırmak performans kazandırmaz, overhead ekler.


2. Shrink ve Split API — Shard Sayısını Değiştirme

Shard sayısını yanlış belirlediniz mi? Panik yok — ama bedavaya da gelmez.

Shrink API

Shard sayısını azaltır. Ama kural var: yeni shard sayısı, eskinin tam böleni olmalı. Örneğin 12 shard → 6, 4, 3, 2 veya 1 yapılabilir. 12 → 5 yapılamaz.

// 1. Adım: Index'i read-only yap ve tüm shard'ları tek node'a taşı
PUT logs-old/_settings
{
  "settings": {
    "index.routing.allocation.require._name": "node-1",
    "index.blocks.write": true
  }
}

// 2. Adım: Shrink işlemi
POST logs-old/_shrink/logs-old-shrunk
{
  "settings": {
    "index.number_of_shards": 2,
    "index.number_of_replicas": 1,
    "index.routing.allocation.require._name": null,
    "index.blocks.write": null
  }
}

Split API

Shard sayısını artırır. Yeni sayı, eskinin katı olmalı. 2 shard → 4, 6, 8... yapılabilir.

// Index'i read-only yap
PUT logs-current/_settings
{
  "settings": {
    "index.blocks.write": true
  }
}

// Split işlemi (2 → 6 shard)
POST logs-current/_split/logs-current-split
{
  "settings": {
    "index.number_of_shards": 6,
    "index.blocks.write": null
  }
}

⚠️ Dikkat: Hem shrink hem split, arka planda tüm veriyi yeniden yazan ağır operasyonlardır. Production'da off-peak saatlerde yapın.


3. Routing — Veriyi Akıllıca Yönlendirme

Varsayılan Routing

Elasticsearch, bir document'ı hangi shard'a koyacağına şu formülle karar verir:

shard_num = hash(_routing) % number_of_primary_shards

Varsayılan _routing değeri document'ın _id'sidir. Bu, verilerin shard'lara eşit dağılmasını sağlar.

Custom Routing

Peki ya belirli verileri aynı shard'da tutmak istiyorsanız? Mesela multi-tenant bir uygulamada, her müşterinin verisi aynı shard'da olsun istiyorsunuz. Böylece bir müşterinin araması tüm shard'ları taramak yerine sadece kendi shard'ını tarar — devasa performans kazancı.

// Custom routing ile document indexleme
PUT my-index/_doc/1?routing=customer_123
{
  "customer_id": "customer_123",
  "order": "Laptop",
  "amount": 15000
}

PUT my-index/_doc/2?routing=customer_123
{
  "customer_id": "customer_123",
  "order": "Mouse",
  "amount": 250
}

PUT my-index/_doc/3?routing=customer_456
{
  "customer_id": "customer_456",
  "order": "Keyboard",
  "amount": 800
}
// Arama sırasında routing belirt — sadece ilgili shard taranır
GET my-index/_search?routing=customer_123
{
  "query": {
    "match": {
      "customer_id": "customer_123"
    }
  }
}

Bu arama, 20 shard'lı bir index'te bile sadece 1 shard'ı tarar. 20x hızlanma demek bu.

Routing Zorunlu Kılma

Routing belirtmeyi unutmayı engellemek için:

PUT my-index
{
  "mappings": {
    "_routing": {
      "required": true
    }
  }
}

Routing ile Dengesiz Shard'lar (Hotspot)

Custom routing'in en büyük riski: bir müşterinin verisi çok büyükse, o shard diğerlerinden çok daha büyük olur. Buna hotspot denir.

Çözüm: routing_partition_size ile veriyi birden fazla shard'a yayabilirsiniz:

PUT my-index
{
  "settings": {
    "number_of_shards": 20,
    "routing_partition_size": 5
  },
  "mappings": {
    "_routing": {
      "required": true
    }
  }
}

Bu durumda her routing değeri 5 farklı shard'a yayılır (20 yerine 5 shard taranır — hâlâ büyük kazanç).

Java ile Custom Routing

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.IndexRequest;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;

// Document indexleme with routing
IndexRequest<Order> request = IndexRequest.of(b -> b
    .index("orders")
    .id("order-1001")
    .routing("customer_123")
    .document(new Order("customer_123", "Laptop", 15000))
);
client.index(request);

// Routing ile arama
SearchResponse<Order> response = client.search(s -> s
    .index("orders")
    .routing("customer_123")
    .query(q -> q
        .match(m -> m
            .field("customer_id")
            .query("customer_123")
        )
    ),
    Order.class
);

4. Index Lifecycle Management (ILM)

Problem: Zamana Bağlı Veri

Log, metrik, event gibi zamana bağlı veriler sürekli büyür. Bugünün logları kritik, geçen ayın logları ara sıra bakılır, geçen yılın logları neredeyse hiç okunmaz ama saklanması gerekir. Her yaştaki veriyi aynı şekilde tutmak kaynak israfıdır.

ILM Nedir?

Index Lifecycle Management, bir index'in hayat döngüsünü otomatik yöneten politikadır. Bir index doğar (hot), yaşlanır (warm), emekliye ayrılır (cold), ve sonunda ölür (delete).

Fazlar (Phases)

FazAmaçTipik Donanım
HotAktif yazma ve okumaHızlı SSD, yüksek CPU
WarmSadece okuma, yazma yokOrta SSD veya HDD
ColdNadiren okumaUcuz HDD, yavaş disk
FrozenÇok nadiren okumaShared storage (S3, etc.)
DeleteSilme

ILM Policy Oluşturma

PUT _ilm/policy/logs-policy
{
  "policy": {
    "phases": {
      "hot": {
        "min_age": "0ms",
        "actions": {
          "rollover": {
            "max_primary_shard_size": "25gb",
            "max_age": "1d"
          },
          "set_priority": {
            "priority": 100
          }
        }
      },
      "warm": {
        "min_age": "7d",
        "actions": {
          "shrink": {
            "number_of_shards": 1
          },
          "forcemerge": {
            "max_num_segments": 1
          },
          "set_priority": {
            "priority": 50
          },
          "allocate": {
            "require": {
              "data": "warm"
            }
          }
        }
      },
      "cold": {
        "min_age": "30d",
        "actions": {
          "set_priority": {
            "priority": 0
          },
          "allocate": {
            "require": {
              "data": "cold"
            }
          }
        }
      },
      "frozen": {
        "min_age": "90d",
        "actions": {
          "searchable_snapshot": {
            "snapshot_repository": "my-s3-repo"
          }
        }
      },
      "delete": {
        "min_age": "365d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

Bu policy şunu diyor:

  • Hot: Yazma ve okuma. Shard 25GB'a ulaşınca veya 1 gün geçince rollover yap.

  • Warm (7 gün sonra): Shard'ları 1'e düşür, segment'leri birleştir, warm node'lara taşı.

  • Cold (30 gün sonra): Cold node'lara taşı.

  • Frozen (90 gün sonra): Searchable snapshot olarak S3'e taşı.

  • Delete (365 gün sonra): Sil.

ILM Policy'yi Index'e Bağlama

// Index template oluştur
PUT _index_template/logs-template
{
  "index_patterns": ["logs-*"],
  "template": {
    "settings": {
      "number_of_shards": 5,
      "number_of_replicas": 1,
      "index.lifecycle.name": "logs-policy",
      "index.lifecycle.rollover_alias": "logs"
    }
  }
}

// İlk index'i alias ile oluştur
PUT logs-000001
{
  "aliases": {
    "logs": {
      "is_write_index": true
    }
  }
}

Rollover — Otomatik Index Rotasyonu

ILM'in en güçlü özelliği rollover. Belirlediğiniz koşullar sağlandığında (boyut, yaş, document sayısı) otomatik olarak yeni bir index oluşturur:

// Manuel rollover (test için)
POST logs/_rollover
{
  "conditions": {
    "max_primary_shard_size": "25gb",
    "max_age": "1d",
    "max_docs": 10000000
  }
}

// Sonuç: logs-000002 oluşur, logs alias'ı yeni index'i gösterir

ILM Durumunu Kontrol Etme

# Index'in ILM durumu
GET logs-000001/_ilm/explain

# Tüm ILM policy'leri
GET _ilm/policy

# ILM durumunu kontrol et
GET _ilm/status

Data Stream ile ILM

Elasticsearch 7.9+ ile gelen Data Streams, time-series veri için ILM'i daha da kolaylaştırır:

// Component template
PUT _component_template/logs-mappings
{
  "template": {
    "mappings": {
      "properties": {
        "@timestamp": { "type": "date" },
        "message": { "type": "text" },
        "level": { "type": "keyword" },
        "service": { "type": "keyword" }
      }
    }
  }
}

// Index template (data stream)
PUT _index_template/logs-ds-template
{
  "index_patterns": ["logs-ds-*"],
  "data_stream": {},
  "composed_of": ["logs-mappings"],
  "template": {
    "settings": {
      "index.lifecycle.name": "logs-policy"
    }
  }
}

// Data stream otomatik oluşur (ilk document yazıldığında)
POST logs-ds-app/_doc
{
  "@timestamp": "2024-01-15T10:30:00Z",
  "message": "User login successful",
  "level": "INFO",
  "service": "auth-service"
}

Data Stream avantajları:

  • Rollover alias'a gerek yok — otomatik

  • Append-only — güncelleme ve silme kısıtlı (log/metrik senaryoları için ideal)

  • @timestamp zorunlu — zamana bağlı veri garanti


5. Force Merge — Segment Optimizasyonu

Her shard birden fazla segment içerir. Yeni document'lar yeni segment'ler oluşturur. Çok fazla segment = yavaş arama.

Segment Durumunu Kontrol Etme

GET _cat/segments/logs-2024.01?v&h=index,shard,segment,size,docs.count

# Çıktı:
# index          shard segment    size   docs.count
# logs-2024.01   0     _0         1.2gb  1500000
# logs-2024.01   0     _1         800mb  1000000
# logs-2024.01   0     _2         50mb   60000
# logs-2024.01   0     _3         2mb    2500

Force Merge İşlemi

// ⚠️ Sadece yazma işlemi biten index'lerde yapın!
POST logs-2024.01/_forcemerge?max_num_segments=1

// Birden fazla index
POST logs-2024.01,logs-2024.02/_forcemerge?max_num_segments=1

⚠️ Dikkat: Force merge aktif yazma olan index'lerde yapılmamalıdır! Yeni segment'ler oluşmaya devam edeceği için merge işlemi tekrar tekrar çalışır ve I/O'yu boğar. Sadece warm/cold fazındaki, artık yazma almayan index'lerde kullanın.


6. Index Sorting — Yazma Anında Sıralama

Elasticsearch, index'e yazılan verileri belirli bir field'a göre sıralı tutabilir. Bu, o field'a göre yapılan aramalarda erken sonlandırma (early termination) sağlar.

PUT sorted-logs
{
  "settings": {
    "index": {
      "sort.field": ["@timestamp", "level"],
      "sort.order": ["desc", "asc"]
    }
  },
  "mappings": {
    "properties": {
      "@timestamp": { "type": "date" },
      "level": { "type": "keyword" },
      "message": { "type": "text" }
    }
  }
}

Bu index'te @timestamp'e göre azalan sırayla arama yapıldığında, Elasticsearch istenen sayıda sonuç bulunca geri kalan segment'leri taramadan durabilir.

💡 İpucu: Index sorting yazma performansını düşürür (her document sıralı eklenmeli), ama okuma performansını artırır. Write-heavy senaryolarda dikkatli kullanın.


7. Codec Ayarı — Sıkıştırma Stratejisi

// Varsayılan: LZ4 (hızlı sıkıştırma, orta oran)
PUT fast-index
{
  "settings": {
    "index.codec": "default"
  }
}

// best_compression: DEFLATE (yavaş sıkıştırma, yüksek oran)
PUT archive-index
{
  "settings": {
    "index.codec": "best_compression"
  }
}
CodecAlgoritmaSıkıştırma OranıYazma HızıOkuma Hızı
defaultLZ4OrtaHızlıHızlı
best_compressionDEFLATEYüksek (~%15-25 daha iyi)YavaşBiraz yavaş

Warm/cold fazındaki index'lerde best_compression kullanmak disk tasarrufu sağlar.


8. Bütünleşik Örnek: E-Commerce Log Sistemi

Gerçek dünya senaryosu: Günde 50GB log üreten bir e-ticaret platformu.

// 1. ILM Policy
PUT _ilm/policy/ecommerce-logs-policy
{
  "policy": {
    "phases": {
      "hot": {
        "min_age": "0ms",
        "actions": {
          "rollover": {
            "max_primary_shard_size": "30gb",
            "max_age": "1d"
          },
          "set_priority": {
            "priority": 100
          }
        }
      },
      "warm": {
        "min_age": "3d",
        "actions": {
          "shrink": {
            "number_of_shards": 1
          },
          "forcemerge": {
            "max_num_segments": 1
          },
          "allocate": {
            "number_of_replicas": 1,
            "require": {
              "data": "warm"
            }
          },
          "set_priority": {
            "priority": 50
          }
        }
      },
      "cold": {
        "min_age": "14d",
        "actions": {
          "readonly": {},
          "allocate": {
            "require": {
              "data": "cold"
            }
          },
          "set_priority": {
            "priority": 0
          }
        }
      },
      "delete": {
        "min_age": "90d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

// 2. Index Template (custom routing + ILM)
PUT _index_template/ecommerce-logs
{
  "index_patterns": ["ecommerce-logs-*"],
  "template": {
    "settings": {
      "number_of_shards": 3,
      "number_of_replicas": 1,
      "index.lifecycle.name": "ecommerce-logs-policy",
      "index.lifecycle.rollover_alias": "ecommerce-logs",
      "index.routing.allocation.require.data": "hot",
      "index.sort.field": ["@timestamp"],
      "index.sort.order": ["desc"]
    },
    "mappings": {
      "properties": {
        "@timestamp": { "type": "date" },
        "store_id": { "type": "keyword" },
        "event_type": { "type": "keyword" },
        "user_id": { "type": "keyword" },
        "product_id": { "type": "keyword" },
        "message": { "type": "text" },
        "response_time_ms": { "type": "integer" },
        "status_code": { "type": "short" }
      }
    }
  }
}

// 3. Bootstrap index
PUT ecommerce-logs-000001
{
  "aliases": {
    "ecommerce-logs": {
      "is_write_index": true
    }
  }
}

// 4. Veri yazma (alias üzerinden)
POST ecommerce-logs/_doc
{
  "@timestamp": "2024-01-15T14:30:00Z",
  "store_id": "store_42",
  "event_type": "purchase",
  "user_id": "user_789",
  "product_id": "prod_12345",
  "message": "Purchase completed successfully",
  "response_time_ms": 234,
  "status_code": 200
}

Java ile ILM Durumu Kontrolü

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.ilm.GetLifecycleResponse;
import co.elastic.clients.elasticsearch.ilm.ExplainLifecycleResponse;

// ILM policy'yi oku
GetLifecycleResponse lifecycle = client.ilm()
    .getLifecycle(g -> g.name("ecommerce-logs-policy"));

System.out.println("Policy phases: " + lifecycle.get("ecommerce-logs-policy").policy().phases());

// Index'in ILM durumunu kontrol et
ExplainLifecycleResponse explain = client.ilm()
    .explainLifecycle(e -> e.index("ecommerce-logs-000001"));

explain.indices().forEach((indexName, status) -> {
    System.out.println("Index: " + indexName);
    System.out.println("Phase: " + status.phase());
    System.out.println("Action: " + status.action());
    System.out.println("Age: " + status.age());
});

9. Best Practices

✅ Yap

KonuÖneri
Shard boyutu10-50GB arasında tut
Küçük index'ler1 shard yeterli
Time-series veriILM + rollover kullan
Multi-tenantCustom routing düşün
Warm/cold index'lerForce merge + best_compression
Data streamsYeni projeler için tercih et

❌ Yapma

KonuNeden
1000+ shard/nodeCluster state şişer, master node zorlanır
Aktif index'te force mergeI/O patlar, yazma yavaşlar
Routing olmadan tüm shard taramaGereksiz kaynak israfı
ILM'siz log index'leriDisk dolana kadar büyür, elle müdahale gerekir
Gereğinden fazla shardOverhead birikir, arama yavaşlar

10. Yaygın Hatalar ve Çözümleri

Hata 1: "Too Many Shards" Uyarısı

# Sorun: cluster.max_shards_per_node limitine ulaşıldı
# Çözüm 1: Gereksiz index'leri sil
DELETE old-unused-index-*

# Çözüm 2: Limiti artır (geçici çözüm, tavsiye edilmez)
PUT _cluster/settings
{
  "persistent": {
    "cluster.max_shards_per_node": 1500
  }
}

# Çözüm 3 (doğru): Index'leri shrink et veya ILM ile yönet

Hata 2: Dengesiz Shard Dağılımı

# Sorun: Bazı node'lar çok daha fazla shard barındırıyor
GET _cat/allocation?v

# Çözüm: Rebalance tetikle
POST _cluster/reroute?retry_failed=true

# Veya allocation ayarlarını kontrol et
PUT _cluster/settings
{
  "transient": {
    "cluster.routing.allocation.balance.shard": 0.45,
    "cluster.routing.allocation.balance.index": 0.55
  }
}

Hata 3: ILM Policy Uygulanmıyor

# Kontrol et
GET my-index/_ilm/explain

# Yaygın sorunlar:
# 1. ILM servisi durmuş olabilir
GET _ilm/status
# Çözüm:
POST _ilm/start

# 2. Rollover alias yok veya yanlış
# Write index flag kontrolü:
GET my-index/_alias

Hata 4: Routing Belirtmeden Arama

// ❌ Routing zorunlu ama belirtilmemiş → Hata!
GET my-index/_search
{
  "query": { "match_all": {} }
}
// routing_missing_exception hatası alırsınız

// ✅ Routing belirt
GET my-index/_search?routing=customer_123
{
  "query": { "match_all": {} }
}

11. İleri Seviye: Index Template Stratejisi

Production'da genelde tek bir index template değil, katmanlı template yapısı kullanılır:

// Component template: Ortak ayarlar
PUT _component_template/base-settings
{
  "template": {
    "settings": {
      "number_of_replicas": 1,
      "index.lifecycle.name": "default-policy"
    }
  }
}

// Component template: Log-specific mappings
PUT _component_template/log-mappings
{
  "template": {
    "mappings": {
      "properties": {
        "@timestamp": { "type": "date" },
        "message": { "type": "text" },
        "level": { "type": "keyword" },
        "host": { "type": "keyword" },
        "service": { "type": "keyword" }
      }
    }
  }
}

// Composed index template
PUT _index_template/logs-template
{
  "index_patterns": ["logs-*"],
  "composed_of": ["base-settings", "log-mappings"],
  "template": {
    "settings": {
      "number_of_shards": 3
    }
  },
  "priority": 200
}

Bu yaklaşım DRY (Don't Repeat Yourself) prensibini uygular. Ortak ayarları bir kere tanımlar, farklı index pattern'ları için birleştirirsiniz.


Özet

  1. Shard boyutu 10-50GB arasında olmalı — çok küçük overhead yaratır, çok büyük recovery'yi zorlaştırır.

  2. Custom routing ile multi-tenant senaryolarda devasa performans kazanımı sağlanır — ama hotspot riskine dikkat edin.

  3. ILM (Index Lifecycle Management) time-series veri için olmazsa olmaz — hot → warm → cold → delete döngüsünü otomatikleştirir.

  4. Rollover ile index'ler belirli boyut/yaş limitlerinde otomatik döner — elle index oluşturma derdinden kurtulursunuz.

  5. Force merge sadece yazma bitmiş index'lerde yapılır — segment sayısını azaltır, arama hızlandırır.

  6. Data Streams yeni projelerde time-series veri için en temiz çözüm — rollover alias'ın yerini alır, daha az konfigürasyon gerektirir.