Elasticsearch'e Python, Node.js ve Java istemcileriyle bağlanmak
Selamlar, bu yazımda Elasticsearch'e farklı dillerden nasıl bağlanacağımıza bakacağız. Kavramlardan çok pratik tarafa odaklanalım çünkü 'cluster ayakta, index hazır, peki şimdi uygulamadan nasıl konuşacağım?' sorusu en çok burada takılıyor. Üç dili de göreceğiz: Python, Node.js, Java.
İlk açıklığa kavuşturalım: hepsinde resmi istemci kullanın. requests ile JSON yollayıp idare etmeye çalışmak ilk gün şirin durur, ama serialization, retry, sniffing, version uyumu derken işin içinden çıkamazsınız. Resmi istemciler bu işleri sizin yerinize hallediyor.
Python istemcisi
Kurulum klasik:
pip install elasticsearch
Asgari bir bağlantı şöyle:
from elasticsearch import Elasticsearch
es = Elasticsearch(
'https://localhost:9200',
basic_auth=('elastic', 'parolaniz'),
ca_certs='/path/to/ca.crt',
request_timeout=30,
max_retries=3,
retry_on_timeout=True,
)
print(es.info()['cluster_name'])
Üç şeye dikkat: verify_certs=False'u sadece localhost'ta deneyin. Prod'da CA dosyasını verin. request_timeout defaultu 10 saniye, ağır query'lerde yetmez. max_retries ile retry_on_timeout'u beraber set etmezseniz retry'lar çoğu durumda devreye girmez.
Çok belge basacaksanız tek tek es.index() çağırmayın. helpers.bulk Türk geliştiricinin en sık atladığı kısım:
from elasticsearch.helpers import bulk
docs = (
{'_index': 'makaleler', '_id': i, '_source': {'baslik': f'Yazi {i}', 'goruntulenme': i * 10}}
for i in range(1, 10001)
)
success, failed = bulk(es, docs, chunk_size=500, stats_only=True)
print(f'Basarili: {success}, basarisiz: {failed}')
Tek tek index'leme ile bulk arasında benim ölçtüğüm fark genellikle 20-50 kat. chunk_size'ı belge boyutuna göre ayarlayın; 500 ortalama metinler için iyi bir başlangıç.
Node.js istemcisi
npm install @elastic/elasticsearch
Bağlantı tarafı:
const { Client } = require('@elastic/elasticsearch');
const fs = require('fs');
const client = new Client({
node: 'https://localhost:9200',
auth: { username: 'elastic', password: 'parolaniz' },
tls: { ca: fs.readFileSync('/path/to/ca.crt') },
maxRetries: 3,
requestTimeout: 30000,
compression: true,
});
const info = await client.info();
console.log(info.cluster_name);
compression: true küçük bir ayar ama bandwidth'iniz uzaksa geri dönüşü çok iyi. Bulk tarafında payload yapısı Python'dakinden farklı; iki satırlık çiftler halinde gidiyor:
const ops = [];
for (let i = 1; i <= 1000; i++) {
ops.push({ index: { _index: 'makaleler', _id: String(i) } });
ops.push({ baslik: `Yazi ${i}`, goruntulenme: i * 10 });
}
const res = await client.bulk({ refresh: false, operations: ops });
if (res.errors) {
// hatali itemları gez, sessiz gecme
res.items.forEach((it, i) => it.index?.error && console.error(i, it.index.error));
}
refresh: true'yu prod'da otomatik açmayın - her bulk'tan sonra segment refresh write performansını yere yapıştırır.
Java istemcisi
Java tarafı biraz daha tören istiyor. Maven'da:
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.12.0</version>
</dependency>
Minimum auth'lu bağlantı:
RestClient rest = RestClient.builder(new HttpHost("localhost", 9200, "https"))
.setHttpClientConfigCallback(b -> b.setDefaultCredentialsProvider(creds))
.build();
ElasticsearchTransport transport = new RestClientTransport(rest, new JacksonJsonpMapper());
ElasticsearchClient client = new ElasticsearchClient(transport);
var info = client.info();
System.out.println(info.clusterName());
creds'i BasicCredentialsProvider ile kurmanız gerekiyor; SSLContext'i de elle inşa edeceksiniz. Spring Boot kullanıyorsanız spring-boot-starter-data-elasticsearch bu kalıbı bir miktar saklıyor, ama altta yatan istemci yine bu.
Sık karşılaşılan tuzaklar
verify_certs=Falseile prod'a çıkmak: Geliştirme modunu unutup canlıya bırakırsanız MITM'e açık olursunuz. CA path'i config'den okuyun,devprofilde gevşetin.- Tek tek index'leme: 10.000 belgeyi
fordöngüsündeindex()ile basıyorsanız ya cluster'ı yıpratıyorsunuz ya da inanılmaz yavaş çalışıyorsunuz. Bulk her zaman. - Timeout'ları default bırakmak: Türkiye'den bir AWS Frankfurt cluster'ına bağlanıyorsanız 10 saniye bazen yetmez. 30 saniye ve
retry_on_timeoutmakul başlangıç. refresh=trueher yazımda: Hızlı arama için cazip ama write throughput'unu uçuruma atar. Sadece testte kullanın.- API key yerine basic auth: Production'da kullanıcı/parola yerine API key kullanın, scope'u dar tutun.
Kapanış
Üç dilde de istemci kurulumu kavramsal olarak aynı: bağlantı, auth, TLS, retry, bulk. Bence en kritik nokta bulk operasyonları doğru kullanmak; tek bu bile cluster'ınızın ömrünü uzatıyor. Umarım faydalı olur, bir sonraki yazıda görüşmek üzere.
