ugrás a tartalomhoz

Facebook like-ok tárolása

Radon · 2018. Már. 13. (K), 13.55
Valakinek van elképzelése, hogy a facebook hogyan tárolja a like-okat?
Ha van 1 milliárd felhasználód, azok az évek alatt több ezer milliárd like-ot hoztak létre. Ezeket hogyan lehet adatbázis táblákban tárolni?
Egy sql táblának van felső korlátja?
 
1

Bitek

Hidvégi Gábor · 2018. Már. 13. (K), 15.06
Ha 64 bites pozitív egész számként tárolják a lájkokat, akkor 18 446 744 073 709 551 615 lehet a legtöbb, ami adható.

A tábláknak vannak korlátaik, de az átlaghalandók nehezen érik el, a "nagyok" pedig különböző módokon kezelik a problémát.
2

De minden lájkoz tartozik egy

Radon · 2018. Már. 13. (K), 15.37
De minden lájkoz tartozik egy név, aki adta, egy bejegyzés, amire adták, egy dátum, meg a 6 féle like fajtája. ezt nem 1 számként tárolják, hanem egy like táblában minden like 1 külön sor. Ezt nem tudom elképzelni, hogy egy like táblának lehet 1000 1000 milliárd sora.
hát ez a különböző mód érdekelne.
3

Bontás

Hidvégi Gábor · 2018. Már. 13. (K), 16.57
Nem muszáj minden lájkot egy táblába tenni, lehet bontani több szempont szerint, például nemzetiség, bejegyzés típusa stb.

Azaz egy bejegyzés esetében a "magyar_bejegyzes_lajk" nevű táblából olvassák be, hogy az adott elemhez hány és milyen típusú kedvelés érkezett, a kommenteknél pedig a "magyar_komment_lajk" táblából.
5

Ja ez logikus. A

Radon · 2018. Már. 13. (K), 23.19
Ja ez logikus.
A magyar_bejegyzes_like tabla azt jelentene, hogy a magyar emberek altal letrehozott bejegyzesekre adott minden nemzetisegtol erkezo likeok. Akkor van gond, ha en 1 ember osszes like-jara vagyok kivancsi. Akkor minden nemzetiseg-bejegyzes-like tablajaba szet kell neznem, mivel magyar nem csak magyar posztot likolhat. Es pl a vine.co-n is osszesitve van az adott felhasznalo kapott like-jai. Ott is 100 milliokkal dobaloznak.
7

Példa

Hidvégi Gábor · 2018. Már. 16. (P), 23.33
Egy példa volt, ezerféleképp lehet csoportosítani. Ha pedig kivonatra van szükség valahol, arra lehet másféle táblát használni.
4

Biztos hogy nem relacios

smokey · 2018. Már. 13. (K), 22.24
Biztos hogy nem relacios adatbazist hasznal minden entitas tarolasara es minden feature kiszolgalasara a facebook. Inkabb tudnam elkepzelni a likokat egy fa szerkezetben levelkent, mintsem valami tabla szerkezetben.
6

Miért?

Hidvégi Gábor · 2018. Már. 16. (P), 23.32
Ezt kifejthetnéd.
8

Léteznek NoSQL adatbázis

smokey · 2018. Már. 17. (Szo), 01.03
Léteznek NoSQL adatbázis megoldások, mint pl mongodb. Gyakorlatilag egy objektum (dokumentum) gráfban tárolják az adatokat tábla alapú relációk helyett. Azért gondolom, hogy a Facebooknak ezen része (lájkok tárolása) is hasonló elven működhet, mert ilyen jellegű információt szerintem adminisztrálni és lekérdezni is egyszerűbb, gyorsabb, mintsem relációkat. Másrészről a graph api is elég árulkodó elnevezés.

Egyébként ezt te sem gondoltad komolyan:

magyar_bejegyzes_lajk
9

Miért?

Hidvégi Gábor · 2018. Már. 17. (Szo), 11.53
Miért gondolod, hogy a lájkokat egyszerűbb egy objektumgráfból lekérdezni? Egy kétdimenziós táblát sokkal könnyebb indexelni.

magyar_bejegyzes_lajk
De, komolyan gondoltam. Nincs különösebb jelentősége.
10

Kicsit ellentmondásosnak

smokey · 2018. Már. 17. (Szo), 16.08
Kicsit ellentmondásosnak érzem, amit írsz. Sok a rekord egy táblában, és azért hozol létre bármilyen csoportosítás szerint szerkezetileg tökéletesen megegyező táblákat, hogy egy egyébként nagy méretű tábla méretét csökkentsd.

Majd állítod, hogy

Egy kétdimenziós táblát sokkal könnyebb indexelni.


Ha könnyebb indexelni, akkor miért szórod szét valamilyen csoportorsítás alapján, hogy aztán még véletlenül se tudj egyszerűen joinolni, mert 100 táblából vadászod össze a rekordokat, mondjuk azzal a célzattal, hogy megtudd, hogy XY miket lájkolt.

Lehet én vagyok elborult, de ha szerkezetét és szerepét is tekintve megegyező táblából több van egy relációs adatbázisban, akkor ott tervezési hiba van. E szerint a magyar felhasználókat, az amcsi felhasználókat és a görög felhasználókat is külön táblában kellene tárolni, mert amúgy sok rekord lenne a users táblában? Vagy éppen a nőket és a férfiakat vennéd külön?
11

Miért tervezési hiba a

BlaZe · 2018. Már. 17. (Szo), 16.48
Miért tervezési hiba a sharding, vagy úgy általában a particionálás? Hogy tárolnál több gépen annyi adatot, ami egy gépen már nem fér el? Nyilván a példa nem volt szerencsés, de az elvet jól szemléltette szerintem.
12

Dimenziók

Hidvégi Gábor · 2018. Már. 17. (Szo), 17.02
A legjobb tudomásom szerint a dokumentum alapú adatbázisokban lévő rekordok többdimenziósak, és nem feltétlenül rendelkeznek fix adatszerkezettel. Ha így van, akkor nehéz őket indexelni, hacsak nem lehetetlen, így a bennük való keresés lassú lehet, vagy pedig nehézkes.

A hagyományos relációs adatbázisoknak is vannak korlátaik, az indexek mérete sem nőhet a végtelenségig, ezért érdemes darabolni.

Azt, hogy mire érdemes optimalizálni, a feladat dönti el. Úgy vélem, hogy mivel a legtöbb felhasználó mások által generált tartalmat olvas, ezért a legcélszerűbb típusonként (bejegyzés, hozzászólás stb.) tárolni a lájkokat. Jóval ritkább esetben van arra szükség, hogy egy felhasználó különböző típusú lájkjait gyűjtsék össze egy oldalon, ezért itt nem annyira számít, hogy hány lekérdezés kell hozzá. Ha mégis, akkor külön táblában lehet gyűjteni ilyen módon is.
13

Rakd össze :)

Pepita · 2018. Már. 18. (V), 13.35
Tulajdonképpen többen is közelítettek az igazsághoz, más-más nézőpontból, és valószínűleg ezek összetett egyvelege a valóság. (Előrebocsátom: nem vagyok fb fejlesztő, és több éve nem olvastam róluk tech cikket, tehát inkább technológiai infókra támaszkodom, nem tudom a konkrét fb megvalósításukat.)

Gábor:
Nem muszáj minden lájkot egy táblába tenni, lehet bontani több szempont szerint, például nemzetiség, bejegyzés típusa stb.
Még nem is muszáj egy adatbázisba, sőt, egy szerverre tenni. Ezek szinkronban tartása egy külön cikksorozatot érdemelne, maradnék annyiban, hogy a Magyarország nevű db szerveren azok az adatok (vagy replikák) tárolódnak, amik a magyarokat leginkább érdekli. Tehát a Gipsz Jakab haverom összes like-ja is elérhető az itteni db szerveren közvetlenül, viszont az ő Kínában élő keresztanyjáé is, mert a keresztmami ismerőseinek a 90%-a szintén magyar. (Keresztanyu dolgai persze a kínai szerveren is meg lesznek.)

Smokey:
Biztos hogy nem relacios adatbazist hasznal minden entitas tarolasara
Szerintem biztos, hogy a gyorsan megjelenítendő dinamikus adatokat mind relációs adatbázisban tárolják.
Más kérdés, hogy a master db-k nagy valószínűséggel NoSql db-k, de nem azokból kérdezget le, mert lassú lenne. Onnan csak szinkronizál a slave-ekre.
MongoDB: kifejezetten arra jó, hogy sokszor / sokat írsz bele, és nagyon ritkán kérdezel le, akkor is előre (tervezéskor) meghatározott struktúrában, szekvenciálisan. (Ilyesmit, mint MySql-ben ORDER BY vagy JOIN felejts el.) Arra semmiképp sem jó, hogy on the fly jeleníts meg belőle összetett adatokat, változó struktúrában.

BlaZe:
Miért tervezési hiba a sharding, vagy úgy általában a particionálás?
Pontosan, adott adatmennyiség felett már tervezéskor kötelező. :)

Gábor:
Azt, hogy mire érdemes optimalizálni, a feladat dönti el.
Így van. Szerintem itt a fő feladat (legalábbis a legtöbbet használt megjelenítés) az egy-egy poszt különféle like-ok száma, plusz a hozzá tartozó kommenteké.

Ez egy-két dolgot máris hoz magával:
- egy posztnak az összes like-ja lehetőleg egy táblában legyen
- egy poszt összes kommentje is egy tábla legyen
- egy poszt összes kommentjének like-jai is egy tábla legyen.
- amennyiben egy poszt bekerül egy regionális db szerverre, akkor "viszi magával" a kommenteket és a like-okat is.

Nyilván regionálisan (nem feltétlen országonként, de ezen ne akadjunk fel most) vannak "statikusabb" tároló megoldások masterként (oda csak megfelelő jogosultságokkal és útvonalról lehet írni), és ezeknek számos slave replikája a dinamikus megjelenítés érdekében. Ezeket igyekszenek jó szinkronban tartani.
Arra nyilván szintén kidolgozott szabályrendszer van, hogy a regionális masterek közül "ki" az "egyetlen" főfő gazdája egy adatnak (igazából nem 1 darab, de megérteni így könnyebb), a gyorsaság kulcsa gyakorlatilag a helymeghatározás, hogy mit hol érdemes "honosítani", a másik fontos dolog pedig az, hogy csaknem 1 - 1 kapcsolat lehessen két, tetszőlegesen választott regionális szerver között, meg is tudják találni egymást és rövid időn belül ki tudják szolgálni a másik szerver kéréseit.
Erre azért van szükség, mert amikor az új kanadai barátnőd adatlapjára / bejegyzésére klikkelsz elsőként, akkor még ő nem szerepelt a magyar db-ben, mégis meg kell tudni jeleníteni pár másodperc alatt.

Szerintem tábla szinten úgy néz ki a like, hogy pl táblanév: entry_like, mezők:
- entry_id (bigint)
- like_type (enum)
- user_id (bigint)
- timestamp

Indexelve van minden oszlop külön, esetleg ha valóban van olyan statisztika, hogy Gipsz Jakab "Hűha" típusú reakcióinak a száma, akkor like_type és user_id közösen is indexelt.
Partícionálni timestamp és entry_id mentén érdemes, egy entry maradjon partíción belül lehetőleg.

comment_like tábla lehet ugyanez a szerkezet. (És ez nem tervezési hiba. :) )