Elasticsearch Performans Rehberi: Eşleme ve Sorgu

Elasticsearch, arama ve analitik iş yüklerinde yaygın kullanılan bir dağıtık veri deposudur. Ancak varsayılan ayarlarla kurulan bir küme, veri hacmi v...

Elasticsearch Performans Rehberi: Eşleme ve Sorgu

Elasticsearch, arama ve analitik iş yüklerinde yaygın kullanılan bir dağıtık veri deposudur. Ancak varsayılan ayarlarla kurulan bir küme, veri hacmi ve sorgu çeşitliliği arttıkça beklenen performansı vermez. Bu rehber, orta seviye geliştiriciler için indeksleme, sorgu ve küme düzeyinde performansı iyileştirmeye yönelik uygulanabilir adımları sıralar.

Önkoşullar ve Sürüm Kapsamı

Bu rehberdeki kavramlar ve API'ler Elasticsearch 7.x ve 8.x serilerinde geçerlidir. Sürümler arasında eşleme (mapping) türleri, güvenlik varsayılanları ve bazı API parametrelerinde farklılıklar bulunduğundan, komutları çalıştırmadan önce kullandığınız sürümün resmi dokümantasyonunu doğrulayın. Elasticsearch 7.0'dan itibaren bir indekste tek bir eşleme türü kullanılır; _type alanına dayalı eski örnekler güncel sürümlerde geçerli değildir.

Temel kavramlara (indeks, shard, replica, eşleme) aşina olduğunuzu varsayıyorum. Küme yönetimi ve üretim ortamı güvenliği bu rehberin kapsamı dışındadır.

Doğru Eşleme ile Başlayın

Performansın büyük kısmı indeksleme anında belirlenir. Dinamik eşleme, alanları otomatik olarak algılar; ancak üretimde alan tiplerini açıkça tanımlamak, hem sorgu davranışını öngörülebilir kılar hem de gereksiz indeksleme yükünü azaltır.

Aşağıdaki örnek, bir ürün indeksi için açık eşleme tanımlar:

PUT /products
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1
  },
  "mappings": {
    "properties": {
      "title":    { "type": "text" },
      "sku":      { "type": "keyword" },
      "price":    { "type": "scaled_float", "scaling_factor": 100 },
      "created_at": { "type": "date" },
      "in_stock": { "type": "boolean" }
    }
  }
}

Burada dikkat edilmesi gereken noktalar:

  • text alanlar tam metin araması için analiz edilir; keyword alanlar ise filtrelenir ve sıralanır. Aynı veriyi her iki amaçla kullanmanız gerekiyorsa çok alanlı (multi-field) tanım kullanın.
  • scaled_float, para birimi gibi ondalık değerlerde kayan noktalı sayılara göre daha az bellek kullanır ve yuvarlama sorunlarını azaltır.
  • number_of_shards değeri indeks oluşturulduktan sonra değiştirilemez. Shard sayısını veri hacminize ve düğüm sayınıza göre planlayın; çok sayıda küçük shard, arama gecikmesini artırır.

Eşleme değişikliklerinin çoğu mevcut alanlar üzerinde uygulanamaz. Bu nedenle yeni bir indeks oluşturup yeniden indeksleme (reindex) yapmak gerekir.

Sorguları Filtre ve Arama Bağlamına Ayırın

Elasticsearch'te iki bağlam vardır: sorgu bağlamı (query context) ve filtre bağlamı (filter context). Sorgu bağlamında alaka puanı hesaplanır; filtre bağlamında puan hesaplanmaz ve sonuçlar önbelleğe alınabilir. Yalnızca "eşleşsin mi" sorusunu sorduğunuz koşulları filtre bağlamına taşımak, hem daha hızlı hem de önbellek dostu sonuç verir.

GET /products/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "kablosuz kulaklık" } }
      ],
      "filter": [
        { "term":  { "in_stock": true } },
        { "range": { "price": { "lte": 3000 } } }
      ]
    }
  }
}

must içindeki match sorgusu alaka puanını etkiler; filter içindeki term ve range koşulları yalnızca sonuç kümesini daraltır. Beklenen davranış: sonuçlar alaka puanına göre sıralanır, ancak yalnızca stokta olan ve belirtilen fiyat aralığındaki belgeler döner.

Filtre bağlamındaki sorgular varsayılan olarak önbelleğe alınır. Sık değişen değerlerle (örneğin her istekte farklı bir zaman aralığı) filtre kullanmak, önbellek isabet oranını düşürür. Sık kullanılan ve yavaş çalışan filtreleri _cache ile açıkça işaretleyebilirsiniz.

Sıralama ve Sayfalama Maliyetini Yönetin

Derin sayfalama, arama performansını en hızlı düşüren etkenlerden biridir. from ve size ile büyük sayfa numaralarına gitmek, her shard'dan from + size kadar belge toplanmasını gerektirir.

Bunun yerine search_after kullanın. Bu yöntem, önceki sayfanın son belgesine ait sıralama değerlerini temel alır:

GET /products/_search
{
  "size": 20,
  "sort": [
    { "created_at": "desc" },
    { "sku": "asc" }
  ],
  "search_after": ["2024-05-01T10:00:00Z", "SKU-1234"]
}

search_after kullanırken sıralama anahtarlarının benzersiz olduğundan emin olun; aksi halde belgeler atlanabilir veya tekrar edebilir. Beklenen davranış: verilen sıralama değerlerinden sonra gelen belgeler döner. Bu yöntem, rastgele sayfa numarasına atlamayı desteklemez; sonsuz kaydırma veya "sonraki sayfa" akışları için uygundur.

Toplu İndeksleme ve Yenileme Davranışı

Tek tek belge indekslemek, her işlem için ayrı bir ağ turu ve segment oluşturma maliyeti doğurur. Bunun yerine toplu API kullanın:

POST /products/_bulk
{ "index": { "_id": "1" } }
{ "title": "Kablosuz Kulaklık", "sku": "SKU-1", "price": 1499.90, "in_stock": true }
{ "index": { "_id": "2" } }
{ "title": "Bluetooth Hoparlör", "sku": "SKU-2", "price": 899.00, "in_stock": false }

Beklenen davranış: her satır çifti bir işlem oluşturur; yanıt, her işlem için ayrı sonuç döner. Toplu isteklerde tek bir hata tüm isteği durdurmaz, bu nedenle yanıttaki errors alanını kontrol edin.

Yenileme (refresh) aralığı, indekslenen belgelerin aramada ne kadar süre sonra görünür olacağını belirler. Varsayılan değer 1 saniyedir. Yoğun yazma dönemlerinde refresh_interval değerini geçici olarak artırmak veya kapatmak indeksleme hızını belirgin şekilde iyileştirir:

PUT /products/_settings
{
  "index": {
    "refresh_interval": "30s"
  }
}

Beklenen davranış: belgeler aramada en fazla 30 saniye gecikmeyle görünür. Yazma işi bittikten sonra ayarı eski değerine döndürün; aksi halde arama tazeliği düşer.

Shard ve Replica Dengesi

Shard sayısı, arama ve indeksleme paralelliğini belirler. Ancak her shard bir maliyettir: daha fazla shard, daha fazla dosya tanıtıcısı, daha fazla segment birleştirme ve daha fazla düğümler arası koordinasyon anlamına gelir. Çok küçük indekslerde tek shard yeterlidir.

Replica sayısı, hem okuma kapasitesini artırır hem de düğüm arızasına karşı dayanıklılık sağlar. Ancak her replica, indeksleme iş yükünü çoğaltır. Yüksek yazma hacmi olan indekslerde replica sayısını dikkatli seçin.

Arama istekleri varsayılan olarak tüm shard'lara gider. Sonuç kümesini daraltan bir filtre varsa ve bu filtre shard anahtarıyla uyumluysa, routing parametresiyle yalnızca ilgili shard'a sorgu gönderebilirsiniz. Bu, gereksiz shard taramalarını önler.

Yaygın Hatalar

  • Her alanı text yapmak: Filtreleme ve sıralama için kullanılan alanlar keyword olmalıdır. Aksi halde hem disk hem de CPU maliyeti artar.
  • from/size ile derin sayfalama: Büyük ofsetlerde bellek ve gecikme hızla büyür. search_after veya scroll API'sini tercih edin.
  • Toplu isteklerde hata kontrolünü atlamak: _bulk yanıtındaki errors alanı ve tek tek işlem sonuçları kontrol edilmezse, sessiz veri kaybı oluşur.
  • Shard sayısını aşırı yükseltmek: Küçük indekslerde çok sayıda shard, arama gecikmesini artırır. Shard başına hedef boyutu veri hacminize göre planlayın.
  • refresh_interval ayarını kalıcı olarak yükseltmek: Yazma bittikten sonra geri alınmayan ayar, arama tazeliğini düşürür.

Güvenlik Etkileri

  • Kimlik doğrulama ve yetkilendirme: Elasticsearch 8.x'te güvenlik özellikleri varsayılan olarak etkindir. 7.x'te ayrı yapılandırma gerekebilir. Kimlik doğrulaması olmadan kümenizi ağa açmayın.
  • TLS: Düğümler arası ve istemci-düğüm arası trafiği şifrelemek için TLS kullanın. Şifrelenmemiş trafik, kimlik bilgilerinin ve verilerin açığa çıkmasına yol açar.
  • Sorgu enjeksiyonu: Kullanıcı girdisini doğrudan sorgu DSL'ine gömerek oluşturmayın. Özellikle script alanlarında kullanıcı girdisi kullanmak, rastgele kod çalıştırma riski taşır. Mümkünse script kullanımından kaçının; gerekiyorsa parametreleri params üzerinden geçirin.
  • Aşırı geniş sorgular: Kullanıcı tarafından tetiklenen sorgularda size ve from değerlerini sınırlayın. Sınırsız sorgular, kaynak tüketimi yoluyla hizmet dışı bırakmaya (DoS) zemin hazırlar.
  • Erişim logları ve hata mesajları: Hata yanıtları, iç yapı hakkında bilgi sızdırabilir. Üretimde ayrıntılı hata mesajlarını istemciye olduğu gibi döndürmeyin.

Sonuç

Elasticsearch performansı tek bir ayarla çözülmez; eşleme, sorgu yapısı, sayfalama yöntemi ve shard planlaması birlikte ele alınmalıdır. Filtre bağlamını doğru kullanmak, derin sayfalamadan kaçınmak, toplu indeksleme yapmak ve yenileme aralığını iş yüküne göre ayarlamak, çoğu üretim senaryosunda en yüksek getiriyi sağlar. Değişiklikleri üretime almadan önce kendi veri hacminizle ölçüm yapın; buradaki yönergeler genel ilkelerdir, kesin değerler değildir.

İLGİLİ İÇERİKLER

Bunları da Okumak İsteyebilirsiniz