PostgresQ માં HyperLogLog સાથે વિડિયો હીટમેપ્સ બનાવવું
તમે એડિટર્સને બરાબર એ જ જગ્યા બતાવવા માંગો છો જ્યાં દર્શકો વિડિયો જોવાનું બંધ કરે છે.
આ કરવા માટે, તમારે હીટમેપની જરૂર પડશે. આ હીટમેપ વિડિયોના દરેક સેકન્ડ માટે યુનિક (unique) દર્શકો દર્શાવે છે.
TrendVidStream માં, અમે દરરોજ 40 મિલિયન ઇવેન્ટ્સ પ્રોસેસ કરીએ છીએ. અમે એક સરળ સ્ટેકનો ઉપયોગ કરીએ છીએ: PHP 8.4 અને Postgres.
સમસ્યા કાર્ડિનાલિટી (cardinality) ની છે. પ્રતિ સેકન્ડ યુનિક દર્શકોની ગણતરી કરવી મુશ્કેલ છે.
નાટિવ (Naive) રીત:
- એક રો (raw) ઇવેન્ટ્સ ટેબલનો ઉપયોગ કરો.
COUNT(DISTINCT viewer_hash)ચલાવો.- વિડિયો અને ટાઈમ બકેટ દ્વારા ગ્રુપ કરો.
આ પદ્ધતિ ઝડપથી નિષ્ફળ ગઈ. 90 દિવસના ડેટા માટે, તમારે 3.6 અબજ રોની જરૂર પડે છે. ક્વેરીઝમાં 9 સેકન્ડ લાગતી હતી. વળી, યુનિક કાઉન્ટ્સ 'રોલ અપ' (roll up) થઈ શકતા નથી. તમે "કલાક દીઠ યુનિક્સ" નો સરવાળો કરીને "દિવસ દીઠ યુનિક્સ" મેળવી શકતા નથી કારણ કે તે જ વ્યક્તિ બંનેમાં દેખાઈ શકે છે.
ઉકેલ: HyperLogLog (HLL).
HLL ડેટાસેટનો એક નાનો "સ્કેચ" (sketch) બનાવે છે. તે ખૂબ જ નાનો હોય છે, લગભગ 10 KB, પછી ભલે કરોડો લોકો વિડિયો જોતા હોય.
HLL હીટમેપ્સ માટે કેમ કામ કરે છે:
- નિશ્ચિત કદ: તે નાનું રહે છે.
- મર્જ કરી શકાય તેવું (Mergeable): તમે ગ્લોબલ કાઉન્ટ મેળવવા માટે બે સ્કેચનું યુનિયન કરી શકો છો. આનાથી રોલઅપની સમસ્યા ઉકેલાય છે.
અમારી અમલીકરણ પદ્ધતિ:
અમે postgresql-hll એક્સટેન્શનનો ઉપયોગ કરીએ છીએ. અમે બે ટેબલનો ઉપયોગ કરીએ છીએ.
- એક સ્ટેજિંગ ટેબલ: એક એપેન્ડ-ઓન્લી (append-only) ટેબલ જ્યાં PHP રો હાર્ટબીટ્સ લખે છે. રાઈટ્સ (writes) ઝડપી રાખવા માટે અમે અહીં ઇન્ડેક્સનો ઉપયોગ કરતા નથી.
- એક સ્કેચ ટેબલ: આ HLL ડેટા સ્ટોર કરે છે.
અમે સ્ટેજિંગમાંથી સ્કેચ ટેબલમાં ડેટા ખસેડવા માટે cron job નો ઉપયોગ કરીએ છીએ. અમે આ કમાન્ડનો ઉપયોગ કરીએ છીએ:
INSERT INTO video_heatmap (...)
SELECT ..., hll_add_agg(hll_hash_text(viewer_hash), 14, 5)
FROM beacon_staging
GROUP BY ...
ON CONFLICT (...)
DO UPDATE SET viewers = video_heatmap.viewers || EXCLUDED.viewers;
"||" ઓપરેટર નવા ડેટાને હાલના સ્કેચમાં મર્જ કરે છે.
પરિણામો:
- ક્વેરી સ્પીડ: અમારી હીટમેપ ક્વેરીઝમાં 15 થી 40 ms લાગે છે. જૂની પદ્ધતિમાં 9 સેકન્ડ લાગતી હતી.
- સ્ટોરેજ: અમારો 90-દિવસનો ડેટાસેટ 40 GB છે. જૂની પદ્ધતિમાં 1.2 TB જગ્યા લાગી હોત.
- ચોકસાઈ: અમે આશરે 0.6% થી 1.4% ભૂલ (error) જોઈએ છીએ. હીટમેપ માટે આ પર્ફેક્ટ છે.
શીખવા મળેલા પાઠ:
- ડેટાબેઝની અંદર હેશ (Hash) કરો. તમારા એપમાં હેશ ન કરો.
- તમારા અપડેટ્સને બેચમાં કરો. સ્કેચને એક સમયે એક રો કરીને અપડેટ ન કરો, નહીંતર તમે 'write hotspots' ઊભા કરશો.
- હેશ માટે ડેઈલી સોલ્ટ (daily salt) નો ઉપયોગ કરો. આ પ્રાઈવસીનું રક્ષણ કરે છે અને તમારા ડેઈલી સ્કેચને ક્લીન રાખે છે.
જો COUNT(DISTINCT) ને કારણે તમારું ડેશબોર્ડ ધીમું હોય, તો તમારે વિશાળ ડેટા વેરહાઉસની જરૂર નથી. તમારે HLL ની જરૂર છે.
