folder Tahribat.com Forumları
linefolder Bilgisayarla İlgili Diğer Konular
linefolder 10.000 Kişilik Requesti Naısl Yönetirim? (Tecrübeli Yazılımcılar)



10.000 Kişilik Requesti Naısl Yönetirim? (Tecrübeli Yazılımcılar)

  1. KısayolKısayol reportŞikayet pmÖzel Mesaj
    zeybekustasi
    zeybekustasi's avatar
    Kayıt Tarihi: 24/Mayıs/2012
    Erkek

    Bir mobil uygulama var.

    Aynı anda 10.000 tane kişi var içerde.

    Hepsine bi soru soracağım. Cevabı aynı anda 10.000 kişi de sunucuya gönderecek.

    En hızlı doğru cevap verene "cevap verme süresini" ve doğru yanlış bilgisini döneceğim.

    Yani 10.000 kişi request gönderecek 10.000 kişiye tak diye response dönmem lazım.

    Bunu nasıl yaparım?

     

    Flutter + Web api ile sunucu üzerinden request leri karşılayamam bence. Sunucu yavaş çalışır böyle olmamalı sanki.

    Flutter + Web api + RabbitMq + Response şeklinde mi yapmam lazım.

    Ya da socket mi kullanmam lazım. 

    Burada bana basit bi çizim yapabilir misiniz? Yada telefonumu versem iki dakka kullanmam gereken teknolojileri söyleyebilir misiniz? Sadece konsepti anlasam yeter detay bilgi istemiyorum.

     


    https://www.youtube.com/watch?v=WC3-71NKwPw
  2. KısayolKısayol reportŞikayet pmÖzel Mesaj
    LevhiMahfuz
    LevhiMahfuz's avatar
    Kayıt Tarihi: 15/Temmuz/2015
    Erkek

    Merhabalar,

    10K req/sn düzgün yazılmış bir API için abartı bir yük değil ancak tahmin ediyorum response için bir yorumlama adımı daha var. Flutter tarafını bilmemekle birlikte işin mimari tarafını gelen requestlere göre yorumlayacağım.

    Kullanıcılara gönderilen sorunun yanıtı, /api/response endpointine gelecek. Bu endpoint veritabanına (MySQL olsun) her kullanıcıya ait yanıtı ve tarihi INSERT edecek. Aynı zamanda doğru yanıt için SELECT atarak, gelen verileri API tarafında yorumlayıp, kullanıcıya gösterecek.

    Kaba hesap ile, 

    10K API req/sn
    10K Insert/sn
    10K Select/sn 

    1 saniye içerisinde, eski tip mimari ile 30K işlem gerçekleştiriyorum. 

    Ben olsam, API için request ve response tarafına ayrı bir microservice olarak yaklaşarak Kubernetes tercih ederdim. Ingress (nginx) gücünüde kullanarak, aksiyon süresinden önce manuel scale ederdim ki riski minimize edeyim. Konunun başında da dediğim 10K req/sn yüksek bir rakam değil ancak 10 küçük pod ile, her poda 1K yük gibi hesaplardım. Probe tarafına hiç girmeden, olurda 1-5 saniye arasında sürecek aksiyonda (herkes hemen cevap veremeyecektir, kimi okuyacak, kimi yanındakine soracak) bir tarafım patlarsa kalan podlar yaşamına devam edecektir. Ancak, veritabanı hala hayattaysa(!)

    Ayrıca, kullanıcılarım bugün 10K, yarın 50K olabilir; kolay scale etmem gerekiyor.

    Mutlaka aramızda sağlam DBA arkadaşlar vardır, benim DBA arkadaşlardan duyduğum/gördüğüm/tecrübe ettiğim kadarıyla bu rakamlar iyi kurgulanmış, gerekli kaynaklara sahip veritabanı sunucusu için hafif. Yine de bir veritabanı bağlılığı yoksa, bu tarz yüklerde MongoDB öneriyorum. Ancak, daha basit olsun, işimiz kısa yoldan çözülsün tarafında iseniz Redis'i tek geçerim :) 

    RabbitMQ ya da Socket, yukarıda yazdıklarım gibi bir yöntem, özellikle Socket anlık response için kıymetli ancak, sorunuz ekranıma geldi ve yanıtı seçip gönder dedim. Burada 1-2 saniyelik spin süresi her kullanıcı için tölere edilebilir bir değer olarak tahmin ediliyorsa bence gerek yok.

    Buraya kadar yeterince dallanıp, konuyu komplike hale getirdik :) Bir de şöyle ilerleyelim. 

    Flutter > Nginx (API) > MySQL (v.s.)

    Bu kurguda en zayıf halka 3. adım, veritabanı adımı. Bence bu şekilde kurgulayıp https://loader.io/ gibi (sanırım 10K requeste kadar ücretsizdi, tam hatırlayamadım) endpoint'i yük altına sokarsanız aşağı yukarı durum ortaya çıkacaktır. 

    * Bu konuda API için geliştirildiği dil, bahsettiğim veritabanı adımı, API tarafının çalışacağı ortam (Cloud ortamlar, OnPrem ortamlar v.s.), bağlılıklar gibi çok fazla parametresi olduğu için kesin konuşmam doğru olmaz fakat konuya bağlı her öznenin (teknolojinin) scale edilebilir olduğundan emin olmanızı öneririm. Yalnızca mimari tarafından düşünüp fikir vermeye çalıştım. Umarım faydası olur. 


    Uçamıyorsan, koş. Koşamıyorsan, yürü. Yürüyemiyorsan, sürün. Ama yerinde durma!
  3. KısayolKısayol reportŞikayet pmÖzel Mesaj
    2021 Talihlisi
    Deleted001
    Deleted001's avatar
    Kayıt Tarihi: 22/Kasım/2020
    Erkek

    Websocket, kuyruk yapısı da iş görür

  4. KısayolKısayol reportŞikayet pmÖzel Mesaj
    ndmylmz
    ndmylmz's avatar
    Kayıt Tarihi: 01/Ocak/2010
    Erkek

    Hepsine ayni anda response donmen gerekiyorsa araya bi queue sistemi koymanin anlami olmaz. 

    Bu arada anlik 10K request cok buyuk bir sistem degil. Golang ile sistem memory kullanimindan kacip yuksek sayilarda requestlere cevap vermen kolay olur. Yine de concurrency yakalamak istiyorum dersen bir Load balancer ile bu isi 3 5 belki 10 kucuk makineye dagitmak daha hos olur. 

    Frontend tamamen sana kalmis.

    Socket senin client ile sunucu arasindaki iletisimini hizlandirabiliriz ama bu durumda sunucu 10K socket connection'ini ayni anda acik tutmaya calisacaktir ki bu da kullandigin server paketine gore memory ve cpu sorunlari ciktartabilir. 

    10K kisiye ayni anda donmek yerine queue yapayim dersen orada o zaman RabbitMq isin icine giriyor olacak. Ama ben tak diye donucem dersen queue'dan uzak durman lazim. Queue seni horizontal'da sabit tutup (tek makine gibi) verticalde (yani islem surende) artisa neden olacaktir. Senin aradigin ise vertical i sabit tutup (islem sureni), horizontal'da (makine sayisinda artis ile) anlik cevap vermek.

    EDIT: Sistemini Go, gin, gorm gibi paketler ile kurarsan 512Mi 0.5vcpu lu bi makine ile anlik 10K gibi bi request saysiini karsilaman cok zor olmayabilir.

    ndmylmz tarafından 09/Tem/23 02:41 tarihinde düzenlenmiştir

    Sistemi de kapattım ama PHP konusunda hala yardımcı olurum // Boş gezenin boş kalfası - Öğrenci - YTÜ
  5. KısayolKısayol reportŞikayet pmÖzel Mesaj
    cukurova
    cukurova's avatar
    Kayıt Tarihi: 21/Aralık/2003
    Erkek

    Veritabanına kullacak mısın? App tasarımı nasıl?

    Duruma göre bunlardan birini veya ikisini aynı anda kullanacaksın; Redis / RabbitMQ / Apcahe Kafka / ZeroMQ ...

    CPU, Ram ve networking (=hosting) iyi olduğu sürece 10k talep fazla değil. Kolay gelsin.

  6. KısayolKısayol reportŞikayet pmÖzel Mesaj
    EnableTurk
    EnableTurk's avatar
    Kayıt Tarihi: 29/Eylül/2007
    Erkek

    Bence her soru için timestamp aralığını belirlemek gerek ve örneğin 60 saniye ise cevap süresi 600 parçaya bölüp hashlemek gerek. (sallıyorum 188233275235 timestamp için bir hash oluşturursun )

    Hashleri adama soruyla beraber gönderip, cevaba dokunduğu an için gerekli hash ile beraber, cevabı delay ederek de alabilirsin. (adam cevap verdiğinde ne zaman dokunduğunu da kendi sana iletsin. tabi buna müdahale edememesi için hashledik. )

    Hatta bu şekilde soruyu bile delay ederek parça parça gönderebilirsin insanlara.

    Bilmiyorum tabi nasıl bir yapı var da.


    seni 4 kere döverim yarın 🤙
  7. KısayolKısayol reportŞikayet pmÖzel Mesaj
    TeRRoR
    TeRRoR's avatar
    Kayıt Tarihi: 06/Nisan/2007
    Erkek

    Yapman gereken ilk şey 10k/s requesti simule etmeyi öğrenmek. Çünkü aksi taktirde burada hepimiz atarız tutarız.

    Benim ilk aklıma gelen şey latency. Kullanıcı cevap verdiğini ve bu cevabın sunucu tarafından en kısa sürede kayıt altına aldığımızdan emin olmalıyız. Cevabı biraz bekleyip sonra dönsekte olur.

    Bu noktada ilk mobil uygulamada sunucuya isteğini gönderirken mümkün mertebe minimum complex kod yazman lazım. Örneğin localstorage'dan token i okumak yerine bu sayfada kullanıcı geldiğinde token bir değişkene atanmış olmalı. IO'dan kaçın. Sonrasında bu işlemi async olarak tanımla hatta compute fonksiyonu ile çağır bunu. Sonrasında buradaki tojson ve json body'i ufak tut. 

    Backende gelincede durum illaki dağıtık mimariye uygun olacak şekilde tasarlanmalı. Fantazi yapıp go, rust, node js deneyebilirsin ancak web api işini gayet görecektir diye düşünüyorum. Burada yapacağın şey websocket açmak. Kullanıcı daha soru cevap aşamasına gelmeden sockete bağlanmış ve dinliyor olmalı. böylece handshake maliyetini önceden ödemiş oluyoruz. Backend async şekilde mesajı alıp zaman kaybetmeden queue'ya atmalı. Yarışma sonlandığında standart sorting algoritması ile hesap yapıp tüm kullanıcılara kazanıp kazanmadığını dönebilirsin.

    *Sorunun gönderilmesi kısmını unutmuşum. Bunuda yine socketten kullanıcılara göndereceksin. Burada 10k kullanıcıya ne kadar sürede soruları ulaştırabileceğin işi sıkıntılı burada belki online game dev'lerin yaptıklarına bakmakta fayda var adamların rutini bu iş. 

    Bence çokta şaapma çözülür mevzu.

     

    TeRRoR tarafından 09/Tem/23 05:16 tarihinde düzenlenmiştir

    herkes programcı olmak zorunda değildir, lütfen bir zorunluluk gibi programlama dilleri öğrenmeye çalışmayın. yabancı dil filan öğrenin amq.// s.kimin etini yerim, kasaba minnet etmem.// ince düşünene kalın girer.//
  8. KısayolKısayol reportŞikayet pmÖzel Mesaj
    MhmdAlmz
    MhmdAlmz's avatar
    Kayıt Tarihi: 09/Ağustos/2015
    Erkek

    Arkadaşlar bir çok şeyi özetlemişler. Benim de aklıma gelen en büyük maliyet boxing unboxing ve JSON decode/encode işlemleri. Basit gibi görünse de bu maliyetler yüksek request ve response değerlerinde yüksek bir işlem yükü gerektiriyor.

    50k r/s sahip olan bir sistem geliştirmiştik (deezer benzeri bir app) bir ekip ile (Mobil tarafında görev aldım) orada JSON yerine messagepack2 kullandık. Hem işlem süresi hemde trafiği çok ciddi optimize ediyor. Benchmarking sonuçlarına internetten erişebilirsin.

    Buradaki tek dezavantaj debug ederken JSON gibi rahat debug edemiyorsun. Veriler anlaşılır bir şekilde okunmuyor (Web API den dönen). 

    Backend de Crystal kullanmışları sebebini bilmiyorum ama o dönemlerde go pek popüler değildi. Adamlar .NET standart ile geliştirdikleri servisi Crystale taşıdığında sunucu maliyetinin nerdeyse %70 seviyesinde düştüğünü söylüyorlardı. Tabii ki de kalkıp Crystal öğrenmeye gerek yok bu aşamada sadece aklıma geldi. Belki ağır yük altında olan servislerini Crystal ile kodlayıp farklı makine de farklı bir servis ile hizmet verebilirsin diğer basit servisler .NET de REST API olarak kalır. 

     

    Micro service mimarisi ile kod geliştireceksen kesinlikle g-RPC öneririm. Yakın zamanda hem backend hem de frontend de deneyimledim. Servislerin arası haberleşmede zaten muazzam seviyede performanslı e birde sunucu<->client arasında çift yönlü haberleşme var (Socket + API derdin yok). Performans olarak bayağı iyi. Zaten RPC yapıları çook çook önceden kullanılan yapılar. Google RPC ile RPC entegrasyonunda bir çok işlem amaleliği ortadan kalkıyor. RPC de ki tek sorun bence WEB tarafında araya bir proxy server eklemek zorunda kalmak. Aradaki proxy server http 2.0 dan http1.1/1.2 convert işlemi yaptığından performansa biraz etki ediyor açıkcası. O da zamanla kalkacaktır tabii. Browser http2.0 desteğini verdiğinde aradaki proxy de kalkacak miss gibi yağ gibi bir sistem olacak.

     

    @TeRRoR Web ya da Mobil tarafta bahsettiğin gibi optimizasyona gerek var mı ki hocam? X bir kullanıcının microsaniye seviyesinde daha kısa beklemesi ne gibi bir avantaj sağlar ki? Neden IO işlemlerinden kaçınmalıyız merak ettim doğrusu. Yani hangi senaryo da patlar? Localstorage de tutsak ne direkt singleton sınıfta tutsak ne.

    Elbette singleton olarak tutarsak sürekli IO işlemi yapmayarak performansı arttırırız ama bu optimizasyon şart mı onu merak ediyorum. Sonuçta tek bir işlem ve tek bir kullanıcı. Bir döngü içerisinde IO işlemi yaptığımız durumda belirtilen kısma optimizasyon yaparız. Döngü içerisinde sürekli IO işlemi yapmak yerine tek seferde değişkene at kullan mantıklı da tek seferlik bir iş için gerek var mı ki? Daha doğrusu maliyeti O(n) ya da daha fazla yük gerektirecek işlemler için kesinlikle IO dan kaçınılmalı bunda aynı fikirdeyim fakat maliyeti O(1) olan bir işlem için optimizasyona girmeye gerek var mı ? bunu öğrenmek istedim.

     

    MhmdAlmz tarafından 09/Tem/23 10:47 tarihinde düzenlenmiştir

    Andolsun kuşluk vaktine ve dindiği zaman o geceye ki, Rabbin sana veda etmedi ve darılmadı! Ve kesinlikle senin için sonu önünden (ahiret dünyadan) daha hayırlıdır. ileride Rabbin sana verecek de hoşnut olacaksın! O, seni bir yetim iken barındırmadı mı? Seni, yol bilmez iken (doğru) yola koymadı mı? Seni bir yoksul iken zengin etmedi mi? Öyle ise, sakın yetime kahretme (onu horlama)! El açıp isteyeni de azarlama! Fakat Rabbinin nimetini anlat da anlat!
  9. KısayolKısayol reportŞikayet pmÖzel Mesaj
    acemi-webci
    acemi-webci's avatar
    Kayıt Tarihi: 11/Haziran/2008
    Erkek

    hocam web api için; tanımladığın soruyu, cevabı ve zamanını hem db hem de bellekte tut. soru endpointine gelen isteğe bellekten direkt soruyu gönderirsen db iodan kaçmış olursun. cevap endpointinde bellekteki cevabı ve zamanından hesap yapıp kullanıcıya response verip requesti tamamlasın bu sırada cevabı queue a göndersin. queue ile arkadan cevapları toplarsın dbye.


    ...
  10. KısayolKısayol reportŞikayet pmÖzel Mesaj
    end
    end's avatar
    Kayıt Tarihi: 16/Ekim/2016
    Erkek
    acemi-webci bunu yazdı

    hocam web api için; tanımladığın soruyu, cevabı ve zamanını hem db hem de bellekte tut. soru endpointine gelen isteğe bellekten direkt soruyu gönderirsen db iodan kaçmış olursun. cevap endpointinde bellekteki cevabı ve zamanından hesap yapıp kullanıcıya response verip requesti tamamlasın bu sırada cevabı queue a göndersin. queue ile arkadan cevapları toplarsın dbye.

    Başta mantıklı geliyor ama belli bir kotası olması lazım sanki bu dediğinin, 5gb ramlik mesela. Öteki türlü öter makine ciyak ciyak.

    end tarafından 09/Tem/23 21:07 tarihinde düzenlenmiştir

    0x0480 takilin madem ﷽﷽﷽
  11. KısayolKısayol reportŞikayet pmÖzel Mesaj
    emirhan-exp
    emirhan-exp's avatar
    Kayıt Tarihi: 10/Ocak/2010
    Erkek

    Hoca şifreli local çözümleri denemeye ne dersin mesela 5. Harf alfabenin sonuna doğru gitsin ve z 1 sn yi temsil etsin y 2 sn ve bunun gibi. Herkesin de appında timer olsun

     

    emirhan-exp tarafından 11/Tem/23 17:49 tarihinde düzenlenmiştir
Toplam Hit: 1994 Toplam Mesaj: 12
request