Buyukweb
Elasticsearch Kurulumu ve Temel Arama Operasyonları

Elasticsearch Kurulumu ve Temel Arama Operasyonları

Elasticsearch kurulumu, index yönetimi, belge CRUD operasyonları ve temel arama sorguları. Full-text search, filtreleme ve aggregation kullanımı.

Büyükweb Editör EkibiHosting, Sunucu ve Sistem Yönetimi Editörü13 dakika okuma

Elasticsearch Kurulumu ve Temel Arama Operasyonları

Elasticsearch, dağıtık, RESTful arama ve analitik motorudur. Apache Lucene üzerine inşa edilmiştir. Log analizi, full-text arama ve gerçek zamanlı analitik için kullanılır.

Elasticsearch Ne İçin Kullanılır?

  • Full-text search: Web sitesi veya uygulama arama
  • Log analizi: ELK Stack (Elasticsearch + Logstash + Kibana)
  • Metrics: Sunucu ve uygulama metrikleri
  • E-ticaret arama: Ürün arama ve filtreleme
  • APM: Uygulama performans izleme

Kurulum (Ubuntu/Debian)

# GPG anahtarı ve repo ekle
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | tee /etc/apt/sources.list.d/elastic-8.x.list

apt update
apt install elasticsearch

# Başlat
systemctl enable --now elasticsearch

# Durum
curl -X GET "localhost:9200/"

Temel Yapılandırma

# /etc/elasticsearch/elasticsearch.yml
cluster.name: my-cluster
node.name: node-1

# Veri ve log dizinleri
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

# Ağ ayarları (sadece lokal için)
network.host: 127.0.0.1
http.port: 9200

# JVM heap (RAM'in ~%50'si, max 32GB)
# -Xms2g -Xmx2g  → /etc/elasticsearch/jvm.options

REST API ile Temel Operasyonlar

Elasticsearch HTTP REST API kullanır:

# Cluster bilgisi
curl -X GET "localhost:9200/"
curl -X GET "localhost:9200/_cluster/health?pretty"

# Index listesi
curl -X GET "localhost:9200/_cat/indices?v"

# Node bilgisi
curl -X GET "localhost:9200/_cat/nodes?v"

Index Yönetimi

# Index oluştur
curl -X PUT "localhost:9200/urunler" -H "Content-Type: application/json" -d '{
    "settings": {
        "number_of_shards": 1,
        "number_of_replicas": 0
    },
    "mappings": {
        "properties": {
            "isim": { "type": "text", "analyzer": "turkish" },
            "fiyat": { "type": "double" },
            "kategori": { "type": "keyword" },
            "stok": { "type": "integer" },
            "olusturulma": { "type": "date" }
        }
    }
}'

# Index sil
curl -X DELETE "localhost:9200/urunler"

# Index ayarları güncelle
curl -X PUT "localhost:9200/urunler/_settings" -H "Content-Type: application/json" -d '{
    "number_of_replicas": 1
}'

Belge CRUD

Create (Ekle):

# Belge ekle (ID otomatik)
curl -X POST "localhost:9200/urunler/_doc" -H "Content-Type: application/json" -d '{
    "isim": "Laptop Dell XPS",
    "fiyat": 25000,
    "kategori": "elektronik",
    "stok": 50,
    "ozellikler": ["16GB RAM", "SSD 512GB", "i7"]
}'

# Belge ekle (belirli ID)
curl -X PUT "localhost:9200/urunler/_doc/1" -H "Content-Type: application/json" -d '{
    "isim": "Wireless Mouse",
    "fiyat": 350,
    "kategori": "elektronik"
}'

Read (Oku):

# Belge getir
curl -X GET "localhost:9200/urunler/_doc/1"

# Birden fazla belge
curl -X GET "localhost:9200/urunler/_mget" -H "Content-Type: application/json" -d '{
    "ids": ["1", "2", "3"]
}'

Update (Güncelle):

curl -X POST "localhost:9200/urunler/_update/1" -H "Content-Type: application/json" -d '{
    "doc": { "fiyat": 380 }
}'

Delete (Sil):

curl -X DELETE "localhost:9200/urunler/_doc/1"

Arama Sorguları

Basit Arama:

# Tüm belgeleri al
curl -X GET "localhost:9200/urunler/_search?pretty"

# Full-text arama
curl -X GET "localhost:9200/urunler/_search?pretty" -H "Content-Type: application/json" -d '{
    "query": {
        "match": { "isim": "laptop dell" }
    }
}'

Filtreleme:

curl -X GET "localhost:9200/urunler/_search?pretty" -H "Content-Type: application/json" -d '{
    "query": {
        "bool": {
            "must": [
                { "match": { "kategori": "elektronik" } }
            ],
            "filter": [
                { "range": { "fiyat": { "gte": 100, "lte": 5000 } } },
                { "term": { "stok": { "gt": 0 } } }
            ]
        }
    },
    "sort": [{ "fiyat": "asc" }],
    "_source": ["isim", "fiyat", "kategori"],
    "from": 0,
    "size": 10
}'

Multi-match (Birden fazla alanda):

curl -X GET "localhost:9200/urunler/_search?pretty" -H "Content-Type: application/json" -d '{
    "query": {
        "multi_match": {
            "query": "dell laptop",
            "fields": ["isim^2", "aciklama"]
        }
    }
}'

Aggregation (Gruplama/İstatistik)

curl -X GET "localhost:9200/urunler/_search?pretty" -H "Content-Type: application/json" -d '{
    "size": 0,
    "aggs": {
        "kategoriye_gore": {
            "terms": { "field": "kategori" }
        },
        "fiyat_istatistik": {
            "stats": { "field": "fiyat" }
        },
        "fiyat_aralik": {
            "range": {
                "field": "fiyat",
                "ranges": [
                    { "to": 1000 },
                    { "from": 1000, "to": 5000 },
                    { "from": 5000 }
                ]
            }
        }
    }
}'

Türkçe Analiz

# Türkçe analyzer ile index
curl -X PUT "localhost:9200/turkce_icerik" -H "Content-Type: application/json" -d '{
    "settings": {
        "analysis": {
            "analyzer": {
                "turkish_analyzer": {
                    "type": "custom",
                    "tokenizer": "standard",
                    "filter": ["lowercase", "turkish_stop", "snowball"]
                }
            }
        }
    }
}'

Kibana Kurulumu

apt install kibana
systemctl enable --now kibana

# Tarayıcıdan: http://localhost:5601

[Büyükweb VDS sunucularında](MASK36) ELK Stack kurarak log analizi ve full-text arama altyapısı oluşturabilirsiniz.

Elasticsearch vs OpenSearch — Lisans Değişimi

2021'de Elastic NV lisansını SSPL/Elastic License'a değiştirdi (artık Apache 2.0 değil). Topluluk bu durumu kabul etmedi → OpenSearch projesini fork etti:

Elasticsearch (Elastic) OpenSearch (Topluluk)
Lisans Elastic License v2 (BSL benzeri) Apache 2.0 (gerçek open source)
Hosting Elastic Cloud, kendi sunucu Topluluk fork hosting, kendi sunucu
X-Pack Premium tier'da Tamamı açık
Dashboards Kibana OpenSearch Dashboards
Aktif gelişim ✓ büyük ekip ✓ topluluk + bakım ekibi
Lucene tabanlı
Vector search ✓ (8.x) ✓ (k-NN plugin)

Karar matrisi:

  • Self-hosted, ücretsiz max: OpenSearch (X-Pack özellikleri ücretsiz)
  • Elastic ekosistem (Beats, APM, Kibana plugins): Elasticsearch
  • Yönetilen alternatif: OpenSearch (yurt dışı bulut sağlayıcıların yönetilen servisi olarak sunulur)
  • SaaS (managed Elastic): Elastic Cloud

Türkiye projeleri için OpenSearch maliyet avantajlı; ekosistem eskidir ama yeterince güçlüdür.

Cluster Topology — Production Setup

Tek node sadece dev/test için. Production minimum 3 master-eligible + 2+ data node:

# elasticsearch.yml — node-1 (master-only)
cluster.name: prod-cluster
node.name: master-1
node.roles: [master]
network.host: 10.0.0.1
discovery.seed_hosts: ["10.0.0.1", "10.0.0.2", "10.0.0.3"]
cluster.initial_master_nodes: ["master-1", "master-2", "master-3"]

# node-4 (data-hot)
node.name: data-hot-1
node.roles: [data_hot, data_content, ingest]
node.attr.data_tier: hot

# node-5 (data-warm)
node.name: data-warm-1
node.roles: [data_warm]
node.attr.data_tier: warm

# Coordinating-only node (load balancer)
node.name: coord-1
node.roles: []

Neden 3 master? Quorum (n/2 + 1) için. 3 master = 2 quorum → 1 master kaybedilebilir. Asla 2 master kullanma (split-brain riski).

Shard Sayısı Hesaplama

number_of_shards index oluşturulduktan sonra değiştirilemez (reindex gerekir). Doğru baştan ayarla:

Index boyutu Shard sayısı Replica
< 10 GB 1 1
10-50 GB 2-3 1
50-200 GB 4-8 1
200 GB - 1 TB 8-20 1-2
> 1 TB rollover ile bölünmeli 1-2

Genel kurallar:

  • Hedef shard boyutu 20-40 GB (max 50 GB)
  • Shard sayısı: (toplam_boyut / 30 GB) yuvarla up
  • Heap üstüne çok shard = bellek bottleneck (her shard ~1 KB heap baseline)
  • ~1000 shard / 32 GB heap RAM cluster sınırı
# Mevcut shard durumu
curl localhost:9200/_cat/shards?v
curl localhost:9200/_cluster/health?level=indices

Index Lifecycle Management (ILM)

Log/time-series için otomatik tier movement + cleanup:

# ILM policy — hot/warm/cold/delete
curl -X PUT "localhost:9200/_ilm/policy/logs-policy" -H "Content-Type: application/json" -d '{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": { "max_size": "30gb", "max_age": "7d" }
        }
      },
      "warm": {
        "min_age": "7d",
        "actions": {
          "shrink": { "number_of_shards": 1 },
          "forcemerge": { "max_num_segments": 1 },
          "allocate": { "include": { "data_tier": "warm" } }
        }
      },
      "cold": {
        "min_age": "30d",
        "actions": {
          "allocate": { "include": { "data_tier": "cold" } },
          "freeze": {}
        }
      },
      "delete": {
        "min_age": "365d",
        "actions": { "delete": {} }
      }
    }
  }
}'

# Index template — yeni index'leri policy'e bağla
curl -X PUT "localhost:9200/_index_template/logs-template" -H "Content-Type: application/json" -d '{
  "index_patterns": ["logs-*"],
  "template": {
    "settings": {
      "index.lifecycle.name": "logs-policy",
      "index.lifecycle.rollover_alias": "logs"
    }
  }
}'

# Initial index + alias
curl -X PUT "localhost:9200/logs-000001" -H "Content-Type: application/json" -d '{
  "aliases": { "logs": { "is_write_index": true } }
}'

Sonuç: İlk 7 gün hot (NVMe), sonra warm (HDD), 30 gün sonra cold (frozen tier — S3 searchable snapshot), 1 yıl sonra otomatik silinir. Disk maliyeti %80 azalır.

Snapshot ve Restore (Backup)

# S3 repository tanımla
curl -X PUT "localhost:9200/_snapshot/s3_backup" -H "Content-Type: application/json" -d '{
  "type": "s3",
  "settings": {
    "bucket": "my-elasticsearch-backups",
    "region": "eu-central-1"
  }
}'

# Snapshot al
curl -X PUT "localhost:9200/_snapshot/s3_backup/snap-2026-05-07?wait_for_completion=true" -H "Content-Type: application/json" -d '{
  "indices": "logs-*,products",
  "include_global_state": false
}'

# Snapshot listesi
curl -X GET "localhost:9200/_snapshot/s3_backup/_all"

# Restore
curl -X POST "localhost:9200/_snapshot/s3_backup/snap-2026-05-07/_restore" -H "Content-Type: application/json" -d '{
  "indices": "products",
  "rename_pattern": "products",
  "rename_replacement": "products-restored"
}'

# SLM (Snapshot Lifecycle Management) — otomatik yedek
curl -X PUT "localhost:9200/_slm/policy/daily-snapshot" -H "Content-Type: application/json" -d '{
  "schedule": "0 30 1 * * ?",
  "name": "<daily-snap-{now/d}>",
  "repository": "s3_backup",
  "config": { "indices": ["*"] },
  "retention": { "expire_after": "30d", "min_count": 5, "max_count": 50 }
}'

Türkçe Analyzer — Profesyonel Setup

Default turkish analyzer temel; production için ICU + custom synonym + lemmatizer:

# ICU plugin kur
bin/elasticsearch-plugin install analysis-icu

# Synonym dosyası
cat > /etc/elasticsearch/analysis/turkish_synonyms.txt <<EOF
hosting, web hosting, web barindirma
sunucu, server
vds, virtual dedicated server, sanal sunucu
ssl, https, sertifika
EOF
curl -X PUT "localhost:9200/turkish_content" -H "Content-Type: application/json" -d '{
  "settings": {
    "analysis": {
      "filter": {
        "turkish_lowercase": {
          "type": "icu_normalizer",
          "name": "nfkc_cf"
        },
        "turkish_synonym": {
          "type": "synonym",
          "synonyms_path": "analysis/turkish_synonyms.txt"
        },
        "turkish_stop": {
          "type": "stop",
          "stopwords": "_turkish_"
        },
        "turkish_stemmer": {
          "type": "stemmer",
          "language": "turkish"
        }
      },
      "analyzer": {
        "my_turkish": {
          "tokenizer": "icu_tokenizer",
          "filter": [
            "turkish_lowercase",
            "turkish_synonym",
            "turkish_stop",
            "turkish_stemmer"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title":   { "type": "text", "analyzer": "my_turkish" },
      "content": { "type": "text", "analyzer": "my_turkish" }
    }
  }
}'

# Test
curl -X POST "localhost:9200/turkish_content/_analyze" -H "Content-Type: application/json" -d '{
  "analyzer": "my_turkish",
  "text": "Web hosting paketleri Türkiye sunucu"
}'

ICU tokenizer Türkçe ı/i/ş/ç/ğ doğru handle eder; default'tan farkı belirgin.

Performance Tuning

# /etc/elasticsearch/jvm.options
-Xms16g
-Xmx16g

# Heap = RAM/2, max 31 GB (compressed oops sınırı)
# Index seviyesinde performans
curl -X PUT "localhost:9200/products/_settings" -H "Content-Type: application/json" -d '{
  "index": {
    "refresh_interval": "30s",                # default 1s; bulk write için artır
    "translog": {
      "durability": "async",                  # default request; async batch için
      "sync_interval": "30s"
    },
    "number_of_replicas": 0                   # bulk insert sırasında 0, sonra 1
  }
}'

# Bulk indexing optimal batch
# 5-15 MB batch size, 4-8 paralel worker

# Force merge (write-once index'lerde)
curl -X POST "localhost:9200/old-logs-2025/_forcemerge?max_num_segments=1"

Query Optimization — Filter vs Query Context

{
  "query": {
    "bool": {
      "must": [                                  // SCORE hesaplar
        { "match": { "title": "laptop" } }
      ],
      "filter": [                                // SCORE hesaplamaz, CACHE'lenir
        { "term": { "category": "electronics" } },
        { "range": { "price": { "lte": 5000 } } }
      ]
    }
  }
}

Kural: Relevance gerekmiyorsa filter context kullan — 2-10x hızlı, cached.

# Query profiling — hangi adım yavaş?
curl -X GET "localhost:9200/products/_search?pretty" -H "Content-Type: application/json" -d '{
  "profile": true,
  "query": { ... }
}'

Vector Search — RAG / AI

ES 8+ ve OpenSearch 2+ dense_vector + kNN search desteği:

# Index — embedding alanı
curl -X PUT "localhost:9200/docs" -H "Content-Type: application/json" -d '{
  "mappings": {
    "properties": {
      "title": { "type": "text" },
      "embedding": {
        "type": "dense_vector",
        "dims": 1536,                          // OpenAI ada-002
        "index": true,
        "similarity": "cosine"
      }
    }
  }
}'

# Belge ekle (embedding API'sinden gelen vektör ile)
curl -X POST "localhost:9200/docs/_doc" -H "Content-Type: application/json" -d '{
  "title": "MongoDB rehberi",
  "embedding": [0.123, 0.456, ...]
}'

# kNN search
curl -X GET "localhost:9200/docs/_search" -H "Content-Type: application/json" -d '{
  "knn": {
    "field": "embedding",
    "query_vector": [0.111, 0.222, ...],
    "k": 5,
    "num_candidates": 100
  },
  "_source": ["title"]
}'

LLM uygulamalarında RAG (Retrieval Augmented Generation) için ideal — kullanıcı sorgusu → embedding → ES kNN search → relevant doc'lar → LLM context.

Security — X-Pack/Default ON (8.x)

ES 8'den itibaren default güvenlik aktif (eski sürümlerde manual kapatılırdı):

# İlk kurulumda — default şifre üretilir
/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic

# Kullanıcı + role
curl -X POST -u elastic:pass "localhost:9200/_security/role/blog_search" -H "Content-Type: application/json" -d '{
  "indices": [
    {
      "names": ["blog-*"],
      "privileges": ["read", "view_index_metadata"]
    }
  ]
}'

curl -X POST -u elastic:pass "localhost:9200/_security/user/app_user" -H "Content-Type: application/json" -d '{
  "password": "guclu_sifre",
  "roles": ["blog_search"]
}'

# API key (uygulama için preferred)
curl -X POST -u elastic:pass "localhost:9200/_security/api_key" -H "Content-Type: application/json" -d '{
  "name": "blog-api",
  "expiration": "30d",
  "role_descriptors": { "blog_role": { "indices": [...] } }
}'

TLS: xpack.security.transport.ssl.enabled: true ile node-to-node şifreli iletişim. Production'da şart.

Pratik Use Case'ler

E-ticaret arama:

  • ürün indeksi (1M+ ürün) + Türkçe analyzer + synonym
  • price range, kategori filter, stok filter
  • "öneri" için kNN (alternatif ürünler)
  • aggregation ile facet (marka, fiyat aralığı, renk)

Log analizi (ELK Stack):

  • Filebeat → Logstash → Elasticsearch → Kibana
  • ILM ile hot/warm/cold rotation
  • Saved searches + alerting

Site search:

  • Blog/içerik full-text search
  • Did-you-mean (suggester)
  • Autocomplete (search-as-you-type)

APM:

  • Elastic APM agent → ES → APM UI
  • Distributed tracing
  • Error tracking + slow transaction

Sıkça Sorulan Sorular

"ES 1 node yeterli mi?"

Dev/test için evet. Production için minimum 3 node (master quorum). Tek node failure tolerance yok — disk arızası = data loss.

Heap niye max 31 GB?

JVM compressed oops (32-bit pointer + 64-bit reference) ile bellek tasarrufu. 32 GB üstünde compressed oops disable → bellek kullanımı patlak verir, performans düşer. 31 GB'a kadar; üstü için ayrı node ekle.

Reindex çok yavaş — hızlandırma?

# Replica'ları geçici disable
curl -X PUT "localhost:9200/target/_settings" -d '{"number_of_replicas": 0}'

# Refresh interval artır
curl -X PUT "localhost:9200/target/_settings" -d '{"refresh_interval": "60s"}'

# Reindex paralel slice
curl -X POST "localhost:9200/_reindex?wait_for_completion=false&slices=auto" -d '{...}'

# Bittikten sonra geri al
curl -X PUT "localhost:9200/target/_settings" -d '{"number_of_replicas": 1, "refresh_interval": "1s"}'

"Elasticsearch unassigned shards" hatası?

curl localhost:9200/_cluster/allocation/explain?pretty

Yaygın sebepler: 1) Disk full (high watermark) 2) Node stop/down 3) Replica yetersiz node 4) Shard allocation filtering yanlış. Çözüm sebebe göre değişir.

MySQL/PostgreSQL yerine Elasticsearch koyabilir miyim?

Hayır — ES transactional değil (ACID yok). Source of truth ilişkisel DB olmalı; ES denormalize edilmiş arama indeksi olarak. Logstash veya custom pipeline ile sync.

WordPress için Elasticsearch?

ElasticPress plugin ile WP search'ü ES'e yönlendirebilirsiniz. Avantaj: 100K+ post'lu sitelerde MySQL search'ten 100x hızlı + relevance daha iyi. Ücretsiz; ES sunucusu ek 2 GB RAM gerektirir.

Türkçe arama default'ta yeterli mi?

turkish analyzer kabul edilebilir ama gerçek production için yetersiz — ICU tokenizer + custom synonym dictionary + custom stop word eklemek gerekir. Yukarıdaki örnek ideal başlangıç.

Vector search ne kadar pahalı?

Disk: 1M doc × 1536 dim × 4 byte = ~6 GB. Heap: indexed dense_vector için ~2 GB. Query: <100ms p99 (1M doc'ta). RAG uygulamasının ölçek sınırı genelde LLM API maliyeti, ES değil.

OpenSearch'e migrate etmek zor mu?

Aynı API'ler %95+ uyumlu. Snapshot al → OpenSearch'e restore → çalışır. Logstash, Beats, küçük config değişikliği. Self-hosted ücretsiz X-Pack özellikleri için yaygın migration yolu 2024'ten beri.

Plugin (analysis-icu, mapper-attachments) güncelleme?

Plugin'ler ES sürümüne bağlıdır. Major upgrade'de yeni sürüm pluginlerini yeniden kur. bin/elasticsearch-plugin list ile kontrol; elasticsearch-plugin install --batch <name> ile reinstall.

Büyükweb'de Elasticsearch Hosting

Büyükweb VDS paketleri Elasticsearch için ideal:

  • 8-16 GB RAM — küçük cluster (single node + 100K-1M doc)
  • 32+ GB RAM — production cluster (3+ node, 10M+ doc)
  • 64+ GB RAM + NVMe — büyük log cluster (TB seviyesi, ELK stack)

E5v4 VDS yüksek single-thread performans ES için ideal. Multi-node cluster için ayrı VDS'ler ile özel iç ağ.

Fiziksel dedicated yüksek disk I/O + RAM ihtiyaçı varsa — büyük production cluster, yüksek arama RPS.

cPanel/paylaşımlı hosting'de Elasticsearch çalışmaz — root erişim ve dedicated RAM gerekir.

Yapılandırma desteği için 0850 302 60 70.

İlgili Rehberler

İlgili Büyükweb Hizmetleri

Veritabanı performansı ve güvenilirliği için Türkiye lokasyonlu sunucu paketlerimiz:

Sorularınız için 0850 302 60 70 numaralı destek hattımıza veya iletişim sayfamıza yazabilirsiniz.

Veritabanı Yönetimi İlgili Hizmetlerimiz

Bu yazıda anlatılan teknik konuyu profesyonel altyapıyla deneyimleyin

Etiketler:

#elasticsearch#kurulum rehberi#veritabanı#database#veri yönetimi

Bu yazıyı paylaş