Elasticsearch nedir?
Tags: elastic, elasticsearch
Published: 2022-03-05 17:13:52

# 1. Tanım

Elasticsearch, büyük bir çoğunluğu Java programlama dili ile yazılmış, özgür ve açık kaynak kodlu bir arama motorudur. 

Arama motoru denilince muhtemelen aklınıza web sayfalarını aratan bir sistem gelse de aslında arkadaplanında "**büyük**" bir içeriği "**barındıran**", bu bilgiler üzerinde "**arama**" yapılabilen ve bu aramalara cevap verip "**analiz**" yapılabilen bir "**veritabanını**" barındırmaktadır. Ayrıca bu veritabanı kendi içerisinde oldukça güzel bir şekilde dağıtık (distributed) ve küme (cluster) şeklinde çalışabilmektedir.

# 2. Kullanım amaçları

Yukarıda bahsettiğim şekilde tasarlanmış bir arama motoru (engine) çeşitli amaçlarla kullanılmaktadır. Kendi [github sayfalarında](https://github.com/elastic/elasticsearch) belirtildiği şekilde en yoğun 5 kullanım amacı aşağıdaki gibi sıralanabilir:

* Kütük kayıtları (log)
* Ölçülebilen veriler (metric)
* Arama altyapısı (search backend)
* Uygulama izleme (monitoring)
* Uçnokta güvenliği (endpoint security)

# 3. Temel kavramlar

Elasticsearch içerisinde veri tutmasından dolayı tamamiyle bir veritabanı olarak düşünülebilir. Fakat içerisindeki kavramlar ilişkisel veritabanlarına göre oldukça farklıdır.

Klasik bir veritabanında sisteminde tablolar bulunmaktadır. Elasticsearch'te ise bu _tablolar_ yerine **indice**'ler kullanılmaktadır. 

İlişkisel veritabanlarındaki _satır_ kavramı yerine ise NoSQL yapılarında karşımıza çıkan **document** kavramı ortaya çıkmaktadır. Ve tabi ki tahmin edildiği gibi JSON olarak tutulmaktadır.

İlişkisel veritabanlarındaki _sutun_ kavramı ise elasticsearch'te **field** olarak kullanılmaktadır.

# 4. Ortam Hazırlama

## 4.1. Kurulum

Örnek kurulumumuzu Ubuntu 20.04 sunucu üzerinde yapacağız. Bunun için öncelikle elasticsearch anahtarını ekleyip, sunucumuza deposunu ekleyerek kurulumu yapabiliriz. Tabi ki aşağıdaki komutların uygulanması için yetkili bir kullanıcı ile giriş yapılması gerekmektedir.

```bash
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list
sudo apt update
sudo apt install elasticsearch
```

## 4.2. Yapılandırma

Sevdiğiniz bir editör ile **/etc/elasticsearch/elasticsearch.yml** dosyasını açıp aşağıda belirtildiği şekilde düzenlemeler yapmanız tavsiye edilir. Aşağıdaki örnekteki satırlar diyezle başlamamalı ve diğer tüm satırlar diyez ile kapalı olmalıdır. Çeşitli farklı kombinasyonlar da çalışabilir fakat ilk denemenizse buna dikkat etmeniz gerekir.

```
cluster.name: kumeadi01
node.name: dugum01
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

network.host: 0.0.0.0
http.port: 9200
discovery.type: single-node
```

Buradaki yapılandırma elasticsearch'ü uzaktaki bir ortamdan da çalıştırabilmek ve tek node'luk bir sistemi oluşturmaktadır. Daha detaylı bilgi için detaylı dokümanları inceleyebilirsiniz.

Bu yapılandırma ayarları ile birlikte 9200 portu üzerinden tüm ağ üzerinden REST API ile sorgu atılabilecek şekilde ayarları yapılmış olacaktır.

## 4.3. Servisi başlatma

Servisi başlatıp, açılışta hep başlaması için aşağıdaki iki komut kullanılabilir. Servisin ayağa kalkması biraz zaman alacaktır.

```bash
sudo systemctl start elasticsearch
sudo systemctl enable elasticsearch
```

## 4.4. Kontrol

Servisin ayağa kalktığına emin olduktan sonra aşağıdaki komut ile elasticsearch sunucusu üzerinden sorgu atıp;

```bash
curl -X GET 'http://localhost:9200'
```

Aşağıdaki gibi çıktı alabilirsiniz:

```json
{
  "name" : "dugum01",
  "cluster_name" : "kumeadi01",
  "cluster_uuid" : "TQuwevhrRvCCvfSAmz0Mxg",
  "version" : {
    "number" : "7.17.1",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "e5acb99f822233d62d6444ce45a4543dc1c8059a",
    "build_date" : "2022-02-23T22:20:54.153567231Z",
    "build_snapshot" : false,
    "lucene_version" : "8.11.1",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
```

Kümenin sağlık durumu için de aşağıdaki komut kullanılabilir:

```bash
curl -XGET 'http://localhost:9200/_cluster/health?pretty'
```

```json
{
  "cluster_name" : "kumeadi01",
  "status" : "yellow",
  "timed_out" : false,
  "number_of_nodes" : 1,
  "number_of_data_nodes" : 1,
  "active_primary_shards" : 15,
  "active_shards" : 15,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 5,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 75.0
}
```

# 5. Basit Uygulama

Örnek bir uygulama yapmak için aşağıdaki komut kullanılabilir:

```json
curl -XPOST 'http://localhost:9200/indis01/uygulama01' -H 'Content-Type: application/json' -d'
{
"timestamp": "2021-03-05 20:00:00",
"message": "örnek bir mesaj",
"ustid": 4,
"deneme": false
}
'
```

Bu uygulama ile basit bir **indice** üzerinde (indis01) uygulama01 isimli bir **type** (uygulama01) oluşturulmuş oluyor. Bu tip içerisinde ise JSON formatındaki içerikteki gibi **document** oluşturuluyor. Ve bu document içinde timestamp, massage, ustid, deneme gibi **field**'ler bulunmakta.

Bu sorgu aşağıdaki gibi bir çıktı vermiş olması lazım.

```json
{"_index":"indis01","_type":"uygulama01","_id":"7UUHW38BvbmLU0LnqFFb","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1
```

Ayrıca indisinizin eklendiğini görebilmek için aşağıdaki komutu çalıştırarak çıktıdaki tablodan takip edebilmelisiniz ve indis01'i görebilmeniz gerekmekte.

```bash
curl -XGET 'http://localhost:9200/_cat/indices?v&pretty'
```

Eklenen verilerin izlenmesi için:

```bash
curl -XGET 'http://localhost:9200/indis01/_search?size=10&q=*:*'
```

Eklenen veriler aşağıdaki gibi gözükmesi beklenmektedir.

```
{"took":18,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":3,"relation":"eq"},"max_score":1.0,"hits":[{"_index":"indis01","_type":"uygulama01","_id":"tXe6XY8BW9idoGYKiO3b","_score":1.0,"_source":
{
"timestamp": "2021-03-05 20:00:00",
"message": "örnek bir mesaj",
"ustid": 4,
"deneme": false
}
},{"_index":"indis01","_type":"uygulama01","_id":"t3e7XY8BW9idoGYKQe0i","_score":1.0,"_source":
{
"timestamp": "2021-03-05 20:00:00",
"message": "örnek bir mesaj",
"ustid": 4,
"deneme": false
}
},{"_index":"indis01","_type":"uygulama01","_id":"uHe7XY8BW9idoGYK7e28","_score":1.0,"_source":
{
"timestamp": "2021-03-05 20:00:00",
"message": "örnek bir mesaj222",
"ustid": 444,
"deneme": false
}
}]}}
```


# 5. Gelişmiş Uygulamalar

Bu adımdan sonra Elasticsearch'in [API dokümantasyonu](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs.html) ve çeşitli tutoriallarla devam edilebileceği gibi farklı seçenekler bulunmaktadır. Bunlardan en popüler 3 tanesi aşağıdaki gibidir. Bu yapılara Elastic Stack adı da verilebilmektedir.

* Logstash
* Fluentd
* Filebeat

Logstash, çeşitli ve farklı kaynaklardan beslenerek elasticsearch'ü çok genişletebilmektedir. Ve bu yapıya kısaca ELK adı veriliyor.

Fluent, ise benzer şekilde elasticsearch'ü beslemek için genellikle Kubernetes ortamlarında kullanıldığını görüyoruz. Ve bu yapıya da EFK adı verilmektedir.

Filebeat'i ise hem logstash'i besleyecek şekilde hem de direkt olarak elasticsearch'ü besleyecek şekilde yapılandırabiliyorsunuz.

Üstte bahsettiğimiz yapıların görselleştirilmesi için de genellikle Kibana kullanılmaktadır ve gelişmiş seçenekler sunmaktadır. Fakat yazımızın konusu olmadığı için bu kısımlara pek girmedim.

---

Pax melior est quam iustissimum bellum