SAMCRO

Teknasyon’un Big Data Platformunu Nasıl İnşa Ettik?

Doğan Aydın
14 min readAug 25, 2022

--

Büyük veri üzerine uygulanmış problemleri, çözümleri gözlemlemek ekosistemin olgunlaşması için çok kıymetli. Maalesef Türkiye’deki bir çok firma yaşadığı tecrübeleri detaylı anlatmıyor. Ekosistemi desteklemek adına yaptığımız çözümün artılarından ve eksilerinden bahsederek hem ekosisteme bir faydamız olsun hem de ilerde dönüp baktığımızda bir anı biriktirmiş olalım istedim.

Yazı biraz uzun olacak diye öngörüyorum. Yazı içinde üçüncü çoğul şahıs kullandığım yerleri Enes Gür ile birlikte yaptığımız değerlendirmelerden aldım. İnsanların çalışma motivasyonlarındaki en büyük kaynaklardan birisi öğrenme motivasyonu. Enes bu noktada ekibe ve bana onlarca şey öğretmiş birisi. Enes gibi adamlara AR-GE kafalı adam diyorum. Kendisi ile çalıştığım her projede yaklaşımları, yenilikleri, hem iş bitiriciliği hem de güven veriyor olması harika. Enes’le çalışma fırsatı bulduğum için gerçekten minnettarım.

Şüphesiz Teknasyon’un Big Data platformundan bahsediyorsak Furkan Salkım’ı anmadan olmaz. Bu platformun yaratılmasında hem PO hem PM hem Analiz hem Test rollerini bir arada yapmış tek kişilik dev kadro. Furkan ve Enes ile tamamlayamayacağımız bir proje ile henüz karşılaşmadım :)

Yeterince övgümüzü yaptıysam şimdi biraz şirket içindeki problemimizden ve neden bir Big Data platformu geliştirdiğimizden bahsedebilirim :)

Problem

Teknasyon’un iş modeli gereği bolca proje, ürün geliştirmekte. Zaman zaman şirkete gelen danışmanların yorumları bu kadar projeyi birlikte nasıl yönetiyorsunuz olabiliyor. Temelde ihtiyaçta buradan çıkıyor.

Teknasyon süreçlerini dijitalize etmeyi başarmış bir şirket. Bir kişiye gösterilecek reklamın kendisinden, tıklamasından, maliyetinden, uygulamayı indirmesine, açmasına, geçtiği sayfaları, abonelik satın almaları, satın almalarının yenilemeleri, LTV’si, tahmini LTV’si ve bunun gibi yüzlerce metrik, event. Uçtan uça tüm adımlar bir şekilde event haline dönüştürülmüştü.

www.desk360.com, www.deepwall.com, Anomaly Detection Sistemimiz ya da diğer projelerimiz için farklı ürün ekipleri, geliştirdikleri ürünlerinin raporlama, analitik ihtiyaçları yaygınlaşma ile birlikte her gecen gün artıyordu. Ekip kendi içinde ihtiyaçları çözmek için proje özelinde çözümler uyguluyordu. Zamanla yükün artması ile birlikte darboğazlarla(bottleneck) karşılaşıyorlardı. Her ayrı ekibin probleme yaklaşımı farklı oluyordu. Verinin saklanması, işlenmesi için ayrı ayrı yöntemler uygulanıyordu. Hem geliştirme hem iyileştirmek için harcadığımız zaman hem veriyi saklamak hem işlemek için ayakta tuttuğumuz sistemler bize maliyet oluşturuyordu.

Artık buna bir dur dememiz gerekiyordu!

Bize ortak bir yapı gerekiyordu.

Yaklaşım

Geliştirme öncelikli derdimiz değildi. Önceliğimiz hangi platformu kullanarak verileri saklayabiliriz ve işleyebiliriz diye yola çıktık. Aklımızda geliştirme yoktu. Samcro dışından birine herhalde Big Data platformu geliştireceğiz desek bizim pek akıllı hareket etmediğimizi söyleyeceğinden şüphe etmiyorduk :)

Çeşitli ürünler inceledik.

  • Amazon Athena
  • Amazon RedShift
  • Amazon DocumentDB
  • ElasticSearch
  • MongoDB
  • PostgreSQL

Denemeler için Amazon’dan bir miktar kredi aldık. Ürünlerin bir kısmını ürettiğimiz veriler ile denedik ve performanslarını değerlendirdik. Anlamaya çalıştık.

Doğru ürünü seçmek için doğru beklentiyi ortaya koymamız gerekiyordu. BigData dediğimiz dünyanın temelinde bu yatıyor denebilir. Beklentiye göre hatta işlemeniz gereken bir verinin varlığına göre kullanacağınız teknolojiyi, mimarinizi değiştirmeniz gerekebilir.

Redshift, Postgre’den fork’lanmış bir üründü. Fiyatlandırmasındaki ilk paket ile azcık tattırıp bir üst paket geçtiğinizde sizi bayıltıyordu.🙂 Olmazdı. Biz bu kadar parayı bu işe vermek istemiyorduk.

Athena kullanılan veri başına bir ücret talep ediyordu. Aldık kalemi, kağıdı kim ne kadar veri gönderir diye tahminledik, yazdık, çizdik ve yine ücretin bize fazla gelmesini başardık.

MongoDB kullanalım dedik. Sharding’leme ile güzel çıktılar aldık. Bunu kendi kuracağımız sunucular üzerinde yönetme fikri masaya geldiğinde, o zamanlar managed service yapılandırmaları bizlere tatlı geliyordu. MongoDB konusunda ekip olarak tecrübemiz vardı ancak yük görmemiş bir mongo ile yük altındaki mongo’nun nasıl tepki vereceğini bilmiyorduk.

“Dayalıklı at yük altında belli olur”. Yoksa her at görünüşü itibariyle dayanıklı izlenimi verir.

MongoDB kullanacaksak da bunu managed service olarak alalım dedik. Amazon’un bu noktada çözümü DocumentDB’di. Ancak o zaman baktığımız DocumentDB çok eski bir MongoDB versiyonundan fork’lanmıştı. Bir çok özellik güncel MongoDB’den geri kalmıştı. Bu sebeple MongoDB kullanacaksak bunu Atlas üzerinden almak mantıklı göründü. Hem güncel hem de yapacağınız peering ile kendi AWS VPC’miz içinde veri akışını döndürebiliyorduk.

Şunu fark ettik: Bir altyapı tercih etsek de bu ortak bir platform olacaktı. Developer müşterileri olacak ve onlara veriyi istedikleri şekilde işleyecek ve döndürecekti. Sadece veriyi bir altyapı üzerinde saklayıp, sorgulayıp yapamazdık. Bütünleşik bir platform olması gerektiğini anladık.

İsteri tekrar tanımladık.

Tüm veri bir Data Warehouse’da saklanacaktı. Zamanlanmış periyotlar ile çekilerek işlenecek, işlem sonuçlarını NoSQL bir veritabanına konacaktı. NoSQL üzerinde tuttuğumuz veriyi de bir API yardımı ile dışarıya açmak istiyorduk. API üzerinden şirket içi geliştirici müşterilerimiz kendi sorgularını hazırlayıp sisteme verebilecekti. Sistem bu sorgu yapısına göre saatlik ya da günlük çalışıp özet verileri çıkartıp NoSQL veritabanımızda tutmasını hedefliyorduk.

Mimari

Teknasyon Big Data Mimarisi

İşin başlangıcı veriyi, Data Warehouse ile bir araya getirmekti. Büyük bir kazanımımız: Şirket içindeki tüm micro-servisleri Event Hub adını verdiğimiz bir Event Broker üzerinden haberleştiriyorduk. Event Driven Architecture modeli uygulamayı başarmıştık. Bu sebeple tüm servislerin eventlerini Big Data platformumuza rahatlıkla getirebildik.

Bileşenler

HTTP API Lambda
Message broker tarafından veya direkt client/server tarafından mesajların gönderildiği REST API servisi. Token validation, source kontrol ve yetki kontrollerinin yapıldığı bölümdür. Gelen veriler doğrulandıktan sonra SQS’e aktarılır.

Consumer Lambda
SQS’den batch olarak alınan veriler PostgreSQL’e aktaran servistir. Partition kontrolü de burada sağlanır.

Worker Beanstalk
Saat başı RAW verilerden Summary verisi çıkaracak sorguların çalıştırıldığı, sonuçların S3'den temporary ortama aktarıp MongoDB’ye aktaran parçadır.

Summary S3 Bucket
PostgreSQL üzerinde çalışan sorguların sonuçlarının aktarıldığı Bucket.

API Beanstalk
MongoDB üzerinde çalışacak sorguların Mapping yaparak, performans optimizasyonu ve yetki kontrollerinin ardından çalıştırılıp sonucunun döndürüldüğü servistir.

MongoDB
Summary verilerinin yer aldığı ortamdır.

PostgreSQL
Raw verilerinin tutulduğu ortamdır.

MySQL
Çizimde görünmeyen ancak API backend’i arkasında olan içinde API erişim bilgileri, task’ların durumu, koşulaşacak sorguların bilgisi vs. bu kısımda tutulur.

Akış

  1. Event’ler HTTP API Lambda üzerinden gelir.
  2. HTTP API Lambda gelen verinin token validation, source kontrol ve yetki kontrollerini yapar.
  3. İşi bekletmeden SQS’e bırakır.
  4. Consumer Lambda veriyi SQS üzerinde batch olarak yani gruplar halinde alır.
  5. Consumer Lambda partition kontrolü yapar. Gelen verilerin tarih kontrollerini yaparak, ilgili partition var mı yok mu onun kontrolünü yapar. Eğer ilgili partition yoksa oluşturur.
  6. Bulk insert yaparak PostgreSQL’e veriyi koyar.
  7. Cron Job saatlik çalışarak Beanstalk olarak yapılandırılan worker üzerinde işlerin belirlenmesi sağlanır.
  8. Üretilen işler job’ları saklayan SQS’e eklenir.
  9. Worker Benstalk işleri SQS üzerinden çeker. Burada paralel koşu yapabilmek adına SQS üzerinden belirli miktarda paralel alır ve paralel olarak PostgreSQL üzerinde sorguları çalıştırır.
  10. PostgreSQL işlemleri sonuçlandırdığında direk sonuçları worker’a dönmek yerine S3'e kayıt eder. Bu şekilde çok yüksek miktarda verinin worker’lara çıkıp out of memory görmesi engellenmiş olur.
  11. PostgreSQL, S3'e sonucu yazdıktan sonra işlem sonuçunu worker’a döner.
  12. Worker ilgili dosyayı S3 üzerinden 1000'lik satırlar halinde stream ederek okur. Amaç burada çok büyük boyutta bir dosyayı lokale alıp worker’ın memory’sini doldurmamak.
  13. Alınan özet bilgileri bulk şekilde MongoDB’ye insert edilir.
  14. MongoDB’nin sharding edilmiş yapısı sayesinde developer müşteriler API beanstalk üzerinden çağrı başlatarak özet bilgiler içinde hızlı bir şekilde sorgu koşturabilirler.

Sorular — Cevaplar

Neden HTTP API’yi Lambda kullandık?

Bir sunucu yapılandırmasına gitmeden scale edebilecek bir yapıya ihtiyacımız vardı. Bu sebeple bu kısımda Lambda tercih ettik.

Neden SQS kullandık?

Gelen veriyi direk PostgreSQL’e yazmaya çalışsak çok fazla insert işlemi gerekirdi. Ancak SQS kullanarak bunları biriktirip batch işlem yapabilir olduk. Bulk insert yapabildik. Veritabanı performansı sağlanmış oldu.

Neden Partition kullandık?

Partition veritabanı performansı için çok önemli bir yapı. Eğer doğru şekilde verinizi partition’lara bölerseniz çok daha hızlı veri elde etme şansınız olur. Biz de partition’lamayı güne göre yaptık. Her veri grubu için günlük partition oluşturup veritabanı performansını arttırdık.

Buyrun! Partition kullanımına ilişkin detaylı bir yazı Enes’in kaleminden.

Neden Worker’ı Beanstalk olarak yapılandırdık?

Bu şekilde worker sayısında artış yaparak SQS’de bekleyen işleri birden çok makine ile eritme şansı kazanmış olduk. Yükün artması halinde işleri Job’lara böldüğümüz için Worker makinesini arttırdığımızda buradaki iş yapabilme kapasitemizi de arttırma imkanımız oluyor.

Cron Job ne kadar sürede bir tetikleniyor?

Saat başı tetikleniyor. Eğer sorgu saatlik ise saatlik özet çıkarma sorgusu çalışıyor ya da günlük ise günde bir defa çalışıyor.

Üretilen işler neden tekrar SQS’e bırakıp, tekrar oradan aldık?

İşlerin süresi uzun sürebilir. İşlerini bitirmeden yeni işler alarak kapasite dışına çıkarak hata verebilir. Şu an için maksimum 15dk içinde worker’lar işlerini tamamlıyor. 15dk uzun bir zaman. Lakin periyodumuz en az 1 saatte 1 defa olduğu için isterimizi karşılamış oluyor.

PostgreSQL neden işlem sonucunu worker’a direk dönmüyor?

PostgreSQL üzerinde çalışan sorgular maksimum 1 saat olacak şekilde kurgulandı. Bu kurgu içerisinde çıkacak olan sonucun boyutu belirli olmadığı için, sorguların çıktıları S3'e JSON olarak aktarılır. Bu sayede Worker makinesi üzerinde çalışan paralel sorguların sonuçlarını memory’e yüklemeyerek memory kontrolü sağlanmış olur.

PostgreSQL nasıl S3'e sonuçları yazıyor?

PostgreSQL’in bir extension’ı sayesinde işlem sonuçları direk olarak S3'e yazılabiliyor. Extension ile ilgili bilgiye buradan ulaşılabilir.

Worker veriyi S3 den okurken neden direk okumuyor da stream ediyor?

PosgreSQL’den sorgunun direk worker’a çekilmemesi ile aynı sebepten dolayı. Worker’da memory’i şişirebilir.

Worker, özetleri neden bulk şekilde MongoDB’ye insert ediyor?

Alınan 1000 tane özet bilgiyi tek tek insert etmek yerine bulk insert ederek Mongodb’ye daha az yük bindirmiş oluyoruz + işlem süresi de kısalıyor.

MongoDB üzerinden yapılan sharding işlemi ne demek?

Sharding aslında genel bir yaklaşım. Bir veritabanı alıp, içine tüm veriyi koyarsanız ve performans isterseniz makineyi devamlı büyütmeniz gerekir. Bir noktada yetmez. Master, slave şeklinde çalıştırırsınız. Slave yetmedi, bir tane daha eklersiniz. Bunun getirdiği problemler olacaktır. Bunlardan birisi eventual consistency. Aynı anda hem write işlemi yapıp hem de read işlemi yaparsanız ya da master, slave’leri beslemeye yetişemez ya da slave’ler hızlı davranamaz ve üstüne alamazsa veri eski kalır. Veri bütünlüğü bozulmuş olur. Bir instance’dan yapılan read farklı sonuç verirken diğerinde farklı sonuç verir.

Madem yük fazla geliyor. Ne yapabilirim. Makineyi sonsuza doğru büyütmeye çalışabilirim ya da master-slave çalışacak bir yapı kurarım. Acaba şu nasıl olurdu. Elimdeki toplam veriyi parçalara böleyim, parçaları farklı makinelere dağıtayım. Bu şekilde ilgili veri için gelenler sadece ilgili verinin üzerinde çalışmış olur. O veri ile ilgili işler hep orada yapılır bu şekilde veri bütünlüğü sağlamış olursunuz değil mi? Sharding diğer yandan güzel görünsede complexity getirdiği için eğer mümkün ise Index, Caching, sorgu performans iyileştirme vs. yaparak geleneksel teknolojiler ile sorunu çözerseniz daha makul bir iş çıkarmış olabilirsiniz.

Sharding işleminde şu soru akla gelebilir: Shard’ların nerede olduğunu kim biliyor? Demek ki başka bir instance var o da dağıtılan verilerin yerlerini biliyor ve geleni oraya yönlendiriyor. Bunun dezavantajı olacaktır. Örneğin bu yapının tek başına çalıştığını düşünelim bu ne doğurur? Single Point of Failure değil mi. Yani bu verilerin nerede olduğunu söyleyen server down olursa geçmiş olsun. Bu durumda verileri tutan instance’larınız da bir şey ifade etmeyecektir. Benzer şekilde sharding işleminde Hot Key diye bir sıkıntı daha mevcuttur. Twitter’dan bir örnek verelim: kullanıcıların tweetler’ini instance’lara eşit dağıttık diyelim. Ancak instance’lardan birisi hem Cristiano Ronaldo hem Rihanna hem Özgür Demirtaş’ın tweet’lerini barındırıyor diyelim. Bu instance’a çok fazla sorgu gelecektir değil mi? Dünyada çok fazla kişi popüler futbolcu ve şarkıcıları takip ediyor, biz Türkler’de ekonomistleri… Bu shard’da yapılan okuma, yazma işlemleri çok daha fazla olacaktır diğer shard’lara nazaran. Buna Hot Key problemi deniyor. Bu problemi aşmak için Data Redistribution yapmak lazım. Bu da bir konudur.

Tekrar söylemekte fayda var. Eğer başarılabiliyorsa Index, Caching, sorgu yapıları düzenlemeleri ya da performans iyileştirmeleri ile geleneksel yöntemlerin tercih edilmesi mimarinizin daha basit olmasını sağladığı gibi cost-saving de sağlayacaktır.

Uzun çalışacak SQL’lerden nasıl kaçınılıyor?

API Beanstalk’a müşteri developer sorgusunu getirdiğinde SQL’in explain yöntemi ile sorgunun gezeceği yerler otomatik olarak inceleniyor. Birde çok partition’a gidiyorsa sorgunun kayıt edilmesine izin verilmiyor. Ayrıca eskiden JOIN kullanımı yasaktı. Bir süre sonra bazı sorgular için aktif ettik. Join kullanımı varsa da benzer şekilde kayıta izin vermiyordu. Ayrıca geliştiriciye, API’nin preview methodu ile kendi sorgusunun preview verisini görmesine imkan verdik. Bu şekilde sistem maksimum 1000 kayıt dönerek geliştiriciye yaptığı sorgunun çıktısını görme imkanı veriyor.

statement_timeout tanımlamaları ile olası uzun SQL’ler durdurulup kuyruğa geri bırakılması.

Görselde gösterilen PostgreSQL sorgularında statement_timeout tanımı kullanılarak işlemlerin PostgreSQL’in kendisi üzerinden uzun sürmesi durumunda işlemlerin iptal edilerek SQS’lere tekrar bırakılması sağlanmakta. Job üzerinden yapılan işlemlerde statement_timeout 45dk olarak belirlendi. Burada 1 saat bizim periyodumuz içinde olduğu için 45dk kabul edilebilir bir uzunluk. Diğer yandan Consumer API üzerinden açılan session ve insert sorguları için 5sn tanımı yapıldı. Eğer session açmada ya da insert işleminde timeout alınırsa Postgre’de işlem iptal edilmiş oluyor. Biz lambda üzerinden hatayı catch ediyoruz ve SQS’e tekrar bırakıyoruz. Bu şekilde veri kaybı da engellenmiş oluyor.

Saatlik değil de dakikalık işlem yapılabilir mi?

Dakikalık işlem yapmak için kapasitelerde artışa gidilebilir. PostgreSQL birden çok slave ile çalıştırılabilir. Aynı zamanda hem job tarafında hem Mongo hem de API tarafında da istekler dakikalığa göre çok daha güçlendirilmesi gerekir. Elimizdeki topoloji sayesinde her bir birim kendi içinde scale edebiliyor. Bu noktaya donanım güçlendirmesi ile çıkılabilir. Ayrıca başka bir öneriyi de aşağıda yer alan iyileştirilebilir noktalar başlığında paylaşıyoruz.

Dakikalık kurguda donanımsal güçlendirilmesi gereken noktalar

Örneğin: Saate bir defa 270 kırılımlı bir sorgu çalıştırdığımızda günde 270 * 24 = 6480 eder. Bunu dakikada bir defa yapacak olursak 270 * 60 * 24 = 388800 eder. Yani 60 katı fark var. Çarpmaya gerek var mıydı! 🙂 Bu bir sorgu başına olan artış. Tüm sorgularınız için bunu yaptığınızda çok daha artmış olacak. Dolayısı ile kapasitenizi buna göre inşa etmeniz gerekiyor.

İşlem adeti ve hızını nasıl kontrol ediyorsunuz? Musluklar nereden açılıp kapanıyor?

Eğer SQS’den daha fazla iş alır, daha fazla paralel iş çıkartırsak dolayısı ile daha hızlı işlem sonuçlandırabiliriz. Ancak paralel yapılacak işlem adetinin artması demek farklı maliyetler ve problemleri yanında getirir.

Paralel koşu miktarını kontrol eden musluk başları

Yukarıdaki görselde görünen kırmızı çemberlerin olduğu kısımlar paralel yapılacak işlem adetlerin yönetimini kontrol etmekte.

  1. Consumer Lambda, SQS üzerinden eğer gelen veri adeti 1000 üzerine çıktı ise ya da son alınan veriden 30 saniyeden fazla süre geçti ise SQS den işleri alır ve consumer lambda container’ı açar.
  2. SQS’in üzerindeki iş yüküne göre maksimum 10 tane container’ın açılmasına izin verilir. Çok fazla container’ın paralel sorgu yapıp PostgreSQL’e gelmesi sınırlanmış olur. Teknik olarak 10 container için her birinden 1000 tane insert ile maksimum 10000 insert işletiliyor. Insert’ler işletilmeden önce Consumer Lambda tarafından gruplanarak aynı tabloda olanlar birleştirilip tek bir bulk işlem olarak sisteme kayıt ediliyor. Örneğin bir container’ın insert etmek istediği 1000 işlem 3 tabloya dağıtılacağını düşünelim bu durumda 3 bulk insert ile 1000 veri eklenmiş oluyor.
  3. Job’ları içeren SQS üzerinden 10 iş alımına izin verilir.
  4. Worker paralel olarak PostgreSQL’e maksimum 10 sorguyu paralel koşturmasına izin verir. Bu şekilde PostgreSQL’in üzerinde yükü yönetir. Postgre gelen verideki Insert’lerden çok etkilenmeden çalışırken asıl yükü job’lardan gelen select sorguları ile alır. Buradaki maksimum 10 sorgunun işletmesi sağlanarak yük düzenlenir. Ayrıca buradaki rakamın artması PostgeSQL üzerineki IOPS tüketimini de artıracağı unutulmamalıdır. IOPS yetmeme durumunda ise PostgreSQL’e yazılmak istenen veriler yavaşlayabilir ya da fail olup verileri tutan SQS’e geri konabilir.

Geçmişe dayalı sorgular çalıştırılabiliyor mu?

Evet. Sistemimizin en güzel yanlarından birisi bu. Bazı platformlar veri yapısında değişiklik yapıldıktan sonra geçmişe dönük işlem yapamaz. Bizim sistemde raw datayı barındıran PostgreSQL’e yeni job’lar ile tekrar sorgu başlatmak yeterli. Yeni structure’a göre verinin özetini çıkarmış oluyor.

Geç gelen event’ler gerçek zamanlarına göre işleme dahil ediliyor mu? Kaçan trene sonradan binebiliyor muyuz?

Bir sebepten event’i PostgreSQL’e ulaştırmada sıkıntı yaşadık. Gelen event 1 saatten fazla geç geldi diyelim. Bu durumda ne olması beklenir. 1 saat önce çalışan job’un işi zaten bitmiş, özet MongoDB’ye taşınmış olması gerekir. Evet bizim sistemimiz de öyle ancak bu tür durumların oluşması durumunu da göz önüne alarak her zaman worker job oluştururken tüm özetlerin 24 saatlik geçmiş verisini de işleyecek şekilde tekrar tüm sorguları çalıştırır ve güncellenen veri Mongo’ya basılır. Eski veri gizlenir ve daha sonradan silinir. Bu şekilde bir update işlemi de yapılmış olur. Harika bir özellik değil mi 😎

Consumer Lambda ile SQS arasında loop oluşturacak bir tehlike yok mu?

Evet var. PostgreSQL düştüğünü düşünelim. Bu durumda Consumer Lambda üzerine aldığı işleri PostgreSQL’e yazamadığı için geri SQS’e bırakacak. Sonra tekrar alıcak sonra tekrar bırakacak. Bu durumda bir loop oluşacak ve oluşan loop’un her çağrısı lambda üzerinden yapıldığı için şirkete maliyet üretecek. Bunu engellemek için eğer lambda üzerinde işlem sonuçlanamazsa CloudWatch üzerinden alarm alıyoruz. Bu şekilde bu tip durumlar için müdahale ediyoruz. Ayrıca paralel koşuyu sınırlama ayarımız burada bizi bir seviye koruyan diğer kısım. Çünkü belirli bir ölçekte iş alıyor ve sonuçlanmasını bekliyor.

Yapı nasıl daha iyileştirilebilir

Genel olarak değerlendirdiğimizde birimlerin her biri kendi içinde genişleme yeteneğine sahip olması yük artışına paralel genişleme imkanı sağlayacak olarak görünüyor. Ancak iki noktada PostgreSQL üzerindeki performans artışı yapılabileceğini düşünüyoruz.

  1. Birden çok PostgreSQL kullanarak yük dağıtılabilir. Örneğin ülke kırılımı yapılarak Amerika’dan gelenleri bir DB’ye, Türkiye’den veriyi başka bir DB’ye konumlandırarak sorguların daha kısıtlı verilerde işletilip sonuçlarının MongoDB üzerinde toplanması sağlanabilir.
  2. Raw veri tutan PostgreSQL dışında verisi sadeleştirilmiş bir PostgreSQL’i kullanarak sorgu yapılacak veri miktarı azaltılabilir.
Raw data’nın tutum şekli

PostgreSQL üzerinde veriler JSONB formatında tutulmakta. Veri dediğimiz kısım developer’ın kendisine ve kaynağına göre değiştiği için asıl işlenmesi istenen veri data alanı içinde yer alan JSON içinde yapılmakta. PostgreSQL JSON üzerinde işlem yapma konusunda her ne kadar başarılı olsada developer’ın gönderdiği JSON genellikle özetlenmek istenen veriden çok daha fazlasını içeriyor. Örneğin bir JSON içinde 30 değişken varken bunun sadece 3–4 tanesi kullanılarak özet çıkartılıyor. Bu durumda iki noktada performans kaybı var.

  1. JSON objede arama işlemleri yapılıyor.
  2. JSON objesi içinde çok fazla gereksiz bilgi var. Bu da çok fazla veri içinde gezinti demek oluyor.
Yapılandırılan veriyi içeren PostgreSQL’in sisteme eklenmesi

İşte bu noktada sadeleştirilmiş veriyi PostgreSQL’e relational database’in tablo yapısında taşıyabilirsek hem veriyi JSON olmaktan çıkartıp tablonun sütunları haline getirmiş oluruz hem de gereksiz verileri buraya taşımadığımız için çok daha az veri içinde sorgu çalıştırmış oluruz.

Kapanış

Big Data platformu kurulmak isteniyorsa öncelikle gereksinim iyi belirlenmesi gerekiyor. Gereksinime göre kurulacak yapı, teknolojiler seçilebiliyor. Enes’in söylemi ile “Rapor sondan başlar.”

Yukarda detayları ile anlatmaya çalıştığımız yapı PostgreSQL’in yokluğunda S3 üzerinden Apache Spark ile ya da diğer bir Big Data çözümü ile de kurgulanabilirdi. Bizim tercihimiz PostgreSQL oldu ve bunu tercih ettiğimiz için de memnunuz. Öncelikli olarak şunu göz önüne almak lazım. PostgreSQL de, MongoDB de yaygınlıkla kullanılan, bir çok developer’ın rahatlıkla üzerinde çalışabileceği yapılar. SQL kullanarak PostgreSQL üzerinde sorgu çalıştırabiliyorlar. Bu önemli bir kazanımımız oldu. Diğer yandan Apache Spark, Flink, Druid, Presto gibi bir çözüm ile ilerlemiş olsaydık hem yapının kurulması hem veri işlemede kullanılacak yapıların hakimiyeti düşünüldüğünde SQL göre zor olacaktı. Şu unutulmamalı ki bu gibi Big Data platformu teknolojilerine hakim dünya genelinde çok kısıtlı geliştirici mevcut. Bu açıdan kurduğumuz yapıyı nispeten developer friendly olarak değerlendiriyoruz. Daha kolay ve hızlı bakımı yapılabileceğini, daha fazla insanın konu üzerine çalışma cesaretini gösterebileceğine inanıyoruz.

Son olarakta şunu vurgulayıp bu uzun yazının kapanışını yapalım. Facebook like, share ve diğer verilerini MySQL üzerinde konumlandırarak hizmet veriyor. Son dönemde geliştirdikleri RocksDB’ye bunların bir kısmını taşıdılar. MySQL bir Big Data platformu olarak görülmesede bu platform üzerinde petabyte’larca veri işleyecek yöntemler geliştirmişler. Benzer şey Discord ekibinin mesajlarını saklama ve sunak için MongoDB’yi bir süre kullanmış olmaları. Yani Big Data için PostgreSQL de, MySQL de, MongoDB de güzel alternatifler. Önemli olan doğru veri saklama ve sorgulama yapıları kurarak çıktı elde etmek.

Ümit ederim bu yazı siz kıymetli geliştirici arkadaşlara bazı konularda ilham ve bilgi kaynağı olmuştur. Olabildiğince açık ve detayları ile paylaşarak nasıl bir Big Data platformu kurulabilir anlatmak istedim. Beğendiyseniz like butonuna basmayı unutmayın ve yazımızı paylaşırsanız daha fazla insanın gelişmesine destek olabilir, ekosistemi bilgi paylaşması konusunda cesaretlendirebilirsiniz.

Doğan Aydın

Yorum yazarak ya da Twitter veya LinkedIn üzerinen bana direk mesaj atarak ulaşabilirsiniz. Twitter üzerinde teknoloji odaklı paylaşımlar yapıyorum daha fazlası için twitter’dan beni takip edebilirsiniz.

Teşekkürler

Bugüne kadar ürettiğimiz onca mobil uygulama ve geliştirdiğimiz onlarca altyapı için samcro’ya sonsuz teşekkür ediyorum. Samcro’nun bir parçası olma şansı bulduğum için minnettarım…

Big Data projesine hayat veren Enes Gür ve Furkan Salkım’a da yoğun çabaları için çok teşekkürler.

Referanslar

--

--

Doğan Aydın

CTO@TurkNet, Software developer, Dad, History book lover, Cyclist, EU4 and HIO4 video games fan, Junior writer, Amateur traveler