নিউজ ফিড ডিজাইন (Design a News Feed)
সমস্যাটি বোঝা (Understanding the Problem)
ইনস্টাগ্রাম, টুইটার বা ফেসবুক খুললে, আপনি যাদের ফলো করেন তাদের পোস্টের যে স্ক্রোলিং তালিকাটি দেখতে পান — সেটাই হলো নিউজ ফিড (news feed)। এটিকে দেখতে সহজ মনে হলেও ব্যাকগ্রাউন্ডে বা পর্দার আড়ালে এটি অন্যতম একটি চ্যালেঞ্জিং সিস্টেম, বিশেষ করে যখন এটিকে বিশাল স্কেলে (scale) ডিজাইন করতে হয়।
একবার ভেবে দেখুন: যখন ১০০ মিলিয়ন ফলোয়ার থাকা কোনো সেলিব্রিটি একটি ছবি পোস্ট করেন, তখন সেই ১০০ মিলিয়ন মানুষের ফিডে এটি খুব দ্রুত পৌঁছানো বা দেখানো প্রয়োজন। একই সময়ে, আরও হাজার হাজার মানুষ পোস্ট করছেন। আবার প্রতিটি ব্যবহারকারীর ফিড সম্পূর্ণ আলাদা — তাদের নিজস্ব ফলো করা মানুষদের কন্টেন্টের একটি পার্সোনালাইজড বা ব্যক্তিগতকৃত মিশ্রণ।
ফাংশনাল রিকোয়ারমেন্টস (Functional Requirements):
- ব্যবহারকারীরা পোস্ট তৈরি করতে পারবেন (টেক্সট, ছবি, ভিডিও)।
- ব্যবহারকারীরা তাদের ফলো করা মানুষদের পোস্টের একটি পার্সোনালাইজড ফিড দেখতে পাবেন।
- ফিডটি প্রাসঙ্গিকতা (relevance) বা সময়ের (time) ভিত্তিতে (অথবা দুটোর মিশ্রণে) সাজানো বা সর্ট করা থাকবে।
- প্যাজিনেশন (pagination) বা অসীম স্ক্রোল (infinite scroll) সাপোর্ট বা সমর্থন করবে।
- নতুন পোস্টগুলো প্রায় তাৎক্ষণিকভাবে (near-real-time) দেখা যাবে।
নন-ফাংশনাল রিকোয়ারমেন্টস (Non-Functional Requirements):
- লো ল্যাটেনসি (Low latency): ফিডটি < ২০০ মিলিসেকেন্ডের মধ্যে লোড হতে হবে।
- স্কেল (Scale): ৫০০ মিলিয়ন দৈনিক সক্রিয় ব্যবহারকারী বা DAU, যেখানে প্রতিটি ব্যবহারকারী গড়ে প্রায় ২০০ জনকে ফলো করেন।
- অ্যাভেইলেবিলিটি (Availability): ফিড সব সময়ই লোড হতে বাধ্য — সম্পূর্ণ ফাঁকা বা কিছুই না দেখানোর চেয়ে সামান্য পুরানো ফিড দেখানোও ভালো।
মূল চ্যালেঞ্জ: ফ্যান-আউট (The Core Challenge: Fan-Out)
আনিকা যখন কিছু পোস্ট করেন, তখন তার সব ফলোয়ারদের সেটি দেখতে পারতে হবে। সবার ফিডে সেই পোস্টটি পৌঁছে দেওয়ার এই প্রক্রিয়াটিকে ফ্যান-আউট (fan-out) বলা হয়। এর ফ্যান-আউটের দুটি বিপরীত পদ্ধতি রয়েছে এবং এগুলোর মধ্যে সঠিকটি বেছে নেওয়াটিই হলো মূল আর্কিটেকচারাল সিদ্ধান্ত।
ফ্যান-আউট অন রাইট বা পুশ মডেল (Fan-Out on Write / Push Model)
আনিকা যখনই পোস্ট করেন, সাথে সাথে তার সমস্ত ফলোয়ারের ফিড ক্যাশে (feed cache) আনিকার পোস্টটি পুশ করা হয়। এটি অনেকটা ভোরে সংবাদপত্র ডেলিভারি করার মতো — আপনি ঘুম থেকে ওঠার আগেই খবরের কাগজ আপনার দোরগোড়ায় পৌঁছে দেওয়া হয়।
- সুবিধা: ফিড রিড বা পড়া বিদ্যুতের মতো দ্রুত হয় — ডেটা আগে থেকেই প্রস্তুত করে ক্যাশে রাখা থাকে। শুধু ক্যাশ থেকে সেটি ফেচ (fetch) করতে হয়।
- অসুবিধা: রাইট করা অনেক ব্যয়বহুল এবং ধীরগতির। যদি আনিকার ১০ মিলিয়ন ফলোয়ার থাকে, তবে একটিমাত্র পোস্টের জন্য ১০ মিলিয়ন ক্যাশ রাইট করতে হবে। সেলিব্রিটিদের ক্ষেত্রে, এটি একটি বিশাল ফ্যান-আউট, যার জন্য বিপুল পরিমাণ সময় এবং রিসোর্স লাগে।
- যাদের জন্য ভালো: যাদের ফলোয়ার সংখ্যা মাঝারি বা কম (< ১০,০০০)।
ফ্যান-আউট অন রিড বা পুল মডেল (Fan-Out on Read / Pull Model)
রাফি যখন তার ফিড ওপেন করে, তখন সিস্টেমটি রাফি যাদের ফলো করে তাদের লেটেস্ট বা সর্বশেষ পোস্টগুলো ফেচ করে এবং তা তাৎক্ষণিকভাবে (on the fly) মার্জ বা মিশ্রিত করে ফিড তৈরি করে। এটি অনেকটা বুফেতে খেতে যাওয়ার মতো — ক্ষুধা লাগলে আপনি নিজেই নিজের খাবার প্লেটে গুছিয়ে নেন।
- সুবিধা: রাইট করা তাৎক্ষণিক হয় — পোস্টটি শুধু ডেটাবেসে সংরক্ষণ করলেই হয়। এখানে ব্যয়বহুল ফ্যান-আউটের ঝামেলা নেই।
- অসুবিধা: রিড করা বা ফিড দেখা ধীরগতির হয় — আপনাকে বাস্তব সময়ে শত শত মানুষের পোস্ট কোয়েরি করে আনতে হয় এবং সেগুলোকে একত্রে মার্জ করতে হয়।
- যাদের জন্য ভালো: সেলিব্রিটি বা ইনফ্লুয়েন্সারদের পোস্টের ক্ষেত্রে, যেখানে ফ্যান-আউট অন রাইট অনেক ব্যয়বহুল হয়ে যায়।
ফিড জেনারেশন: ফ্যান-আউট অন রাইট বনাম রিড
ফিড র্যাঙ্কিং এবং স্কোরিং (Feed Ranking and Scoring)
একটি সম্পূর্ণ কালানুক্রমিক (বা সময় অনুসারে) ফিড (যেখানে নতুন পোস্টটি প্রথমে দেখা যায়) খুবই সাধারণ, তবে বেশিরভাগ ক্ষেত্রেই এটি সেরা ইউজার এক্সপেরিয়েন্স প্রদান করে না। যদি আপনি গত ৮ ঘণ্টা ধরে আপনার ফিড চেক না করে থাকেন, তবে এমনটা হতে পারে যে সবচেয়ে আকর্ষণীয় পোস্টগুলো শত শত কম-প্রাসঙ্গিক পোস্টের নিচে চাপা পড়ে আছে।
আধুনিক ফিডগুলোতে র্যাঙ্কিং অ্যালগরিদম (ranking algorithms) ব্যবহার করা হয়, যা কিছু সিগন্যালের (signal) ওপর ভিত্তি করে প্রতিটি পোস্টকে স্কোর করে:
- সাম্প্রতিকতা (Recency): নতুন পোস্টগুলোর স্কোর বেশি হয়। ৫ মিনিট আগের একটি পোস্ট গতকালের যেকোনো পোস্টের চেয়ে র্যাঙ্কিংয়ে এগিয়ে থাকবে।
- এনগেজমেন্ট (Engagement): যেসব পোস্টে প্রচুর লাইক, কমেন্ট ও শেয়ার রয়েছে, সেগুলোর স্কোর বেশি হয় — এটি একটি সামাজিক প্রমাণ বা প্রমাণ-নির্ভর নির্দেশক যে পোস্টটি আসলেই আকর্ষণীয়।
- সম্পর্ক (Relationship): ঘনিষ্ঠ বন্ধুদের পোস্ট (যাদেরকে আপনি মেসেজ করেন, যাদের পোস্টে আপনি রিয়্যাক্ট করেন, বা যাদের প্রোফাইলে আপনি প্রায়শই ভিজিট করেন) আপনার পরিচিত সাধারণ বন্ধুদের চেয়ে ফিডে উচ্চতর স্থান পায়।
- কন্টেন্টের ধরন (Content type): আপনি যদি টেক্সটের চেয়ে ভিডিওতে বেশি এনগেজ বা রিয়্যাক্ট করেন, তবে ভিডিও পোস্টগুলো র্যাঙ্কিংয়ের ক্ষেত্রে বাড়তি সুবিধা বা বুস্ট পায়।
- বৈচিত্র্য (Diversity): একই ব্যক্তির পর পর ৫টি পোস্ট দেখানো থেকে এড়িয়ে চলা হয়। এর পরিবর্তে বিভিন্ন মানুষের বিষয়বস্তুর মিশ্রন করা হয়।
একটি সহজ সংকেত-নির্ভর স্কোরিং ফর্মুলা (formula) এরকম হতে পারে:
score = recency_weight × time_decay + engagement_weight × (likes + 2×comments + 3×shares) + relationship_weight × interaction_score
বাস্তবে ফেসবুক এবং টিকটকের মতো কোম্পানিগুলো জটিলো মেশিন লার্নিং (Machine Learning) মডেল ব্যবহার করে। প্রতিটি ব্যবহারকারী কী দেখতে চায় তা অনুমান করার জন্য এই মডেলগুলোতে শত শত নির্দেশক বা সিগন্যাল বিবেচনা করা হয়।
মিডিয়া হ্যান্ডলিং (Media Handling)
যেসব পোস্টে ছবি বা ভিডিও থাকে, সেগুলো শুধুমাত্র-টেক্সট পোস্টগুলোর তুলনায় অনেক বেশি জটিল হয়ে থাকে:
ছবি আপলোড (Image uploads):
- ক্লায়েন্ট একটি প্রাক-স্বাক্ষরিত বা প্রি-সাইন্ড URL (pre-signed URL) এর মাধ্যমে অবজেক্ট স্টোরে (যেমন- S3) ছবি আপলোড করে।
- একটি প্রসেসিং পাইপলাইন ছবির একাধিক রেজোলিউশনের (resolution) কপি তৈরি করে: থাম্বনেইল (১৫০px), মাঝারি (৬০০px), এবং অরিজিনাল বা ফুল (১২০০px)।
- সারা বিশ্বে দ্রুত ডেলিভারির জন্য ছবিগুলোকে একটি CDN এর মাধ্যমে পরিবেশন করা হয়।
- পোস্টের রেকর্ডে বা ডেটাবেস টেবিলে ছবির আসল ফাইল নয়, বরং এর URL সংরক্ষণ করা থাকে।
ভিডিও আপলোড (Video uploads):
- আসল বা র (raw) ভিডিওটি S3 তে আপলোড করা হয়।
- একটি ট্রান্সকোডিং পাইপলাইন (FFmpeg বা AWS MediaConvert এর মতো সার্ভিস ব্যবহার করে) বিভিন্ন কোয়ালিটির ফাইলের সংস্করণ তৈরি করে: ৩৬০p, ৭২০p, ১০৮০p।
- অ্যাডাপটিভ বিটরেট স্ট্রিমিং বা Adaptive bitrate streaming (HLS/DASH) ব্যবহারকারীর ইন্টারনেট স্পিড বা সংযোগের গতির ওপর ভিত্তি করে সঠিক কোয়ালিটির ভিডিও ডেলিভারি করে।
- ভিডিওগুলো সারা বিশ্বের CDN এজ সার্ভারগুলোতে ক্যাশ করে রাখা হয়।
মূল বিষয়: মিডিয়া প্রসেসিং একটি অ্যাসিঙ্ক্রোনাস (asynchronous) প্রক্রিয়া। পোস্টটি তৈরি হওয়ার সাথে সাথেই ব্যবহারকারীকে "প্রসেসিং" (processing) বা প্রক্রিয়াজাতকরণের স্ট্যাটাস দেখানো হয়, এবং মিডিয়া বা ছবি/ভিডিও কয়েক সেকেন্ড অথবা মিনিট পর ফিডে ভিজিবল বা দৃশ্যমান হয়। এই প্রক্রিয়াজাতকরণের পাইপলাইন সমন্বয় করতে রিয়েল-লাইফ সিস্টেমে একটি মেসেজ কিউ (message queue) ব্যবহার করা হয়।
কার্সরের সাহায্যে প্যাজিনেশন (Pagination with Cursor)
ব্যবহারকারীরা তাদের ফিড জুড়ে স্ক্রোল করতেই থাকেন (এন্ডলেস স্ক্রলিং)। আপনি কীভাবে এটিকে দক্ষতার সাথে প্যাজিনেট (paginate) করবেন?
অফসেট-ভিত্তিক (Offset-based - খারাপ): "আমাকে ১০০-১২০ নম্বর পোস্টগুলো দাও।" কিন্তু যদি আপনি প্রথম পৃষ্ঠাটি লোড করার পর এর মধ্যে নতুন ৫টি পোস্ট যোগ করা হয়, তবে কী হবে? আপনি তখন একই পোস্ট দু'বার দেখবেন, অথবা মাঝখান থেকে বেশ কয়েকটি পোস্ট মিস করে যাবেন। তাছাড়া, ৫০০ নম্বর পৃষ্ঠাটি লোড করতে চাইলে ডেটাবেসকে মাঝখানের ১০,০০০টি সারি ফেলে দিতে হয়, যা অত্যন্ত ধীরগতির বা স্লো।
কার্সর-ভিত্তিক (Cursor-based - ভালো): "আমাকে অমুক টাইমস্ট্যাম্প বা আইডির পর থেকে ২০টি পোস্ট দাও।" কার্সর হলো একটি অস্বচ্ছ টোকেন বা হিসেব সংরক্ষক (সাধারণত শেষ পোস্টের টাইমস্ট্যাম্প বা আইডি) যা সঠিকভাবে বলে দেয় যে আপনি আপনার স্ক্রলিং কোথায় ছেড়েছিলেন। নতুন কোনো পোস্ট এলে তা আপনার স্ক্রোল করা পজিশনকে ব্যাহত করে না।
ক্যাশের ক্ষেত্রে, রেডিজ-সর্টেড সেট বা Redis sorted sets এ (স্কোর/টাইমস্ট্যাম্প অনুযায়ী সাজানো) ফিডগুলো সংরক্ষণ করা হয়। কার্সর-ভিত্তিক প্যাজিনেশনের ক্ষেত্রে এটি একটি সাধারণ ZRANGEBYSCORE কোয়েরিতে রূপান্তরিত হয়, যা অনেক দ্রুত এবং সঠিক বা কনসিস্টেন্ট (consistent) হয়ে থাকে।
ক্যাশ স্ট্র্যাটেজি (Cache Strategy)
ক্যাশিং হলো ফিড পারফরম্যান্সের মেরুদণ্ড (backbone)। আসুন একটি মাল্টি-লেয়ার অ্যাপ্রোচ বা বহুমুখী ক্যাশিং স্ট্র্যাটেজি দেখে নেওয়া যাক:
- ফিড ক্যাশ (Feed cache/Redis): প্রতিটি ব্যবহারকারীর জন্য একটি আগে থেকে তৈরি করা (pre-computed) ফিড থাকে, যা একটি সর্টেড-সেট (sorted set) বা ক্রমে সাজানো সেট হিসেবে জমা রাখা হয়। এটি হলো ক্যাশিংয়ের মূল পাথ (primary read path) — ডেটাবেসের বদলে সরাসরি ক্যাশ থেকেই ফিড লোড হয়। সাধারণত একজনের জন্য সর্বোচ্চ ৫০০-৮০০টি আইটেম ক্যাশে রাখা হয়।
- পোস্ট ক্যাশ (Post cache): পৃথক পোস্টের ডেটা (পোস্টদাতা, কন্টেন্ট, মিডিয়া ইউআরএল, লাইকের সংখ্যা) আলাদাভাবে ক্যাশ করা হয়। যখন কোনো ফিডকে রেন্ডার (render) করা হয়, তখন এই ক্যাশ থেকে উক্ত পোস্টের বিস্তারিত তথ্য তুলে আনা হয়।
- সোশ্যাল-গ্রাফ ক্যাশ (Social graph cache): ফ্যান-আউট প্রক্রিয়ার (fan-out service) সুবিধার্থে কে কাকে ফলো করছে, সেটি এই ক্যাশ লেয়ারে জমা রাখা হয়।
- সিডিএন (CDN): আপনার সমস্ত মিডিয়া ফাইলসমূহ (যেমন ছবি এবং ভিডিও) CDN এজ সার্ভারগুলোর (edge servers) মাধ্যমে পরিবেশন করা হয়।
যেসব ব্যবহারকারী সম্প্রতি খুব একটা লগ-ইন করেননি, তাদের ফিড ক্যাশ সাধারণত খালি (evicted/অপসারিত) থাকে। যখন তারা পুনরায় অ্যাপ চালু করেন, তখন সিস্টেম তার ফলোয়িংয়ের লেটেস্ট পোস্টগুলো (recent posts based on followings) তুলে এনে সম্পূর্ণ নতুনভাবে তাদের ফিড প্রস্তুত করে (on-demand)। এটিকে "কোল্ড স্টার্ট (cold start)" বলা হয়, যা কিছুটা স্লো হলেও এটি কেবল প্রথমবারই ঘটে।
রিয়েল-টাইম আপডেট (Real-Time Updates)
যখন একটি নতুন পোস্ট প্রকাশ করা হয়, একজন সক্রিয় ব্যবহারকারীকে রিফ্রেশ না করেই তা দেখতে পারা উচিত। এর দুটি ভিন্ন প্রক্রিয়া বা অ্যাপ্রোচ রয়েছে:
পুল-টু-রিফ্রেশ (Pull-to-refresh): ব্যবহারকারী নতুন পোস্ট চেক করার জন্য ম্যানুয়ালি রিফ্রেশ করে বা পেজটি টেনে নিচে নামায়। এটি বেশ সহজ তবে পুরোপুরি রিয়েল-টাইম নয়। বেশিরভাগ সোশ্যাল অ্যাপ তাদের প্রধান ফিডের জন্য এটিই ব্যবহার করে।
সার্ভার-পুশ নোটিফিকেশন (Server-push notifications): একটি "নতুন পোস্ট পাওয়া গেছে" টাইপের নোটিফিকেশন (indicator) পুশ করতে ওয়েবসকেট (WebSockets) বা সার্ভার-সেন্ট ইভেন্টস (SSE) ব্যবহার করা হয়। তখন ক্লায়েন্ট বা ব্রাউজারে "৩টি নতুন পোস্ট" টাইপের একটি ব্যানার দেখানো হয়। এটিতে ট্যাপ করলে নতুন পোস্টগুলো ফেচ হয় এবং ইনসার্ট হয়। এর ফলে ব্যবহারকারীর বিরক্তি তৈরি হয় না, পাশাপাশি ফিডটিতে সবসময় নতুন কন্টেন্ট দেখতে পাওয়া যায়।
ফুল রিয়েল-টাইম ইনসার্শনের (স্ক্রোল করার সাথে সাথে পোস্টগুলোর লোড হওয়া) প্রক্রিয়াটি প্রধান ফিডের ক্ষেত্রে সাধারণত রিয়েল-টাইম ইভেন্ট বা চ্যাটের জন্য সংরক্ষিত থাকে — কারণ এটি স্ক্রলিংয়ের সময় আচমকা দৃশ্যমান হলে ইউজার এক্সপেরিয়েন্সকে ব্যাহত করতে পারে।
Key Metrics
ছোট কুইজ
পড়া চালিয়ে যান