Bulk İşlemler ve Reindex Stratejileri
Giriş — Bulk API Best Practices, _reindex ve Aliases
Taşınma günü düşün. Eşyalarını tek tek taşırsan — bir tabak al, arabaya koy, git, bırak, geri gel, bir bardak al... — bir hafta sürer. Ama kolilere paketleyip kamyonla taşırsan bir günde biter. Hatta profesyonel bir nakliye firması tutarsan, eşyaları sınıflandırır, paketler, yeni evde doğru odalara yerleştirir.
Elasticsearch'te Bulk API "kamyon", Reindex API "nakliye firması", Aliases ise "adres yönlendirmesi" (eski adrese gelen mektuplar yeni adrese yönlendirilsin). Bu üçü birlikte çalışarak veri taşıma, dönüştürme ve sıfır kesinti geçişi mümkün kılar.
1. Bulk API — Toplu İşlemler
Neden Bulk?
Her tekil index/update/delete işlemi bir HTTP request'tir. Her request:
TCP bağlantısı kurar
JSON parse eder
Shard'a yönlendirir
Response döner
1 milyon document için 1 milyon HTTP request = saatler. Bulk API ile bunları tek request'e paketlersiniz = dakikalar.
Bulk API Formatı
Bulk API özel bir format kullanır: NDJSON (Newline Delimited JSON). Her satır ya bir action ya da bir document body'dir.
POST _bulk
{"index": {"_index": "products", "_id": "1"}}
{"name": "Laptop", "price": 15000, "category": "electronics"}
{"index": {"_index": "products", "_id": "2"}}
{"name": "Mouse", "price": 250, "category": "electronics"}
{"create": {"_index": "products", "_id": "3"}}
{"name": "Keyboard", "price": 500, "category": "electronics"}
{"update": {"_index": "products", "_id": "1"}}
{"doc": {"price": 14500}}
{"delete": {"_index": "products", "_id": "2"}}⚠️ Dikkat: Her satır
\nile bitmeli — son satır dahil! JSON'lar tek satırda olmalı, pretty-print yapılmamalı.
Bulk Action Tipleri
| Action | Açıklama | Body Gerekir mi? |
|---|---|---|
index | Ekle veya üzerine yaz | ✅ |
create | Sadece ekle (varsa hata) | ✅ |
update | Partial update | ✅ |
delete | Sil | ❌ |
Bulk Response
{
"took": 125,
"errors": true,
"items": [
{
"index": {
"_index": "products",
"_id": "1",
"status": 201,
"result": "created"
}
},
{
"index": {
"_index": "products",
"_id": "2",
"status": 201,
"result": "created"
}
},
{
"update": {
"_index": "products",
"_id": "999",
"status": 404,
"error": {
"type": "document_missing_exception",
"reason": "[999]: document missing"
}
}
}
]
}Kritik nokta: Bulk işlem atomik değildir! Bir satır başarısız olursa diğerleri etkilenmez. Her zaman errors flag'ini kontrol edin:
// Hata kontrolü
// Response'ta "errors": true ise, items dizisini tarayın
// Her item'ın status'una bakın — 2xx = başarılı, diğer = hata2. Bulk API Best Practices
2.1. Optimal Batch Boyutu
"Ne kadar büyük batch o kadar iyi" doğru değil! Çok büyük batch'ler:
Network buffer'ı patlatır
Node'da bellek sorununa yol açar
Timeout'a düşer
Önerilen başlangıç noktası: 5-15 MB per batch veya 1000-5000 document per batch.
// İyi: 1000 document per batch
POST _bulk
{"index": {"_index": "products"}}
{"name": "Product 1", "price": 100}
{"index": {"_index": "products"}}
{"name": "Product 2", "price": 200}
// ... 998 satır daha💡 İpucu: Optimal batch boyutunu bulmak için benchmark yapın. 1000, 3000, 5000, 10000 document ile test edin. Throughput artmayı bıraktığı veya error almaya başladığınız noktanın bir altı optimal boyuttur.
2.2. Refresh Interval Ayarı
Bulk yazma sırasında her 1 saniyede bir index refresh yapmak gereksiz:
// Bulk öncesi: Refresh kapat
PUT products/_settings
{
"index.refresh_interval": "-1"
}
// Bulk işlemi yap...
POST _bulk
{"index": {"_index": "products"}}
{"name": "Product 1", "price": 100}
// ... binlerce satır
// Bulk sonrası: Refresh'i geri aç
PUT products/_settings
{
"index.refresh_interval": "1s"
}
// Manuel refresh tetikle
POST products/_refresh2.3. Replica Sayısını Azaltma
Bulk yazma sırasında her document hem primary hem replica shard'lara yazılır. Geçici olarak replica'yı kapatmak yazma hızını 2x artırabilir:
// Bulk öncesi
PUT products/_settings
{
"index.number_of_replicas": 0,
"index.refresh_interval": "-1"
}
// Bulk işlemi...
// Bulk sonrası
PUT products/_settings
{
"index.number_of_replicas": 1,
"index.refresh_interval": "1s"
}⚠️ Dikkat: Replica 0 iken node düşerse veri kaybı olur! Sadece ilk yükleme (initial load) senaryolarında yapın. Production'da aktif veri alan index'lerde yapmayın.
2.4. Pipeline ile Bulk
Bulk işlemlerinde ingest pipeline kullanabilirsiniz:
// Önce pipeline oluştur
PUT _ingest/pipeline/product-pipeline
{
"description": "Product enrichment",
"processors": [
{
"set": {
"field": "indexed_at",
"value": "{{_ingest.timestamp}}"
}
},
{
"lowercase": {
"field": "category"
}
}
]
}
// Pipeline ile bulk
POST _bulk?pipeline=product-pipeline
{"index": {"_index": "products"}}
{"name": "Laptop", "price": 15000, "category": "ELECTRONICS"}
{"index": {"_index": "products"}}
{"name": "Mouse", "price": 250, "category": "PERIPHERALS"}2.5. Routing ile Bulk
POST _bulk?routing=tenant_abc
{"index": {"_index": "orders"}}
{"tenant": "tenant_abc", "product": "Laptop", "amount": 15000}
{"index": {"_index": "orders"}}
{"tenant": "tenant_abc", "product": "Mouse", "amount": 250}
// Veya her document'a ayrı routing
POST _bulk
{"index": {"_index": "orders", "_routing": "tenant_abc"}}
{"tenant": "tenant_abc", "product": "Laptop", "amount": 15000}
{"index": {"_index": "orders", "_routing": "tenant_xyz"}}
{"tenant": "tenant_xyz", "product": "Keyboard", "amount": 500}3. Java ile Bulk İşlemler
Temel Bulk
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.BulkRequest;
import co.elastic.clients.elasticsearch.core.BulkResponse;
import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem;
// Bulk request oluştur
BulkRequest.Builder builder = new BulkRequest.Builder();
for (Product product : products) {
builder.operations(op -> op
.index(idx -> idx
.index("products")
.id(product.getId())
.document(product)
)
);
}
BulkResponse response = client.bulk(builder.build());
// Hata kontrolü
if (response.errors()) {
for (BulkResponseItem item : response.items()) {
if (item.error() != null) {
System.err.println("Error: " + item.id() +
" — " + item.error().reason());
}
}
}Batch İşleme ile Büyük Veri Seti
import java.util.List;
import java.util.ArrayList;
public class BulkIndexer {
private final ElasticsearchClient client;
private static final int BATCH_SIZE = 3000;
public BulkIndexer(ElasticsearchClient client) {
this.client = client;
}
public void indexAll(List<Product> products) throws Exception {
List<Product> batch = new ArrayList<>();
int totalSuccess = 0;
int totalFailed = 0;
for (int i = 0; i < products.size(); i++) {
batch.add(products.get(i));
if (batch.size() >= BATCH_SIZE || i == products.size() - 1) {
BulkResponse response = sendBatch(batch);
if (response.errors()) {
for (BulkResponseItem item : response.items()) {
if (item.error() != null) {
totalFailed++;
} else {
totalSuccess++;
}
}
} else {
totalSuccess += batch.size();
}
batch.clear();
System.out.printf("Progress: %d/%d (success: %d, failed: %d)%n",
i + 1, products.size(), totalSuccess, totalFailed);
}
}
}
private BulkResponse sendBatch(List<Product> batch) throws Exception {
BulkRequest.Builder builder = new BulkRequest.Builder();
for (Product p : batch) {
builder.operations(op -> op
.index(idx -> idx
.index("products")
.id(p.getId())
.document(p)
)
);
}
return client.bulk(builder.build());
}
}Retry Mekanizması
public BulkResponse bulkWithRetry(BulkRequest request, int maxRetries)
throws Exception {
BulkResponse response = client.bulk(request);
if (response.errors() && maxRetries > 0) {
// Başarısız olanları topla
BulkRequest.Builder retryBuilder = new BulkRequest.Builder();
List<BulkResponseItem> items = response.items();
for (int i = 0; i < items.size(); i++) {
BulkResponseItem item = items.get(i);
if (item.error() != null && isRetryable(item.status())) {
// Orijinal request'ten ilgili operation'ı tekrar ekle
retryBuilder.operations(
request.operations().get(i)
);
}
}
// Kısa bekleme
Thread.sleep(1000 * (4 - maxRetries));
return bulkWithRetry(retryBuilder.build(), maxRetries - 1);
}
return response;
}
private boolean isRetryable(int status) {
return status == 429 || status >= 500;
}4. Reindex API — Veri Taşıma ve Dönüştürme
Neden Reindex?
Mapping değişikliği (field tipi değiştirme)
Shard sayısını değiştirme
Analyzer değiştirme
Veri dönüştürme (enrich, filter)
Index birleştirme veya bölme
Temel Reindex
// Basit reindex — kaynak → hedef
POST _reindex
{
"source": {
"index": "products-v1"
},
"dest": {
"index": "products-v2"
}
}Reindex with Query (Filtreleyerek Taşıma)
// Sadece aktif ürünleri taşı
POST _reindex
{
"source": {
"index": "products-v1",
"query": {
"bool": {
"filter": [
{ "term": { "status": "active" } },
{ "range": { "created_at": { "gte": "2023-01-01" } } }
]
}
}
},
"dest": {
"index": "products-v2"
}
}Reindex with Script (Dönüştürerek Taşıma)
// Field adlarını değiştir, veri dönüştür
POST _reindex
{
"source": {
"index": "products-v1"
},
"dest": {
"index": "products-v2"
},
"script": {
"source": """
// Field adı değişikliği
ctx._source.product_name = ctx._source.remove('name');
// Yeni field ekle
ctx._source.migrated_at = '2024-01-15';
// Fiyatı KDV dahil yap
if (ctx._source.price != null) {
ctx._source.price_with_tax = ctx._source.price * 1.20;
}
// Belirli document'ları atla
if (ctx._source.status == 'deleted') {
ctx.op = 'noop';
}
"""
}
}Reindex with Pipeline
// Ingest pipeline ile dönüştürme
POST _reindex
{
"source": {
"index": "logs-old"
},
"dest": {
"index": "logs-new",
"pipeline": "log-enrichment-pipeline"
}
}Remote Reindex (Farklı Cluster'dan Taşıma)
POST _reindex
{
"source": {
"remote": {
"host": "https://old-cluster:9200",
"username": "elastic",
"password": "changeme",
"socket_timeout": "1m",
"connect_timeout": "10s"
},
"index": "products",
"query": {
"match_all": {}
}
},
"dest": {
"index": "products"
}
}Remote reindex için elasticsearch.yml'de whitelist gerekir:
reindex.remote.whitelist: "old-cluster:9200"Reindex Performans Ayarları
// Hızlı reindex için optimizasyon
POST _reindex?wait_for_completion=false&slices=auto
{
"source": {
"index": "logs-2024.01",
"size": 5000
},
"dest": {
"index": "logs-2024.01-v2"
},
"conflicts": "proceed"
}Parametreler:
wait_for_completion=false: Async çalıştır, task ID dönerslices=auto: Shard sayısı kadar paralel slicesize: Batch boyutu (scroll size)conflicts: proceed: Conflict'lerde durma, devam et
Async Reindex İzleme
# Task durumunu kontrol et
GET _tasks/node-1:12345
# Tüm reindex task'lerini listele
GET _tasks?detailed=true&actions=*reindex
# Task iptal et
POST _tasks/node-1:12345/_cancelReindex with Throttle
// Saniyede max 500 document (production load'u etkilemesin)
POST _reindex?requests_per_second=500
{
"source": {
"index": "products-v1"
},
"dest": {
"index": "products-v2"
}
}
// Throttle'ı runtime'da değiştir
POST _reindex/node-1:12345/_rethrottle?requests_per_second=10005. Index Aliases — Sıfır Kesinti Geçişi
Alias Nedir?
Alias, bir index'e verilen takma ad. Uygulamanız gerçek index adını bilmek zorunda kalmaz — alias kullanır. Index değiştiğinde alias'ı yeni index'e yönlendirirsiniz. Uygulama hiçbir şeyden habersiz çalışmaya devam eder.
Temel Alias İşlemleri
// Alias oluştur
POST _aliases
{
"actions": [
{
"add": {
"index": "products-v1",
"alias": "products"
}
}
]
}
// Artık "products" alias'ı üzerinden arama yapılabilir
GET products/_search
{
"query": { "match_all": {} }
}Alias Swap — Atomik Geçiş
Bu, reindex sonrası en kritik adım. Eski index'ten alias'ı kaldır, yeni index'e ekle — tek atomik operasyonda:
POST _aliases
{
"actions": [
{ "remove": { "index": "products-v1", "alias": "products" } },
{ "add": { "index": "products-v2", "alias": "products" } }
]
}Bu operasyon atomik — iki action aynı anda uygulanır. Arada boşluk yok, sorgu kaybı yok.
Write Alias
Hem okuma hem yazma alias'ı ayrı tutabilirsiniz:
POST _aliases
{
"actions": [
{
"add": {
"index": "products-v2",
"alias": "products-read"
}
},
{
"add": {
"index": "products-v2",
"alias": "products-write",
"is_write_index": true
}
}
]
}Filtered Alias
Alias'a filtre ekleyerek sanal view oluşturabilirsiniz:
POST _aliases
{
"actions": [
{
"add": {
"index": "products-v2",
"alias": "electronics",
"filter": {
"term": { "category": "electronics" }
}
}
},
{
"add": {
"index": "products-v2",
"alias": "clothing",
"filter": {
"term": { "category": "clothing" }
}
}
}
]
}
// Sadece elektronik ürünleri arar
GET electronics/_search
{
"query": { "match": { "name": "laptop" } }
}Multi-Index Alias
Birden fazla index'i tek alias altında birleştirebilirsiniz:
POST _aliases
{
"actions": [
{ "add": { "index": "logs-2024.01", "alias": "logs-recent" } },
{ "add": { "index": "logs-2024.02", "alias": "logs-recent" } },
{ "add": { "index": "logs-2024.03", "alias": "logs-recent" } }
]
}
// Son 3 ayın loglarını tek seferde ara
GET logs-recent/_search
{
"query": {
"range": {
"@timestamp": { "gte": "now-7d" }
}
}
}Alias Bilgilerini Görüntüleme
# Tüm alias'lar
GET _cat/aliases?v
# Belirli bir alias
GET _alias/products
# Belirli bir index'in alias'ları
GET products-v2/_alias6. Bütünleşik Örnek: Zero-Downtime Migration
Senaryo: products-v1 index'inde mapping hatası var. description field'ı keyword olarak tanımlanmış, text olmalıydı. Analyzer da eklenmeli. Sıfır kesinti ile geçiş yapacağız.
Adım 1: Mevcut Durumu Kontrol Et
# Mevcut alias yapısı
GET _alias/products
# Sonuç: products → products-v1
# Mevcut mapping
GET products-v1/_mappingAdım 2: Yeni Index'i Doğru Mapping ile Oluştur
PUT products-v2
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"analysis": {
"analyzer": {
"turkish_custom": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase", "turkish_stop", "turkish_stem"]
}
},
"filter": {
"turkish_stop": {
"type": "stop",
"stopwords": "_turkish_"
},
"turkish_stem": {
"type": "stemmer",
"language": "turkish"
}
}
}
},
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "turkish_custom",
"fields": {
"keyword": { "type": "keyword" }
}
},
"description": {
"type": "text",
"analyzer": "turkish_custom"
},
"price": { "type": "float" },
"category": { "type": "keyword" },
"status": { "type": "keyword" },
"created_at": { "type": "date" }
}
}
}Adım 3: Reindex (Dönüştürerek Taşıma)
// Yeni index'in yazma performansını artır
PUT products-v2/_settings
{
"index.refresh_interval": "-1",
"index.number_of_replicas": 0
}
// Reindex başlat
POST _reindex?wait_for_completion=false
{
"source": {
"index": "products-v1",
"size": 5000
},
"dest": {
"index": "products-v2"
},
"script": {
"source": """
// Status field'ı standartlaştır
if (ctx._source.status == 'aktif') {
ctx._source.status = 'active';
}
// Silinen ürünleri atla
if (ctx._source.status == 'deleted') {
ctx.op = 'noop';
}
"""
}
}
// Task ID al ve izle
GET _tasks?detailed=true&actions=*reindexAdım 4: Reindex Tamamlandıktan Sonra
// Ayarları geri al
PUT products-v2/_settings
{
"index.refresh_interval": "1s",
"index.number_of_replicas": 1
}
// Refresh zorla
POST products-v2/_refresh
// Document sayısını karşılaştır
GET _cat/count/products-v1?v
GET _cat/count/products-v2?vAdım 5: Atomik Alias Swap
POST _aliases
{
"actions": [
{ "remove": { "index": "products-v1", "alias": "products" } },
{ "add": { "index": "products-v2", "alias": "products" } }
]
}Adım 6: Doğrulama ve Temizlik
// Yeni index'ten arama test
GET products/_search
{
"query": {
"match": {
"description": "harika bir ürün"
}
}
}
// Her şey OK ise eski index'i sil
DELETE products-v1Bu Sürecin Java Otomasyonu
public class ZeroDowntimeMigration {
private final ElasticsearchClient client;
public void migrate(String sourceIndex, String destIndex,
String aliasName) throws Exception {
// 1. Yeni index'i oluştur (mapping ayrıca tanımlanmış olmalı)
// 2. Performans ayarları
client.indices().putSettings(s -> s
.index(destIndex)
.settings(st -> st
.refreshInterval(t -> t.time("-1"))
.numberOfReplicas("0")
)
);
// 3. Reindex
var reindexResponse = client.reindex(r -> r
.source(src -> src.index(sourceIndex).size(5000))
.dest(dst -> dst.index(destIndex))
.waitForCompletion(false)
);
String taskId = reindexResponse.task();
System.out.println("Reindex task started: " + taskId);
// 4. Task'i izle
waitForTask(taskId);
// 5. Ayarları geri al
client.indices().putSettings(s -> s
.index(destIndex)
.settings(st -> st
.refreshInterval(t -> t.time("1s"))
.numberOfReplicas("1")
)
);
client.indices().refresh(r -> r.index(destIndex));
// 6. Atomik alias swap
client.indices().updateAliases(a -> a
.actions(act -> act.remove(rm -> rm
.index(sourceIndex)
.alias(aliasName)
))
.actions(act -> act.add(ad -> ad
.index(destIndex)
.alias(aliasName)
))
);
System.out.println("Migration complete! Alias '" +
aliasName + "' now points to '" + destIndex + "'");
}
private void waitForTask(String taskId) throws Exception {
while (true) {
var task = client.tasks().get(g -> g.taskId(taskId));
if (task.completed()) {
System.out.println("Reindex completed!");
break;
}
var status = task.task().status();
System.out.println("Progress: " + status);
Thread.sleep(5000);
}
}
}7. Update by Query — Toplu Güncelleme
Reindex gibi ama aynı index üzerinde çalışır:
// Tüm "draft" status'lu ürünleri "pending_review" yap
POST products/_update_by_query
{
"query": {
"term": { "status": "draft" }
},
"script": {
"source": "ctx._source.status = 'pending_review'; ctx._source.updated_at = params.now",
"params": {
"now": "2024-01-15T14:00:00Z"
}
}
}
// Async ve throttled
POST products/_update_by_query?wait_for_completion=false&requests_per_second=500&conflicts=proceed
{
"query": {
"range": {
"created_at": { "lt": "2023-01-01" }
}
},
"script": {
"source": "ctx._source.archived = true"
}
}Delete by Query
// Belirli koşula uyan document'ları toplu silme
POST products/_delete_by_query
{
"query": {
"bool": {
"filter": [
{ "term": { "status": "deleted" } },
{ "range": { "deleted_at": { "lt": "now-90d" } } }
]
}
}
}
// Async ve throttled
POST logs/_delete_by_query?wait_for_completion=false&requests_per_second=1000
{
"query": {
"range": {
"@timestamp": { "lt": "now-180d" }
}
}
}8. Best Practices
✅ Yap
| Konu | Öneri |
|---|---|
| Batch boyutu | 5-15MB veya 1000-5000 doc/batch — benchmark ile belirle |
| Bulk öncesi | Refresh interval -1, replica 0 (initial load) |
| Reindex | wait_for_completion=false ile async çalıştır |
| Alias | Her zaman alias üzerinden oku/yaz — doğrudan index adı kullanma |
| Alias swap | Tek atomik operasyonda yap — ayrı remove + add yapmayın |
| Throttle | Production'da requests_per_second ile throttle kullan |
| Hata kontrolü | Bulk response'ta errors flag'ini mutlaka kontrol et |
❌ Yapma
| Konu | Neden |
|---|---|
| Tek tek HTTP request | Her request overhead yaratır, bulk kullan |
| 100MB batch | Memory patlatır, timeout alırsın |
| Reindex sırasında replica 2 | Her document 3 kopyaya yazılır, çok yavaş |
| Alias'sız doğrudan index adı | Migration'da uygulama kodunu değiştirmek zorunda kalırsın |
| Sync reindex (büyük data) | HTTP timeout'a düşer, async kullan |
9. Yaygın Hatalar ve Çözümleri
Hata 1: Bulk Request Parse Error
// Sorun: "Malformed action/metadata line"
// Neden: JSON pretty-print veya eksik newline
// ❌ YANLIŞ — Pretty-printed JSON
POST _bulk
{
"index": {
"_index": "products",
"_id": "1"
}
}
{
"name": "Laptop"
}
// ✅ DOĞRU — Tek satırda
POST _bulk
{"index": {"_index": "products", "_id": "1"}}
{"name": "Laptop"}Hata 2: Version Conflict (Reindex)
// Sorun: Reindex sırasında kaynak index'e yazma oluyor → conflict
// Çözüm: conflicts: proceed
POST _reindex
{
"conflicts": "proceed",
"source": { "index": "products-v1" },
"dest": { "index": "products-v2" }
}Hata 3: Reindex Çok Yavaş
// Sorun: Reindex saatler sürüyor
// Çözüm 1: Slicing ile paralelize et
POST _reindex?slices=auto
{
"source": { "index": "large-index" },
"dest": { "index": "large-index-v2" }
}
// Çözüm 2: Hedef index'i optimize et
PUT large-index-v2/_settings
{
"index.refresh_interval": "-1",
"index.number_of_replicas": 0,
"index.translog.durability": "async",
"index.translog.flush_threshold_size": "1gb"
}Hata 4: Alias Çakışması
// Sorun: Yeni index adı mevcut bir alias ile aynı
// ES hata verir: "index and alias have the same name"
// Çözüm: Index ve alias adlarını farklı tut
// Konvansiyon:
// Index: products-v1, products-v2, products-v3
// Alias: products (read), products-write (write)Hata 5: Bulk Timeout
// Sorun: Bulk işlem timeout'a düşüyor
// Çözüm 1: Batch boyutunu küçült
// Çözüm 2: Timeout'u artır
POST _bulk?timeout=5m
{"index": {"_index": "products"}}
{"name": "Product 1"}
// ...10. Reindex Alternatifleri: Ne Zaman Hangisi?
| Senaryo | Çözüm |
|---|---|
| Mapping değişikliği | _reindex + alias swap |
| Aynı index'te toplu güncelleme | _update_by_query |
| Toplu silme | _delete_by_query |
| Farklı cluster'a taşıma | Remote _reindex |
| Shard sayısı azaltma | _shrink API |
| Shard sayısı artırma | _split API |
| Harici veri kaynağından yükleme | Logstash veya Bulk API |
| Günlük index rotasyonu | ILM + Rollover |
Özet
Bulk API toplu işlemler için zorunlu — tek tek HTTP request göndermek kabul edilemez performans kaybı yaratır.
Optimal batch boyutu 5-15MB — benchmark ile kendi ortamınız için ince ayar yapın. Çok büyük batch timeout, çok küçük batch overhead yaratır.
Reindex API mapping değişikliği, veri dönüşümü ve cluster arası taşıma için kullanılır —
slices=autoile paralelize edin,wait_for_completion=falseile async çalıştırın.Aliases production'da olmazsa olmaz — uygulama kodunuz asla doğrudan index adını bilmemeli. Alias swap ile sıfır kesinti geçişi yapılır.
Atomik alias swap ile eski index'ten yenisine geçiş tek operasyonda yapılır — arada boşluk yok, sorgu kaybı yok.
Bulk öncesi optimizasyon (refresh kapatma, replica azaltma) yazma hızını dramatik artırır — ama sadece ilk yükleme senaryolarında güvenlidir.
AI Asistan
Sorularını yanıtlamaya hazır