Nah, hát akkor adjunk a rendszerhez egy új funkcionalitást. Ebben a konkrét esetben szeretnék hordozható dolgokra hirdetéseket pakolni. Pl szeretnék a hirdetők megcélozni azokat az androidos tableteket, amiket a Samsung gyárt. Hogy miért? Mert hosszú piackutatások után azt találták, hogy ez a réteg nagy valószínűséggel veszi meg a termékeiket. Vagy valami ilyesmi.

Namármost a feladat jól van definiálva. Egy harmadik féllel van is megállapodás, ami szolgáltat mindenfajta információt useragent-ek alapján a készülékről. Nekem csak annyi a dolgom, hogy lekérjem.

Itt kezdődnek a problémák. Egy lekérés mondjuk a szolgáltatott XML file-ból túl sok idő. Meg kell nyitni, be kell parse-olni, és akkor még ha szerencsésen csinálom akkor is valszin lineáris. Szóval amikor a rendszer indul, be kell rakni az egészet a memóriába. Nade csak úgy simán nem elég, mert mivan ha valaki operációs rendszer szerint akar szűrni, más meg valami más kombinacióra. Akkor hogy elég gyors legyen (ez még csak előszűrés, igazából a teljes hirdetéskiválasztáshoz van kb 3-5 milisec) sok különböző kulcsokra és hashtáblákra van szükség. Van kb 8k telefonfajta, nemtomhány oprendszer és gyártó... mondjuk azt hogy kb 10-12k kulcsos táblám lesz. Miltikey for the rescue, fingerprint a kulcsokról, máris csak 8 byte-osak a kulcsaim. Persze az adatok amire mutatnak az másik 16-24 byte, de sajnos ezt nem tudom elkerülni. Szóval 10k kulcs, 24 byte adat, 5 szerverparkban, összesen kb 600 szerveren... még nem csináltam semmit és máris 137MB adatot pakoltam memóriába a teljes rendszeren.

Ennél sokkal szebb, amikor tényleg adatokat kell összehasonlítani. Tegyük fel hogy minden hirdető rájön, hogy ez egy jó kis funkcionalitás. Kiválasztanak 1-2 oprendszert és 5-6 nagyobb márkát. Most hogy milyen a típusa az végülis mindegy, meg legyen bármilyen verzió. Azért mondjuk minimum os verziót megadnak. Szóval ez 2*8 byte oprendszer adat (igen itt lehet még optimalizálni, elvben nem kellene long id, de a harmadik fél csak közepesen konzisztens), kell 6*8 byte a márkákra, meg mondjuk 2*2*8 byte a verzióra. 96 byte. Még néhány byte hogy a többi adatot null-ázuk. Szóval >100 byte adat, de jelenleg 200k ilyen halmaz van a rendszerben. 20 MB adat a memóriába per szerver.

Akkor még le kell kérnem a mit sem sejtő böngésző adatait (500k-szor másodpercenként), user agent-eket parsolni (1M ua parse-olásnál átlagosan 0.0178ms per ua) és azt veszem észre, hogy kicsinként hozzápakoltam 100MB adatot szerverenként a memóriába, úgyhogy heap-et kell növelni. Megnöveltem a kiválasztást kb 0.3ms-al, ami épphogy még elfogadhatóan benne van a 3-5ms kiválasztásba (igen, draga hashelni). És én még azt hittem ez nagyon optimalizált kód egy nagyon egyszerű feladatra. Jah, és ez főleg még csak az USA, ázsiában ez sokkal több lesz.

Namármost ez csak 4-5 új adat volt és kb négy nap munkám. Jelenleg kb 1000 paramétert használunk egy felhasználónál. Van még mit tanulnom.

Utoljára módosította Ulmar 2012.IV.17 08:37-n
PermaLink

Hozzászólások

2

UPi 2012.IV.19 16:36

...És akkor itt még nem beszéltél az olyan performance-t érintő tényezőkről, mint pl az, hogy a több adat milyen hatással van az L1 és L2 cache-ekre azokon a hardver konfigurációkon, ahol mindez futni fog, avagy van-e korreláció a user agent és egyéb metrikák között.


Ulmar 2012.V.03 08:15

(Válaszképp erre)

Hát akkor hamár ez szóbajött:

Szóval alapvetően a szervereink... monstrumok. 24 core, 128GB memória, SSD wincsik sok terra mennyiségekben. És rack-rack hátán az egészből. Az adat mennyiség amivel dolgozom már L1-L2 cache felett van, azzal nem tudok mit csinálni, de pl az adatok nagyrészére bitmask-ot számolni és tárolni, azzal nincs gond.

Viszont bizony épp ma benchmark-oltam, hogy ha nem tároljuk az adatokat egyesével, hanem csak a user agent-eket és azt újraparsoljuk adatbányászatnál, az hogy fog működni. Aztán csak poénból építek dinamikusan egy hashtáblát is a dologhoz, hiszen kit érdekel ha a hadoop node-ok minden egyes darabjal felhúzok még néhány giga adatot a memóriába... van nekik most épp elég. Nos, hát gyors. Kellően gyors, hogy nyerünk annyit a helytakarékossággal és az opcióval hogy később más adatot is kinyerjünk a user-agent-ekből, hogy érdemes legyen ezt csinálni. Érdekes hogy bepakolni nihány gigát a memóriába (node-onként) az olcsóbb mint pl 200 byte-al megnövelni a felhasználók profijának adatait. Ez van ha milliárdokban kezded mérni a felhasználó adataidat.

Amúgy így átlagosan egy user-agent-et 4-szer fogok parse-olni, és 2-szer egyéb lookup-ot csinálni. És még így is megéri, semmint szétszedni darabjaira és csak egyszer parseolni.

Tagek: