Building Video Heatmaps With HyperLogLog In PostgresQ

तुम्हाला एडिटर्सना प्रेक्षक व्हिडिओ पाहणे नक्की कुठे थांबवतात हे दाखवायचे आहे.

यासाठी तुम्हाला हीटमॅपची गरज आहे. हा हीटमॅप व्हिडिओच्या प्रत्येक सेकंदासाठी युनिक (unique) प्रेक्षकांची संख्या दर्शवतो.

TrendVidStream मध्ये, आम्ही दररोज ४ कोटी (40 million) इव्हेंट्स प्रोसेस करतो. आम्ही एक साधे स्टॅक वापरतो: PHP 8.4 आणि Postgres.

समस्या 'कार्डिनॅलिटी'ची (cardinality) आहे. प्रति सेकंद युनिक प्रेक्षक मोजणे कठीण आहे.

साधी पद्धत (The naive way):

  • रॉ इव्हेंट्स टेबल वापरा.
  • COUNT(DISTINCT viewer_hash) चालवा.
  • व्हिडिओ आणि टाइम बकेटनुसार ग्रुप करा.

हे लवकरच अपयशी ठरले. ९० दिवसांच्या डेटासाठी, तुम्हाला ३.६ अब्ज (3.6 billion) रो (rows) लागतील. क्वेरीजना ९ सेकंद लागत होते. तसेच, युनिक काउंट्स 'रोल अप' (roll up) होत नाहीत. तुम्ही "तासाला युनिक प्रेक्षक" यांची बेरीज करून "दिवसाला युनिक प्रेक्षक" मिळवू शकत नाही, कारण तीच व्यक्ती दोन्हीमध्ये असू शकते.

उपाय: HyperLogLog (HLL).

HLL डेटासेटचा एक छोटा "स्केच" (sketch) तयार करते. कितीही लाखो लोक पाहत असले तरी, तो फक्त १० KB च्या आसपास असतो.

HLL हीटमॅप्ससाठी का उपयुक्त आहे:

  • निश्चित आकार (Fixed size): तो लहान राहतो.
  • मर्ज करण्यायोग्य (Mergeable): तुम्ही ग्लोबल काउंट मिळवण्यासाठी दोन स्केचेसचे युनियन (union) करू शकता. यामुळे रोलअपची समस्या सुटते.

आमची अंमलबजावणी (Our Implementation):

आम्ही postgresql-hll एक्सटेंशन वापरतो. आम्ही दोन टेबल्स वापरतो.

  1. एक स्टेजिंग टेबल: एक 'अँपेंड-ओन्ली' (append-only) टेबल जिथे PHP रॉ हार्टबीट्स (raw heartbeats) लिहितो. लिहिण्याची प्रक्रिया वेगवान ठेवण्यासाठी आम्ही येथे इंडेक्स वापरत नाही.
  2. एक स्केच टेबल: यामध्ये 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;

"||" ऑपरेटर नवीन डेटा अस्तित्वात असलेल्या स्केचमध्ये मर्ज करतो.

निकाल (The Results):

  • क्वेरी स्पीड: आमच्या हीटमॅप क्वेरीजना १५ ते ४० ms लागतात. जुन्या पद्धतीला ९ सेकंद लागायचे.
  • स्टोरेज: आमचा ९० दिवसांचा डेटासेट ४० GB आहे. जुन्या पद्धतीला १.२ TB लागला असता.
  • अचूकता: आम्हाला सुमारे ०.६% ते १.४% त्रुटी (error) आढळते. हीटमॅपसाठी हे अगदी योग्य आहे.

शिकलेले धडे (Lessons learned):

  • डेटाबेसमध्ये हॅश (Hash) करा. तुमच्या ॲपमध्ये हॅश करू नका.
  • अपडेट्स बॅचमध्ये करा. स्केचेस एका वेळी एक रो अपडेट करू नका, अन्यथा 'राईट हॉटस्पॉट्स' (write hotspots) तयार होतील.
  • हॅशसाठी दररोज 'सॉल्ट' (salt) वापरा. यामुळे गोपनीयता जपली जाते आणि तुमचे दैनंदिन स्केचेस स्वच्छ राहतात.

जर COUNT(DISTINCT) मुळे तुमचे डॅशबोर्ड स्लो होत असेल, तर तुम्हाला मोठ्या डेटा वेअरहाऊसची गरज नाही. तुम्हाला HLL ची गरज आहे.

Source: https://dev.to/ahmet_gedik778845/building-per-second-video-heatmap-analytics-with-hyperloglog-in-postgres-2p22