Cluster Health ve Shard Allocation
Giriş — Green/Yellow/Red ve Allocation Explain
Bir apartmanın yönetim sistemi düşün. Her dairede oturan var (primary shard), her dairenin bir de yedek anahtarı var komşuda (replica shard). Apartman yöneticisi (master node) kimin nerede oturduğunu takip eder. Herkes yerindeyse durum yeşil. Birinin yedek anahtarı kaybolmuşsa sarı — acil değil ama riskli. Birinin dairesi yanmışsa (primary shard kayıp) kırmızı — acil müdahale gerek.
Cluster health ve shard allocation, Elasticsearch yönetiminin en temel konusu. Production'da "cluster neden sarı?" sorusuna 30 saniyede cevap verebilmek olmazsa olmaz bir beceri. Bu derste bu beceriyi kazanacaksınız.
1. Cluster Health Derinlemesine
Üç Renk, Üç Anlam
GET _cluster/health{
"cluster_name": "production-cluster",
"status": "yellow",
"timed_out": false,
"number_of_nodes": 5,
"number_of_data_nodes": 3,
"active_primary_shards": 45,
"active_shards": 80,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 10,
"delayed_unassigned_shards": 5,
"number_of_pending_tasks": 0,
"number_of_in_flight_fetch": 0,
"task_max_waiting_in_queue_millis": 0,
"active_shards_percent_as_number": 88.9
}Her Alanın Anlamı
| Alan | Açıklama | Endişe Eşiği |
|---|---|---|
status | Green/Yellow/Red | Yellow = uyarı, Red = acil |
number_of_nodes | Toplam node sayısı | Beklenen sayıdan azsa sorun var |
active_primary_shards | Aktif primary shard | Bu 0'dan büyük olmalı |
active_shards | Aktif primary + replica | |
relocating_shards | Taşınmakta olan shard | > 0 ise rebalancing var |
initializing_shards | Başlatılmakta olan shard | > 0 ise recovery var |
unassigned_shards | Atanmamış shard sayısı | > 0 ise sorun var |
delayed_unassigned_shards | Gecikmeli atanmamış shard | Node geçici düştüyse bekler |
number_of_pending_tasks | Bekleyen cluster task | > 50 ise master yetişemiyor |
active_shards_percent | Aktif shard yüzdesi | < 100% ise sorun var |
Index Seviyesinde Health
GET _cluster/health?level=indices
// Sadece sorunlu index'ler:
GET _cluster/health?level=indices&filter_path=indices.*.status
// Belirli bir index:
GET _cluster/health/productsShard Seviyesinde Health
GET _cluster/health/products?level=shards
// Yanıt:
{
"cluster_name": "production-cluster",
"status": "yellow",
"indices": {
"products": {
"status": "yellow",
"number_of_shards": 3,
"number_of_replicas": 1,
"active_primary_shards": 3,
"active_shards": 5,
"unassigned_shards": 1,
"shards": {
"0": {
"status": "green",
"primary_active": true,
"active_shards": 2,
"unassigned_shards": 0
},
"1": {
"status": "yellow",
"primary_active": true,
"active_shards": 1,
"unassigned_shards": 1
},
"2": {
"status": "green",
"primary_active": true,
"active_shards": 2,
"unassigned_shards": 0
}
}
}
}
}Buradan görüyoruz: Shard 1'in replica'sı atanmamış (yellow).
2. Shard Allocation — Shard'lar Nasıl Dağıtılır?
Allocation Kuralları
Master node, shard'ları node'lara atarken şu kurallara uyar:
Aynı shard'ın primary ve replica'sı aynı node'da olamaz — yoksa node düşünce her ikisi de kaybolur
Disk watermark'ları: Disk %85 doluysa yeni shard atanmaz, %90'da shard'lar taşınır
Allocation awareness: Zone bazlı dağıtım yapılandırılabilir
Custom allocation rules: Index bazında node filtreleme
Shard Durumları
| Durum | Açıklama |
|---|---|
STARTED | Aktif, çalışıyor |
INITIALIZING | Başlatılıyor (recovery) |
RELOCATING | Başka node'a taşınıyor |
UNASSIGNED | Hiçbir node'a atanmamış |
# Shard durumlarını listele
GET _cat/shards?v&s=state
# Sadece unassigned shard'lar
GET _cat/shards?v&h=index,shard,prirep,state,unassigned.reason&s=state:ascUnassigned Shard Sebepleri
| Sebep | Açıklama |
|---|---|
INDEX_CREATED | Index yeni oluşturuldu, shard'lar henüz atanmadı |
CLUSTER_RECOVERED | Cluster recovery sonrası |
DANGLING_INDEX_IMPORTED | Dangling index import edildi |
NEW_INDEX_RESTORED | Snapshot'tan restore edildi |
NODE_LEFT | Node cluster'dan ayrıldı |
REROUTE_CANCELLED | Reroute iptal edildi |
REINITIALIZED | Shard yeniden başlatıldı |
REPLICA_ADDED | Replica sayısı artırıldı |
ALLOCATION_FAILED | Atama başarısız oldu |
EXISTING_INDEX_RESTORED | Mevcut index üzerine restore |
3. Allocation Explain — "Neden Atanmadı?"
Bu, shard allocation sorunlarını teşhis etmenin en güçlü aracı.
Otomatik Explain (İlk Atanmamış Shard)
GET _cluster/allocation/explain
// Yanıt örneği:
{
"index": "products",
"shard": 1,
"primary": false,
"current_state": "unassigned",
"unassigned_info": {
"reason": "NODE_LEFT",
"at": "2024-01-15T10:30:00.000Z",
"last_allocation_status": "no_attempt",
"delayed": true,
"allocation_delay_in_millis": 60000,
"remaining_delay_in_millis": 35000
},
"can_allocate": "no",
"allocate_explanation": "cannot allocate because allocation is not permitted to any of the nodes",
"node_allocation_decisions": [
{
"node_id": "node-1-id",
"node_name": "data-1",
"transport_address": "10.0.1.10:9300",
"node_decision": "no",
"deciders": [
{
"decider": "same_shard",
"decision": "NO",
"explanation": "a copy of this shard is already allocated to this node"
}
]
},
{
"node_id": "node-2-id",
"node_name": "data-2",
"transport_address": "10.0.1.11:9300",
"node_decision": "yes"
}
]
}Belirli Bir Shard İçin Explain
GET _cluster/allocation/explain
{
"index": "products",
"shard": 1,
"primary": false
}Yaygın Allocation Kararları (Deciders)
| Decider | Karar | Anlam |
|---|---|---|
same_shard | NO | Primary ve replica aynı node'da olamaz |
disk_threshold | NO | Node'un diski dolu (watermark aşılmış) |
filter | NO | Index allocation filter'ı bu node'u engelliyor |
awareness | NO | Zone/rack awareness kuralı engel |
max_retry | NO | Atama defalarca başarısız oldu |
node_version | NO | Node versiyonu uyumsuz |
throttling | THROTTLE | Aynı anda çok fazla recovery — bekle |
4. Shard Allocation Ayarları
Disk Watermark'ları
GET _cluster/settings?include_defaults=true&flat_settings=true&filter_path=defaults.cluster.routing.allocation.disk*
// Varsayılan değerler:
// cluster.routing.allocation.disk.watermark.low: 85%
// cluster.routing.allocation.disk.watermark.high: 90%
// cluster.routing.allocation.disk.watermark.flood_stage: 95%
// Değiştirme:
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": "80%",
"cluster.routing.allocation.disk.watermark.high": "85%",
"cluster.routing.allocation.disk.watermark.flood_stage": "92%",
"cluster.routing.allocation.disk.watermark.flood_stage.frozen": "97%"
}
}Watermark davranışları:
Low (%85): Bu eşik aşıldığında, node'a yeni shard atanmaz
High (%90): Bu eşik aşıldığında, shard'lar diğer node'lara taşınmaya başlar
Flood stage (%95): Bu eşik aşıldığında, ilgili index'ler read-only olur
Allocation Enable/Disable
// Tüm allocation'ı durdur (maintenance window)
PUT _cluster/settings
{
"transient": {
"cluster.routing.allocation.enable": "none"
}
}
// Sadece primary allocation
PUT _cluster/settings
{
"transient": {
"cluster.routing.allocation.enable": "primaries"
}
}
// Normal duruma dön
PUT _cluster/settings
{
"transient": {
"cluster.routing.allocation.enable": "all"
}
}| Değer | Açıklama |
|---|---|
all | Tüm shard'lar atanabilir (varsayılan) |
primaries | Sadece primary shard'lar atanabilir |
new_primaries | Sadece yeni oluşturulan index'lerin primary'leri |
none | Hiçbir shard atanmaz |
Recovery Throttling
// Aynı anda kaç shard recover edebilir
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.node_concurrent_incoming_recoveries": 2,
"cluster.routing.allocation.node_concurrent_outgoing_recoveries": 2,
"cluster.routing.allocation.node_concurrent_recoveries": 2,
"indices.recovery.max_bytes_per_sec": "100mb"
}
}Delayed Allocation
Bir node geçici olarak düştüğünde (restart), hemen shard'ları başka yere taşımak yerine belirli bir süre beklemek daha akıllıca:
// Index bazında delayed allocation
PUT products/_settings
{
"settings": {
"index.unassigned.node_left.delayed_timeout": "5m"
}
}
// Cluster genelinde
PUT _all/_settings
{
"settings": {
"index.unassigned.node_left.delayed_timeout": "10m"
}
}Neden? Bir node restart için 2 dakika offline kalsa, tüm shard'larını başka node'lara taşımak (ve geri geldiğinde tekrar taşımak) saatler alabilir. 5-10 dakika beklemek çoğu durumda doğru karardır.
5. Shard Allocation Filtering
Index Bazında Filtreleme
// Index'i sadece belirli node'lara ata
PUT products/_settings
{
"index.routing.allocation.require.data_tier": "hot"
}
// Belirli node'lardan kaçın
PUT old-logs/_settings
{
"index.routing.allocation.exclude._name": "data-hot-1,data-hot-2"
}
// Belirli IP adreslerine ata
PUT products/_settings
{
"index.routing.allocation.include._ip": "10.0.1.10,10.0.1.11"
}Filter Operatörleri
| Operatör | Açıklama |
|---|---|
require | Shard sadece bu koşulu sağlayan node'lara atanabilir |
include | Shard bu node'lardan birine atanabilir |
exclude | Shard bu node'lara atanamaz |
Built-in Attribute'lar
| Attribute | Açıklama |
|---|---|
_name | Node adı |
_host_ip | Host IP adresi |
_publish_ip | Publish IP adresi |
_ip | Host veya publish IP |
_host | Hostname |
_id | Node ID |
_tier | Data tier (hot, warm, cold, frozen) |
6. Allocation Awareness — Zone ve Rack
Shard Allocation Awareness
Replica'ların primary ile farklı zone'da olmasını garanti eder:
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.awareness.attributes": "zone"
}
}# Node konfigürasyonu
# data-1 (AZ-1)
node.attr.zone: az-1
# data-2 (AZ-1)
node.attr.zone: az-1
# data-3 (AZ-2)
node.attr.zone: az-2
# data-4 (AZ-2)
node.attr.zone: az-2Bu durumda: Shard 0'ın primary'si az-1'deyse, replica'sı az-2'ye atanır. Bir zone tamamen çökse, diğer zone'daki kopya veriyi korur.
Forced Awareness
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.awareness.attributes": "zone",
"cluster.routing.allocation.awareness.force.zone.values": "az-1,az-2,az-3"
}
}force ile: Eğer tanımlı zone'lardan biri tamamen yoksa (tüm node'ları düşmüşse), o zone'a ait replica'lar atanmadan bekler — kalan zone'lara sıkıştırılmaz. Bu, bir zone geri geldiğinde veri tutarlılığını korur.
7. Manuel Shard Yönetimi — Reroute API
Shard Taşıma (Move)
POST _cluster/reroute
{
"commands": [
{
"move": {
"index": "products",
"shard": 0,
"from_node": "data-1",
"to_node": "data-3"
}
}
]
}Unassigned Shard'ı Manuel Atama
// Replica'yı belirli node'a ata
POST _cluster/reroute
{
"commands": [
{
"allocate_replica": {
"index": "products",
"shard": 1,
"node": "data-2"
}
}
]
}Kayıp Primary Shard'ı Kurtarma (Veri Kaybı Riski!)
// ⚠️ DİKKAT: Bu komut veri kaybına yol açabilir!
// Sadece primary shard tamamen kaybolduğunda ve başka seçenek yoksa
POST _cluster/reroute
{
"commands": [
{
"allocate_stale_primary": {
"index": "products",
"shard": 0,
"node": "data-1",
"accept_data_loss": true
}
}
]
}
// Boş primary atama (tüm veri kaybolur!)
POST _cluster/reroute
{
"commands": [
{
"allocate_empty_primary": {
"index": "products",
"shard": 0,
"node": "data-1",
"accept_data_loss": true
}
}
]
}⚠️ Dikkat:
allocate_stale_primaryveallocate_empty_primaryson çare olarak kullanılır. Mümkünse snapshot'tan restore edin.
Başarısız Atama Denemelerini Sıfırlama
POST _cluster/reroute?retry_failed=true8. Rebalancing — Otomatik Dengeleme
Elasticsearch, shard'ları node'lar arasında otomatik dengeler. Ama bazen müdahale gerekir:
// Rebalancing ayarları
PUT _cluster/settings
{
"persistent": {
"cluster.routing.rebalance.enable": "all",
"cluster.routing.allocation.balance.shard": 0.45,
"cluster.routing.allocation.balance.index": 0.55,
"cluster.routing.allocation.balance.threshold": 1.0
}
}| Ayar | Açıklama |
|---|---|
balance.shard | Node'lar arası toplam shard dengesinin ağırlığı |
balance.index | Index başına shard dengesinin ağırlığı |
balance.threshold | Rebalancing tetikleme eşiği (düşük = daha agresif) |
// Rebalancing'i geçici durdur
PUT _cluster/settings
{
"transient": {
"cluster.routing.rebalance.enable": "none"
}
}
// Tekrar aç
PUT _cluster/settings
{
"transient": {
"cluster.routing.rebalance.enable": "all"
}
}9. Bütünleşik Örnek: "Cluster Yellow — Ne Yapmalı?"
Gerçek dünya senaryosu: Sabah geldiniz, monitoring alert vermiş — cluster yellow.
Adım 1: Genel Durum
GET _cluster/health
// Sonuç: yellow, unassigned_shards: 8Adım 2: Hangi Index'ler Sorunlu?
GET _cat/indices?v&health=yellow&h=index,health,pri,rep,docs.count,store.size
// Çıktı:
// index health pri rep docs.count store.size
// orders-2024.01 yellow 3 1 5000000 12gb
// logs-2024.01 yellow 5 1 25000000 45gbAdım 3: Hangi Shard'lar Atanmamış?
GET _cat/shards?v&h=index,shard,prirep,state,unassigned.reason,node&s=state
// Çıktı:
// index shard prirep state unassigned.reason node
// orders-2024.01 1 r UNASSIGNED NODE_LEFT
// orders-2024.01 2 r UNASSIGNED NODE_LEFT
// logs-2024.01 0 r UNASSIGNED NODE_LEFT
// logs-2024.01 2 r UNASSIGNED NODE_LEFT
// ...Tüm unassigned shard'lar replica ve sebep NODE_LEFT. Bir node düşmüş.
Adım 4: Node Durumu
GET _cat/nodes?v&h=name,ip,role,heap.percent,cpu,disk.used_percent,master
// Çıktı: 2 data node görünüyor, normalde 3 olmalı
// data-3 listede yok!Adım 5: Allocation Explain
GET _cluster/allocation/explain
// Sonuç:
{
"index": "orders-2024.01",
"shard": 1,
"primary": false,
"can_allocate": "no",
"allocate_explanation": "cannot allocate because allocation is not permitted to any of the nodes",
"node_allocation_decisions": [
{
"node_name": "data-1",
"node_decision": "no",
"deciders": [
{
"decider": "same_shard",
"decision": "NO",
"explanation": "a copy of this shard is already allocated to this node [[orders-2024.01][1], node[data-1], primary]"
}
]
},
{
"node_name": "data-2",
"node_decision": "no",
"deciders": [
{
"decider": "same_shard",
"decision": "NO",
"explanation": "a copy of this shard is already allocated to this node"
}
]
}
]
}Sorun net: 3 shard'lı index, replica=1 ama sadece 2 node var. Bazı shard'ların hem primary'si hem replica'sı aynı node'da olamayacağı için replica atanamıyor.
Adım 6: Çözüm
# Seçenek 1: Düşen node'u geri getir (en iyi)
# data-3'ü restart et
# Seçenek 2: Yeni node ekle
# Yeni data node kurulumu
# Seçenek 3 (geçici): Replica sayısını düşür// Geçici çözüm — replica'yı düşür
PUT orders-2024.01/_settings
{
"index.number_of_replicas": 0
}
// ⚠️ Bu, node düşerse veri kaybı riski demek!Java ile Otomatik Health Checker
public class ClusterHealthChecker {
private final ElasticsearchClient client;
public ClusterHealthChecker(ElasticsearchClient client) {
this.client = client;
}
public void diagnose() throws Exception {
// 1. Cluster health
var health = client.cluster().health();
System.out.println("Status: " + health.status());
System.out.println("Unassigned: " + health.unassignedShards());
if (health.unassignedShards() == 0) {
System.out.println("✅ All shards assigned!");
return;
}
// 2. Unassigned shard'ları listele
var shards = client.cat().shards(s -> s
.headers("index,shard,prirep,state,unassigned.reason,node")
);
System.out.println("\n=== Unassigned Shards ===");
for (var shard : shards.valueBody()) {
if ("UNASSIGNED".equals(shard.state())) {
System.out.printf(" %s [%s] %s — Reason: %s%n",
shard.index(), shard.shard(),
shard.prirep(), shard.unassignedReason());
}
}
// 3. Allocation explain
var explain = client.cluster().allocationExplain(e -> e);
System.out.println("\n=== Allocation Explain ===");
System.out.println("Index: " + explain.index());
System.out.println("Shard: " + explain.shard());
System.out.println("Primary: " + explain.primary());
System.out.println("Can allocate: " + explain.canAllocate());
System.out.println("Explanation: " + explain.allocateExplanation());
}
}10. Best Practices
✅ Yap
| Konu | Öneri |
|---|---|
| Allocation awareness | Zone bazlı awareness kullan |
| Delayed allocation | Node restart için 5-10 dakika bekle |
| Disk watermark | Low=%80, High=%85 — varsayılanlardan önce aksiyon al |
| Health monitoring | Her dakika kontrol, alert kur |
| Allocation explain | Sorunu anlamadan çözmeye çalışma |
| Reroute retry_failed | Başarısız atamaları periyodik retry yap |
❌ Yapma
| Konu | Neden |
|---|---|
| Yellow'u ignore etme | Bir node daha düşerse kırmızı |
| accept_data_loss ile allocation | Son çare — önce snapshot dene |
| Allocation disable unutma | Maintenance sonrası enable: all yapmazsan shard atanmaz |
| Flood stage'de watermark yükseltme | Geçici çözüm, asıl çözüm disk temizleme |
11. Yaygın Hatalar ve Çözümleri
Hata 1: "Cluster RED ama veri var mı?"
# Adım 1: Red index'leri bul
GET _cat/indices?v&health=red
# Adım 2: Hangi primary shard kayıp?
GET _cat/shards?v&h=index,shard,prirep,state&s=state
# Adım 3: Node geri dönebilir mi?
# Evet → node'u restart et
# Hayır → snapshot'tan restore et
# Son çare → allocate_stale_primary (veri kaybı riski)Hata 2: "Shard allocation timed out"
// Sorun: Recovery çok yavaş, timeout
// Çözüm: Recovery throttle'ı artır
PUT _cluster/settings
{
"transient": {
"indices.recovery.max_bytes_per_sec": "200mb",
"cluster.routing.allocation.node_concurrent_incoming_recoveries": 4
}
}Hata 3: "Index read-only (flood stage)"
// Sorun: Disk flood stage'e ulaşmış, index read-only
// Adım 1: Disk aç (eski index sil, temp dosya temizle)
DELETE old-unnecessary-index-*
// Adım 2: Read-only block'u kaldır
PUT _all/_settings
{
"index.blocks.read_only_allow_delete": null
}
// Adım 3: Watermark'ları kontrol et
GET _cat/allocation?vHata 4: "Allocation keeps failing"
# Sorun: Shard atama sürekli başarısız (retry max'a ulaşmış)
# Kontrol:
GET _cluster/allocation/explain
# Genelde neden: Mapping uyumsuzluğu, corrupt shard, disk dolu
# Çözüm:
POST _cluster/reroute?retry_failed=true
# Hâlâ başarısızsa: index'i kapatıp açmayı dene
POST problematic-index/_close
POST problematic-index/_open12. Recovery Monitoring
Bir node cluster'a katıldığında veya shard taşındığında recovery başlar:
# Aktif recovery'leri izle
GET _cat/recovery?v&active_only&h=index,shard,time,type,stage,files_percent,bytes_percent,source_node,target_node
// Çıktı:
// index shard time type stage files_percent bytes_percent source_node target_node
// products 0 2.5m peer translog 100% 87.3% data-1 data-3
// logs-2024.01 2 5.1m peer index 56.2% 42.1% data-2 data-3Recovery Stages
| Stage | Açıklama |
|---|---|
init | Recovery başlatılıyor |
index | Segment dosyaları kopyalanıyor |
verify_index | Kopyalanan segment'ler doğrulanıyor |
translog | Translog replay ediliyor |
finalize | Recovery tamamlanıyor |
done | Tamamlandı |
Özet
Cluster health üç renkle özetlenir — Green (herkes yerinde), Yellow (replica eksik), Red (primary kayıp). Yellow'u asla ignore etmeyin — bir node daha düşerse RED olur.
`_cluster/allocation/explain` shard'ın neden atanamadığını detaylı gösterir — sorunu anlamadan çözmeye çalışmayın, önce explain çıktısını okuyun.
Disk watermark'ları shard atamayı doğrudan etkiler — low (%85) yeni atama durdurur, high (%90) shard taşır, flood stage (%95) index'i read-only yapar.
Allocation awareness ile primary ve replica'yı farklı zone'lara dağıtarak zone arızasına karşı koruma sağlayın.
Delayed allocation node restart senaryolarında saatler sürecek gereksiz veri taşımayı önler — 5-10 dakika beklemek mantıklıdır.
Manuel reroute son çaredir —
allocate_stale_primaryveallocate_empty_primaryveri kaybına yol açabilir. Önce snapshot'tan restore etmeyi deneyin.
AI Asistan
Sorularını yanıtlamaya hazır