Protobuf দিয়ে কম্প্যাক্ট ভিডিও মেটাডেটা
আমাদের ইনজেস্ট ওয়ার্কার (ingest worker) প্রতি দুই ঘণ্টা অন্তর হাজার হাজার ট্রেন্ডিং ভিডিও সংগ্রহ করে। আমরা এই ডেটা তিনটি সার্ভিসে পাঠাই: একটি র্যাঙ্কিং সার্ভিস, একটি ক্যাশ ওয়ার্মার (cache warmer), এবং একটি অ্যানালিটিক্স জব।
দীর্ঘ সময় ধরে, আমরা এই ডেটা আদান-প্রদানের জন্য JSON ব্যবহার করেছি। এটি ততক্ষণ পর্যন্ত কাজ করেছিল যতক্ষণ না এটি ব্যর্থ হতে শুরু করে।
JSON-এ একটি ভিডিও রেকর্ডের সাইজ ছিল ২.৪ KB। ৪০,০০০টি রেকর্ড তিনটি ভিন্ন সার্ভিসে পাঠানোর অর্থ হলো প্রতি দুই ঘণ্টা অন্তর ২৮০ MB অতিরিক্ত বা অপ্রয়োজনীয় টেক্সট পাঠানো। এটি ব্যান্ডউইথ অপচয় করছিল এবং আমাদের PHP ওয়ার্কারগুলোর গতি কমিয়ে দিচ্ছিল।
আমরা Protocol Buffers (Protobuf)-এ চলে এসেছি। কেন এবং কীভাবে এটি আমাদের সিস্টেম পরিবর্তন করেছে তা নিচে দেওয়া হলো।
JSON-এর তিনটি প্রধান সমস্যা:
- সাইজ: JSON প্রতিটি রেকর্ডে ফিল্ডের নাম বারবার ব্যবহার করে। "viral_score_24h"-এর মতো একটি ফিল্ডের নাম মাত্র একটি ৮-বাইটের সংখ্যা বহন করার জন্য ১৫ বাইট খরচ করে।
- পার্স করার খরচ (Parse Cost): কোনো সার্ভিসের যদি মাত্র দুটি ফিল্ডের প্রয়োজন হয়, তবুও PHP-কে পুরো JSON ব্লবটি পার্স করতে হয়।
- স্কিমা ড্রিফট (Schema Drift): JSON-এর কোনো চুক্তি (contract) নেই। যদি একটি সার্ভিস কোনো ফিল্ড পরিবর্তন করে, তবে অন্য সার্ভিসগুলো রানটাইমে কোনো সতর্কতা ছাড়াই অকেজো হয়ে পড়ে।
Protobuf কীভাবে এটি সমাধান করেছে:
Protobuf নামের পরিবর্তে ফিল্ড নম্বর ব্যবহার করে। এটি একটি একক সত্যের উৎস (single source of truth) হিসেবে .proto ফাইল ব্যবহার করে। এই ফাইলটি PHP, Python এবং Go-এর জন্য কোড তৈরি করে। আপনি যদি স্কিমা পরিবর্তন করেন, তবে কোডটি কম্পাইল হতে ব্যর্থ হবে। এটি রানটাইম বাগগুলোকে কম্পাইল-টাইম এরর-এ রূপান্তরিত করে।
ফলাফল:
আমরা এক সপ্তাহ ধরে এই পরিবর্তনগুলো পরিমাপ করেছি:
- পেলোড সাইজ: ২.৪ KB থেকে কমে ৭২০ বাইট হয়েছে (৭০% হ্রাস)।
- PHP এনকোড করার সময়: ৩১০ ms থেকে কমে ৯৫ ms হয়েছে।
- Go ডিকোড করার সময়: ১৪০ ms থেকে কমে ৩৮ ms হয়েছে।
- ব্যান্ডউইথ: প্রতি সাইকেলে ২৮০ MB থেকে কমে ৮৪ MB হয়েছে।
কখন Protobuf ব্যবহার করবেন:
এটি সবকিছুর জন্য ব্যবহার করবেন না। যদি আপনার পেলোড ছোট হয় বা আপনি যদি মানুষের সহজে পড়ার উপযোগী ডেটা চান, তবে JSON-ই ব্যবহার করুন। উচ্চ-ভলিউম ইন্টারনাল ট্রাফিকের ক্ষেত্রে Protobuf ব্যবহার করুন যেখানে গতি এবং কঠোর চুক্তি (strict contracts) সবচেয়ে বেশি গুরুত্বপূর্ণ।
আমাদের পাবলিক API এখনও JSON ব্যবহার করে। আমাদের ইন্টারনাল সার্ভিসগুলো Protobuf ব্যবহার করে।