Najpopularnija hrvatska sportska aplikacija u svijetu i vjerojatno najopsežniji dostupni izvor za sportske statistike uopće, Sofascore, prava je tehnološka tvornica koja teži savršenstvu
Hrvatska aplikacija Sofascore diči se time što pruža opsežne podatke, rezultate, detaljne statistike i brojne druge podatke o sportskim događajima, u stvarnom vremenu, za milijune korisnika diljem svijeta. No, što stoji u pozadini te priče? Kako se njihovi sustavi nose s tolikom količinom podataka i navalom korisnika, kojih nerijetko više milijuna u isto vrijeme želi pogledati isti podatak? O tome smo popričali s ljudima koji vode inženjersku stranu priče u Sofascoreu. Oni su Josip Stuhli, CTO (našoj publici poznat kao izvrsno ocijenjen predavač s .debuga 2021) i Dejan Vasko, Principal Engineer.
Krenimo s “laganim” pitanjem – koje tehnologije koristite u Sofascoreu, i zašto?
JOSIP: Što se tiče backenda, tu je PHP, i to na zadnjoj verziji (8.2), jer ta naša ekipa jako voli biti na “bleeding edge” tehnologiji, pa sve nove verzije testiraju u produkciji i prije nego su službeno objavljene (smijeh). Jednako tako, uvijek se koristi i najnovija verzija frameworka, u ovom slučaju Symphonyja. Baza podataka nam je Postgres, budući da ona može “prožvakati” veliku količinu podataka. Svojom tehnologijom MVCC omogućava nam istovremeno čitanje i pisanje podataka. To nam je važno jer obično imamo jako puno promjena u kratkom periodu, npr. tisuću sportskih događaja istodobno s kojih stižu stotine statistika, a mi ne možemo dozvoliti da korisnici čekaju ažuriranje podataka. Ne bi to svaka baza mogla podnijeti.
Što se tiče frontenda, web aplikacija je pisana u Reactu, također na najnovijoj verziji. Iznimno se pazi na kvalitetu kod puštanja novih ažuriranja, tu postoji razrađeni proces kontrole prije deploya. Unatoč tome, dnevno se novi featurei u produkciju puštaju i do 50-ak puta, ali kako je proces razvoja vrlo brz i radi se na manjim inkrementalnim promjenama, lako je detektirati gdje se problem pojavi i odmah ga popraviti.
DEJAN: U mobilnim aplikacijama nemamo release svaki dan 50 puta. Radi se u dvotjednim sprintovima, pa i ažuriranja idu svaka dva tjedna. Nadogradnja ide kroz to vrijeme od developera, preko QA, pa sve što se unutar tog razdoblja skupi, uključuje se u testnu alfa verziju. Još jednom sve prolazi kroz QA, pa tek tada ide na store. Tamo se pušta postupno, kako bi se nadogradnja provjerila i u praksi. Tek tada pušta se i na veći broj korisnika, kako bi sve bilo savršeno i sigurno dobro.
Koje programske jezike koristite u razvoju mobilnih aplikacija?
DEJAN: Tu naravno imamo Android i iOS. Na Androidu cijela je aplikacija bila napisana u Javi. Kada je prije koju godinu izišao Kotlin, prvo smo malo pričekali da ga i Google prihvati kao službeni jezik, pa smo počeli pisati i u njemu. Nismo sve još prebacili, ali s vremenom je to došlo na oko 70%. Nikamo nam se ne žuri, jer većina naših ljudi dobro poznaje ta oba jezika.
Na iOS-u je aplikacija prije bila napisana u Objective-C-u, a onda se pojavio Swift. Tada se počelo pisati u njemu, pa je sada i tu na oko 70% već prebačeno na novi jezik. Ovdje je naglasak na to da se sve prepiše u Swift jer većina novih developera koristi isključivo njega. Ovim ritmom ćemo kroz možda godinu dana biti 100% na Kotlinu i Swiftu.
JOSIP: Dodao bih i da mi ne prepisujemo kod u drugi jezik samo zbog toga da ga prepišemo. Proces ide prirodnim tijekom, pa sve ono što se u nekom trenutku “dira”, radi se na novom jeziku. Ipak imamo preko 23 milijuna mjesečno aktivnih korisnika, pa moramo biti iznimno oprezni da se ne pojave bilo kakve greške u produkciji. To bi odmah rezultiralo “jedinicama” u App Storeu.
Što je s backendom?
JOSIP: Cijeli backend nam se vrti na unajmljenim “bare-metal” mašinama, dakle ne u cloudu. Time upravlja naš DevOps tim, od instalacije OS-a na dalje, tako da je sve pod našom kontrolom. Koristimo i Kubernetes, koji nam omogućava bolje upravljanje, automatsko oporavljanje grešaka i ostale optimizacije, kao da smo u cloudu, dok ne plaćamo visoke cloud cijene. Koristimo se uslugama dvaju podatkovnih centara u Francuskoj, koji su redundantni i na različitim lokacijama. To nam se pokazalo najboljim rješenjem, jer čak i da jedan od data centara izgori, naš sustav može potpuno normalno raditi na drugome.
Vaša aplikacija vjerojatno komunicira s “milijun” API-ja. Kako upravljate tim integracijama i kako osiguravate njihovu pouzdanost?
JOSIP: Nije baš milijun, ali ih je jako jako puno… To je zaista poseban izazov, jer partneri su brojni i različiti. Mi imamo cijeli sustav za unos, filtriranje i spajanje podataka. Konkretno, postoje kompanije koje šalju svoje ljude na stadione, oni unose podatke, a mi te podatke od njih kupujemo. Naravno, kupuje se od različitih kompanija, a svaka od njih ima svoje posebnosti, set API-ja, pa i set problema. Podaci o istim timovima se često u različitim sustavima pojavljuju pod različitim oznakama, da spomenem samo jedan od problema. Mi potom moramo biti u mogućnosti to sve prepoznati, spojiti sve ulazne podatke, kako bi naš korisnik dobio kvalitetnu informaciju.
Kada korisnik otvori Sofascore i pogleda detalje jednog meča, trenutačno se tu radi o agregiranju 30-ak različitih izvora podataka, što plaćenih, što iz javnih izvora, što izravno od naših ovlaštenih korisnika, koji sami unose podatke kroz aplikaciju Sofascore Editor. Tu je i crowdsourcing, jer svi korisnici mogu predlagati pojedine promjene, pa naš pametni algoritam razaznaje koje od tih promjena su legitimne i koje će se unijeti u bazu.
Kako se nosite s tolikim brojem korisnika, koji svi žele istodobno znati da je pao gol?
JOSIP: Mnogo radimo na tome da se cijeli sustav optimizira za brzinu slanja push notifikacija. Trenutačno ih možemo poslati milijune u desetak sekundi. Dakle više-manje svi korisnici koji prate popularne utakmice u isto vrijeme će dobiti notifikaciju. Oni u pravilu imaju mobitel kraj sebe, pa kad im dođe obavijest, oni će na nju kliknuti i potom će svi – u istom trenutku – doći pogledati podatke o toj utakmici. Kad je riječ o popularnim utakmicama, tolika navala korisnika inače se naziva – DDoS. No, ovdje si ga mi sami sebi svjesno radimo, pa moramo imati sustav koji je sposoban nositi se s tim vršnim opterećenjima.
Čak smo imali i problem s Cloudflareom, koji nas štiti od DDoS napada. Oni su taj obrazac počeli prepoznavati kao napad, iako je legitiman. Morao sam otići u Ameriku k njima, kako bih im objasnio da je to sve OK. Morao sam tamo doći do inženjera koji razumije problem i koji je otkrio da ponašanje aplikacije “okida” neka njihova pravila. U konačnici, Cloudflare je samo za nas napravio iznimku u svojem kodu, kako ne bi naš promet proglašavali DDoS-om.
DEJAN: Sa strane aplikacije priča je nešto jednostavnija, jer se vežemo na naš backend, s čijim se timom lako možemo dogovoriti. Ipak, aplikacija nam ima nešto više od 200 endpointova – svaki ekran, svaki tab, pa unutar njih, sve to je segmentirano radi cachea i da bi se mogle brzo pratiti promjene u mečevima. Samim time s promjenama u utakmicama mijenja se samo dio podataka, dok ostalo može biti i u cacheu. Na sve to imamo i sockete, kojima se osvježavaju najvažnije informacije u stvarnom vremenu.
JOSIP: Ima tu još nešto specifično za nas. Standard u industriji je da se podaci u aplikacijama osvježavaju, primjerice svakih 15 sekundi, što nije loše. No, mi “nismo normalni”, puno polažemo na to da sve bude brzo i optimalno, patimo na to da korisničko iskustvo bude što bolje. Shvatili smo da je tih 15 sekundi predugo, i da neki taj vremenski odmak mogu percipirati kao bug. To smo riješili tako da je svaka aktivna aplikacija povezana s našim socket serverom, pretplaćena na ono što vidi na ekranu. Dakle, čim se dogodi promjena, ona se prikazuje onima koji su na nju pretplaćeni. Nismo mi to izmislili, to se zove Pub/Sub (publish-subscribe), i zahvaljujući tome možemo brzo svima prikazati promjene. Tu je dodatni izazov što bude i po više milijuna aktivnih konekcija, pa server mora biti vrhunski konfiguriran da bi to sve podnio, ali i kako bi u memoriji imao sve te konekcije i poslao obavijesti na prava mjesta.
Mi tu zaista idemo do ekstrema, pa ako utakmicu recimo pratite preko IPTV-a, koji malo kasni, promjena rezultata će vam se prije prikazati u Sofascoreu nego što ćete je vidjeti na ekranu. Čak su nam se ljudi zbog toga i žalili, pa tražili da im “usporimo” dostavu notifikacija. Naravno, taj feature nismo dodali (smijeh).
Inače, u Sofascoreu se generira oko 800 TB prometa prema van i više od 200 milijardi zahtjeva na servere – svaki mjesec! Pratimo i akcije korisnika u aplikaciji, pa je i tu njih preko milijardu dnevno, odnosno oko terabajt podataka. Mi te podatke sve čuvamo od 2019., pa imamo pohranjeno preko jednog petabajta podataka, koje analiziramo da bi sustav bio bolji. To je u punom smislu riječi “big data”, na kojem radi naš analitički AI/ML tim.
Na kraju, možete li nam otkriti neke od planova za budući razvoj vaše aplikacije? Kakve inovacije i poboljšanja možemo očekivati u bliskoj budućnosti?
JOSIP: Sljedeća velika stvar za nas je dodatni razvoj crowdsourcinga, koji želimo podići na višu razinu. Ako uzmemo za primjer Google Maps, dobar dio korisnih informacija tamo je nastalo na taj način, a i vrlo brzo se tako ažuriraju. Mi sad želimo preko našeg Sofascore Editora osnažiti sve niže lige u svijetu, koje nisu dovoljno dobro popraćene, tj. dati im globalnu pozornicu, gdje će svi moći vidjeti rezultate, pratiti mlade sportaše od malih nogu i nižih liga. Recimo, da sada možemo pogledati cijelu povijest igara Luke Modrića, od početaka i prvih utakmica, pa do danas – to bi bila izuzetno korisna informacija, a teško da bismo mogli doći do nje.
Primijenimo li taj koncept na cijeli svijet, bilo bi to korisno i brojnim roditeljima, koji će kroz našu aplikaciju moći pratiti svoje dijete, ali i upisivati rezultate nižih liga ako žele. Sofascore Editor, koji ima ovlaštene korisnike, proširit ćemo pravim, otvorenim crowdsourcingom, uz to da se algoritmima eliminiraju manipulacije i greške od kvalitetnih podataka. Mi bismo najradije htjeli, da možemo, apsolutno svaki meč koji se igra u svijetu željeli imati unesen, kako bi se podaci o njemu mogli pronaći u našoj aplikaciji.
DEJAN: Spomenuo bih tu i naših pet cross-funkcionalnih timova. Jedan se bavi, primjerice, dodavanjem novih sportova, drugi radi na nadolazećem redizajnu aplikacije, treći radi samo A/B testiranjem određenih funkcionalnosti i promjena, itd… Cilj nam je složiti i tim za rast i monetizaciju, uglavnom puno se toga trenutačno događa u Sofascoreu.
Ako vam se sviđaju tehnologije i teme o kojima pričaju dečki iz Sofascorea, slobodno pogledajte otvorene pozicije i prijavite se!