Elasticsearch: Veri İşleyişinin Temel Yapıtaşları ve Analiz Süreçleri [2/5]

Elasticsearch: Basic Building Blocks of Data Processing and Analysis Processes [2/5]

Cihat Solak
Intertech
8 min readNov 2, 2023

--

Elasticsearch’te, verilerin etkin bir şekilde depolanması, yönetilmesi ve aranabilir hale getirilmesi için Document, Index, Data Stream, Shard, Replicas, Node, Cluster, Inverted Index ve Relevancy gibi yapıtaşları kullanılır.

Elasticsearch, hızlı ve gerçek zamanlı arama performansı sağlayarak büyük miktardaki verileri hızla işleyebilir.

Document | Row

Elasticsearch tarafından indekslenen en temel JSON formatlı bilgilerdir.

{
"name": "John",
"age": 30,
"car": null
}

Tabloların anlamına bağlı olarak, NoSQL veri tabanlarında depolanan bilgiler “document” (belge) olarak adlandırılırken, SQL veri tabanlarında ise “row” (satır) olarak adlandırılır. Veri kaydetme işlemleri için genellikle REST API’ler (POST, PUT vb.) kullanılır. Elasticsearch’e veri gönderildiğinde, bu verileri depolamak için öncelikle var olan bir tablo yoksa oluşturulur. Ardından her bir alanın (field) tipi (double, float, integer, string vb.) belirlenir.

Elasticsearch, kaydedilen verinin formatını JSON olarak beklemektedir.

Elasticsearch dağıtılmış ve belge tabanlı olup esnek şema yapısıyla ilişkisel veritabanlarından farklıdır.

Index | Database | Collection

Birbiriyle ilişkili belgelerin topluluğuna genellikle SQL veri tabanlarında Table, NoSQL veri tabanlarında ise Collection denir.

Elasticsearch’te, veri depolama ve arama hızını artırmak için belgeler index’lerde saklanır ve her biri belirli bir veri türü için bir koleksiyonu temsil eder.

İndexlemek: Veriyi kaydetmek.

[Soru]: İlişkisel veri tabanlarında kaydetmek eylemi kullanılırken, elasticsearch neden indexleme kavramını tercih ediyor?

Elasticsearch, verinin depolanmadan önce analiz sürecinden geçirilmesini sağlar. Bu süreç, verinin parçalanması, farklı yerlerde indekslenmesi vb. adımları içerir. Eğer gönderilen veri text tipindeyse, Elasticsearch bu veriyi analiz eder. Bu sürecin amacı, veri sorgulandığında hızlı bir şekilde indeks tablolarına bakarak sonuçları dönmektir. Bu nedenle bu sürece ‘indexleme’ denir.

Index Management

Index kavramı, ansiklopediye benzemektedir. Ansiklopedinin en son sayfalarında index tema sayfaları bulunmaktadır. Burada ansiklopedi içerisinde geçen kelimelerin hangi sayfada geçtiği bilgisi yazmaktadır. (Örnek: King, Stephen 87) Bu aranacak kelime için tüm ansiklopediyi gezmektense geçtiği sayfaları nokta atışı bulmak demektir.

Data Streams (Zaman Temelli)

Data streams, veri akışlarını etkili bir şekilde yönetmek için kullanılan bir araçtır.

Birçok ilişkisel veya NoSQL veri tabanlarında olmayan kavramdır. Her gün için farklı bir index oluşturabilir. Örneğin

  • service1.logs.06–09–2023
  • service1.logs.07–09–2023
  • service1.logs.08–09–2023

takma isim: service1.logs.data-stream (service1.logs.*)

Her gün için farklı index oluşturmanın faydası da bulunmaktadır. Örneğin herhangi bir t anında 30 günden fazla olan verileri silmek istediğimizde zaman damgalı indexleme yaptığımız için işler daha kolay olacaktır. Çünkü birbirinden ayrı şekilde tutulan index tablolarını silmek çok daha performanslı ve kolaydır.

Nasıl arama yapacağız? Tek bir index tablosu olsaydı, direkt olarak arama yapabilirdik. Fakat zaman damgalı indexleme yöntemine gittiğimiz için her gün için farklı bir index ismine sahibiz. Bu durumda bu zaman damgalı indexleri gruplayabileceğimiz takma isim vereceğiz. Takma isim birden fazla index tablosunu temsil edecektir. Dolasıyla belirlediğimiz takma isim üzerinden arama gerçekleştirdiğimizde elasticsearch ilgili takma isimle ilişkili tüm indexlerde arama yapacaktır.

[Soru]: 200 tane zaman damgalı index’im var. Takma isim oluştururken 200 tanesini de tek tek belirtecek miyim?

Hayır. Takma isim belirlenirken service1.logs.* şablonunu kullanabiliriz. Buradaki yıldız (*) ifadesi service1.logs. ifadesinden sonra gelen herhangi bir tarih service1.logs.data-stream takma ismine sahip olacaktır.

[Soru]: Her gün log atmadan önce index tablosu oluşturacak mıyım?

Hayır, diğer NoSQL veri tabanlarında olduğu gibi elasticsearch’de ilgili veriye uygun index tablosu bulunmuyorsa otomatik olarak oluşturmaktadır.

Data stream türü özellikle loglamalar için kullanacağız. Elasticsearch’ün indexleme yeteneğinden dolayı log içerisinde çok hızlı arama yapabiliriz.

Node (Düğüm) ve Cluster (Küme)

Elasticsearch’te, bir ‘node’, bir Elasticsearch örneğini temsil eder ve bir ‘cluster’ oluşturmak için bir araya gelir.

Node terimi, her biri kendi başına çalışan bir sanal makineyi ifade eder. Her bir sanal makine, içerisinde Elasticsearch örneğini barındırır. Görselde de görüldüğü gibi, üç farklı node için üç farklı sanal sunucu kurulumu gerçekleştirilmiş ve her birine Elasticsearch yüklenmiştir. Bu üç node’un bir araya gelmesiyle oluşan yapıya ise ‘cluster’ adı verilir.

Shard (Parça)

Shard’lar, veri depolayan bileşenlerdir ve kullanılabilirlik ve yük dengelemesi için dağıtılırlar. Gelen veriler, Shard’lara segment adı verilen bloklara kaydedilir. Her shard’a gelen veri, farklı segmentlere kaydedilir.

Shardlar, verileri dağıtılmış olarak depolamak için kullanılırken, segmentler her shard içindeki arama ve analiz işlemleri için temel birimlerdir.

Örneğin aşağıdaki görselde 3 adet shard (Shard 1, Shard 2, Shard 3) bulunmaktadır. Bunlar verileri tutan birincil bileşenlerdir. Örneğin ürün verisi kaydetmek istediğimizde gelen veri üç shard içerisinden birine kaydedilir.

Node’lar tek birimlerdir ve birden fazla node, cluster’ı oluşturur; bu da veri depolama ve işleme kapasitesini artırır.
{
"Id": "12345",
"Name": "Example Product",
"description": "This is an example product description.",
"price": 29.99,
"category": "Electronics",
"inStock": true
}

Verinin hangi shard’a kaydedilmesi gerektiğini belirli koşullarla birlikte belirleyebiliriz. Ürün verisinin id’sine göre ya da fiyatına göre ayrıştırabiliriz. Herhangi bir kural belirlemezsek elasticsearch ilgili veriyi hash algoritmasına sokarak çıkan sonuca göre bu üç shard’dan birine veriyi gönderir.

Farklı shard’larda tutulan veriler bir araya geldiklerinde index meydana gelmektedir. Dolayısıyla arama yaptığımızda, elastic search ilgili index’in bulunduğu tüm shardlarda bu aramayı gerçekleştirmektedir.

İdeal shard boyutunun 25–50 GB olduğu söylenir.

Replica (Çoğaltma)

Node’lar tek birimlerdir ve birden fazla node, cluster’ı oluşturur; bu da veri depolama ve işleme kapasitesini artırır.

Shard’ların kopyaları olan replikalar, salt okunur (read-only) verilere sahiptir. Herhangi bir shard’a yapılan veri kaydı, ilgili shard’ın replikasına asenkron bir şekilde iletilir. Örneğin, Shard 1'in bir kopyası Node 2'de (replica 1) ve diğer bir kopyası da Node 3'te bulunmaktadır. Bu yapı, bir node’un çökmesi durumunda Elasticsearch’in farklı node’lardaki replikalarından verileri kullanarak çökme durumunu tolere etmesine olanak tanır. Bu davranışta sistemin high avability ve fault tolerance olmasına imkan verir.

Örneğin, farklı ülkelerde bulunan 3 farklı veri merkezinde barınan her bir node ile oluşturulan cluster, herhangi bir ülkedeki veri merkezinde meydana gelebilecek potansiyel bir afet durumunda (örneğin yangın vb.), Elasticsearch, hasar gören node’u diğer ülkelerdeki veri merkezlerinden yeniden ayağa kaldırabilir ve kendini onarabilir. Bu mimari, doğası gereği esneklik ve güvenilirlik sağlayarak sistemdeki olası riskleri en aza indirir.

High availability (yüksek kullanılabilirlik), sistemde herhangi bir sıkıntı olduğunda uygulama veya veri tabanının çalışmaya devam edebilme yeteneğidir. Bu tür bir yapıda, olası bir sorun durumunda sistemde yavaşlama olabilir ancak işlemler devam eder. Fault Tolerance (Hata tolere edebilirlik) yüksek olduğunda ise sistem kendini onarırken performans kaybı yaşatmaz.

Öncelikle, high availability sağlanması önemlidir, ardından gerektiğinde fault tolerance sisteme dahil edilmesi uygun olacaktır. Bu sıralama, sistemin güvenilirliğini ve dayanıklılığını artırarak sağlam bir altyapı oluşturmayı destekler.

Metin Analizi (Text Analyzing)

Tokenization ve Normalization analiz konusunda temel aşamalardır.

Tokenizasyon, metni parçalara ayırma işlemidir.

Elasticsearch’e text tipinde veri geldiğinde ilgili veri kaydedilmeden önce analiz sürecinden (text analyzing) geçer daha sonra kaydedilir. Bu analiz süreci tokenization ve normalization olmak üzere iki aşamadan meydana gelmektedir.

Elasticsearch’de bir veriyi analiz sürecinden geçirmek için mutlaka tipinin text olması gerekmektedir. Boolean, datetime, int vb. tipler analiz sürecine dahil edilmez.

Texttipi analiz sürecinden geçer. Çünkü analiz sürecinden geçtikten sonra oluşan veri, index tablolarına kaydedilir ve arama performansı sağlanır.

1.1 — Tokenization (Parçalama)

Analiz sürecinin birinci aşamasıdır.

Boşluklar ve belirteçler kullanılarak anlamlı parçalara dönüştürülür. Dil işleme ve arama motorları için kritiktir.

Text tipindeki “Tokenized string” ifadesini elasticsearch’e kaydetmek istediğimizde analiz sürecinden geçecektir. Analiz süreçlerinden olan tokenization, metni boşluk karakterlerinden parçalara ayırarak liste oluşturuyor. Dizi içerisindeki her bir öğe token dır.

1.2 — Normalization (Zenginleştirme)

Analiz sürecinin ikinci aşamasıdır. Veri eş anlamlı veya kök cümleler ile zenginleştirilir.

Normalization aşamasında veri eş anlamlı veya kök cümleler ile zenginleştirilir.

Tokenization sürecinden geçip, parçalara ayrılmış olan veri için zenginleştirme işlemi gerçekleştirilir. Örneğin ‘Bankadaydı’ kelimesinin kökü olan ‘Banka’ alınır. Bunun yanı sıra hem kökü, hem kendisi, hem eş anlamlısı index tablolarına kaydedilmektedir. Eş anlamlısından kasıt aslında Büyük kelimesi varsa, bunu iri, devasa vb. şeklinde de kaydetmesidir.

Bu zenginleştirme, eş anlamlısının bulunması, köklerinin çıkartılması, normalizasyon sürecini kapsamaktadır. Tüm işlemler sonucunda üretilen veriler inverted index tablolarına kaydedilmektedir.

Analiz sürecine dahil edilecek birçok eklenti (plugin) bulunmaktadır. Dolasıyla normalizasyon süreci özelleştirilebilirdir (customize). Örneğin gelen verinin eş anlamlarının bulunmasını istemiyorsanız normalizasyon sürecine bunu koymazsınız.

Inverted Index (Ters İndeks)

Inverted index tabloları tokenization ve normalization süreçlerinden geçen verinin kaydedildiği yerdir. Veri tokenization aşamasında parçalanır, normalizasyon aşamasında zenginleştir ve oluşan veri inverted index tablolarına kaydedilir.

Her full-text field karşılık bir inverted index oluşmaktadır.

Genelde kitapların arkasında hangi kelimelerin hangi sayfalarda geçtiği yazılıdır. Örneğin yukarıdaki Denizbank kelimesi 1, 5, 6 sayfalarında geçiyormuş. Elasticsearch normalizasyon sürecinden çıkan verileri inverted index tablolarına kaydeder. Bunun sonucunda bir arama gerçekleştirdiğimizde asıl tablolarda full tarama yapmak yerine inverted index verilerine bakar, aranan kelimenin hangi sayfalarda geçtiğini, hangi shard içerisindeki hangi segmentlerde geçtiğini kolayca bulur.

Verinin orjinal hali segmentlere, ayrıştırılan kelimeler inverted index tablolarına kaydedilmektedir.

Örnek Senaryo

Rich text editöre sahip web sayfanız bulunabilir. Rich text editörden gönderilen veriler html ifadelerine sahip olacağı için bunların temizlenmesi gereklidir.

Tokenization aşamasında rich text editörden gelen verilerin html taglerinden ayrıştırılması için HTML strip filter ismindeki filtreden geçirebiliriz. HTML strip filter ile html veri ham hale çevriliyor. Whitespace tokenizer ile ham veri boşluk karakterlerinden ikiye ayrılıyor. Son aşamada Lowercasing tokenizer ile parçalanmış kelimeleri küçük harfe çeviriyoruz.

Whitespace tokenizer’ın yanı sıra Pattern tokenizer, Standard tokenizer, Classic tokenizer gibi piyasada oldukça fazla tokenizer bulunmaktadır. Senaryonuza göre customize edilebilir.

Belgelerin içeriğini anahtar kelimelere göre dizinleyerek hızlı arama ve sorgulama imkanı sağlar.

Inverted index içerisinde her bir kelimenin ne kadar sıklıkla geçtiği bilgisi de bulunmaktadır. Örneğin kaydedilmiş olan Güvenilir banka ve Güvenilir transfer bilgisine göre güvenilir kelimesi 1 ve 2 inci belgelerde geçmektedir. Güvenilir kelimesinin geçme sıklığı ise 2'dir. Çünkü her iki veri de de güvenilir geçmektedir. Bu çok önemlidir. Çünkü elasticsearch bir aramanın sonucunda en ilişkili veriyi dönmek için verinin ne kadar sıklıkla geçtiği bilgisini inverted index tablolarına kaydeder.

Güvenilirkelimesiyle arama gerçekleştiğinde en ilişkili veri ilk sırada yer alacaktır. En ilişkili olduğunu kelimenin geçiş sıklığına göre karar vermektedir. Dolayısıyla özellikle text temelli verileri üzerinde arama yapıldığında en ilişkiliden en ilişkisize doğru bir liste dönmektedir.

Relevancy (Alaka Düzeyi)

Elasticsearch için ilişkili skor değeri olup, BM25 algoritmasına göre üretilir. Aranan kelime ile dönülen veri arasındaki ilişkiyi ifade eder. BM25 algoritması varsayılan (default) algoritmadır fakat ihtiyaca göre farklı algoritmalarda kullanılabilir.

Positive floating number — Best Match Relevancy Algoritm (BM25)

Elasticsearch’de arama sonucunda dönülen her bir veriye skor değeri verilerek verinin ne kadar ilişkili olduğu belirtilir. Örneğin text temelli veriler üzerinde denizbank olarak arama yaptığımızda, dönen liste içerisinde en alakalı sonuçlar listenin en üstünde olacaktır. En üstü olan bu sonuçların relevancy değeri diğerlerine nazaran daha yüksektir.

Özellikle text temelli verilerde arama yapıldığında dönen sonucu herhangi bir alan (field) a göre sıralanmamalıdır. Herhangi bir sıralama işlemi gerçekleştirirseniz relevancy dediğimiz alaka düzeyi sıralamasını bozarsınız.

--

--