ChatGPT এর ১০০ কোটি user, data থাকে কোথায়?
OpenAI এর storage system Habitat প্রতি সেকেন্ডে ৭ কোটি request সামলায়, ৫০০ PB এর বেশি data নিয়ে। শুরুটা ছিল একটা সাধারণ Python library। সেখান থেকে শেখার মতো পাঁচটা engineering সিদ্ধান্ত।
· ৯ মিনিটের পড়া
শুরুর আগে একটা গল্প
আমরা অনেকেই ভাবি database মানে একটা Postgres, সাথে কিছু query, ব্যস। ছোট project এ কথাটা ঠিকও। কিন্তু ভাবো ChatGPT এর কথা। প্রায় ১০০ কোটি মানুষ, প্রত্যেকের chat history, settings, file, memory। প্রতিটা message পাঠানোর সাথে সাথে পেছনে কয়েকশো database call।
OpenAI এর engineering blog এ ওদের storage system এর গল্প পড়ে মনে হলো, scale এ গেলে database এর গল্পটা পুরো আলাদা হয়ে যায়। সেই গল্পটাই এখানে, সাথে প্রতিটা সিদ্ধান্তের পেছনের "কেন"।
| বিষয় | সংখ্যা |
|---|---|
| System এর নাম | Habitat |
| প্রতি সেকেন্ডে request | ৭ কোটি (70 million) |
| Data | ৫০০ PB এর বেশি |
| শুরু হয়েছিল | একটা সাধারণ Python library হিসেবে |
শুরু: সবার code এ একটা library
প্রথম দিকে Habitat কোনো আলাদা system ছিল না। এটা ছিল একটা Python library। প্রতিটা team এই library নিজের service এর code এ import করে database এর সাথে কথা বলতো। Connection, retry, কোন data কোন server এ, সব logic ছিল library এর ভেতরে।
ছোট scale এ এটা চমৎকার কাজ করে:
- আলাদা কোনো server চালাতে হয় না, রক্ষণাবেক্ষণ নেই।
- মাঝখানে কোনো network hop নেই, তাই দ্রুত।
- শুরু করা সহজ:
pip install, তারপর ব্যবহার।
সমস্যা দেখা দেয় যেদিন library তে কিছু বদলাতে হয়।
যে outage আটকাতে গিয়ে outage হলো
একবার একটা বড় সমস্যা আটকাতে library তে নতুন logic যোগ করা হলো। এখন সেই নতুন version ডজনখানেক service এ পৌঁছাতে হবে। প্রতিটা team কে বলতে হবে version update করো, test করো, deploy করো। এতে কয়েক দিন লেগে গেল।
তারপর যা হলো, সেটাই আসল শিক্ষা: একটা team পুরো আলাদা একটা কারণে নিজের service rollback করলো। সেই rollback এর সাথে library ও ফিরে গেল পুরোনো, buggy version এ। আর যে outage আটকানোর জন্য এত খাটুনি, ঠিক সেই outage টাই হয়ে গেল।
সমাধান: library থেকে service
তাই ওরা library টাকে একটা আলাদা service বানালো। এখন product গুলো আর নিজের ভেতরে storage এর logic রাখে না, তারা শুধু Habitat service কে request পাঠায়। কোনো bug fix বা নতুন নিয়ম আনতে হলে এক জায়গায় deploy করলেই সব product সাথে সাথে পায়। কোনো team rollback করলেও storage এর logic আর পিছিয়ে যায় না।
| Library | Service | |
|---|---|---|
| Fix পৌঁছাতে | প্রতিটা team কে deploy করতে হয়, দিন লাগে | একবার deploy, মিনিট লাগে |
| Version | প্রতিটা service এ আলাদা হতে পারে | সবার জন্য একটাই |
| Rollback এর প্রভাব | পুরোনো bug ফিরে আসতে পারে | Storage এর logic স্বাধীন |
| খরচ | কোনো network hop নেই | প্রতি call এ একটা network hop, চালানোর জন্য আলাদা server |
জেনে-বুঝে Python: "strategic tech debt"
এই পুরো গল্পে আমার কাছে সবচেয়ে মজার লেগেছে এই সিদ্ধান্তটা। ওরা জানতো Python এ service বানালে সেটা ধীর হবে। তবুও Python এই বানালো।
কেন? কারণ তখনকার priority ছিল team গুলোকে unblock করা, performance না। পুরোনো library ছিল Python এ। একই ভাষায় service বানালে পুরোনো code বেশিরভাগ ব্যবহার করা যায়, team সবাই ভাষাটা চেনে, আর সবচেয়ে দ্রুত আসল সমস্যাটা মেটে। ধীরগতির দাম পরে দেওয়া যাবে।
ওরা নিজেরাই এর নাম দিয়েছে strategic tech debt।
কেউ নিখুঁত system দিয়ে শুরু করে না। আসল দক্ষতা হলো জানা কোথায় compromise করছো, আর কেন। আর এই ধার ওরা পরে শোধও করেছে, Rust rewrite এর অংশে সেই গল্প।
Average না, সবচেয়ে ধীর call টা
ChatGPT তে তুমি একটা message পাঠালে পেছনে একটা না, শত শত database call হয়। তোমার history, settings, memory, file, permission, সব আলাদা আলাদা জায়গা থেকে আসে। আর তোমার উত্তর তৈরি হতে পারে কেবল তখনই, যখন সবগুলো call ফিরে আসে।
তার মানে তোমার অপেক্ষার সময় ঠিক করে দেয় সবচেয়ে ধীর call টা, গড়টা না।
p50 আর p99 মানে কী
ধরো ১০০টা call এর সময় ছোট থেকে বড় সাজালে:
- p50 (median): মাঝখানেরটা। অর্ধেক call এর চেয়ে দ্রুত।
- p99: ৯৯তমটা। মানে ১০০টার মধ্যে মাত্র ১টা এর চেয়ে ধীর।
শুনে মনে হয় "১% ধীর call, তাতে কী?" এবার একটু অংক করি। ধরো প্রতিটা call এর ধীর হওয়ার সম্ভাবনা ১%। একটা user request যদি অনেকগুলো call করে, তাহলে অন্তত একটা ধীর call পড়ার সম্ভাবনা:
| একটা request এ call | অন্তত একটা ধীর call এর সম্ভাবনা |
|---|---|
| ১টা | ১% |
| ১০টা | প্রায় ১০% |
| ১০০টা | প্রায় ৬৩% |
| ৩০০টা | প্রায় ৯৫% |
অর্থাৎ যে system এ একটা request শত শত call করে, সেখানে "বিরল" ধীর call টাই প্রায় প্রত্যেক user অনুভব করে। এজন্যই বড় system এ p50 দেখে খুশি হওয়ার কিছু নেই। p99 (আর আরো বড় scale এ p99.9) টাই আসল মাপকাঠি।
ইচ্ছা করে SQL বাদ
Habitat এ SQL নেই। আছে শুধু একটা সহজ NoSQL API: মোটামুটি "এই key এর data দাও", "এই key তে data রাখো" ধরনের কাজ।
শুনে অবাক লাগতে পারে। SQL তো কত শক্তিশালী! Join, filter, aggregate, সব এক লাইনে। সমস্যাটা ঠিক সেখানেই। SQL এ অনেক ভারী query লেখা খুব সহজ। একটা ভুল join বা index ছাড়া একটা filter হাজার কোটি row ঘাঁটতে পারে। আর shared database এ একটা খারাপ query CPU, memory আর disk দখল করে নিলে বাকি সবার query আটকে যায়। একজনের ভুলে পুরো product নেমে যায়।
ওরা ইচ্ছা করেই ক্ষমতা কমিয়েছে, যাতে system predictable থাকে। সহজ API তে প্রতিটা request এর খরচ মোটামুটি জানা: একটা key, একটা জায়গা, একটা উত্তর। কেউ ভুল করেও পুরো system নামাতে পারে না।
ধার শোধ: ২ জন engineer, Codex আর Rust
Python দিয়ে যে ধার নিয়েছিল, এবার সেটা শোধের পালা। Python এ লেখা service টা ওরা পুরোটা Rust এ নতুন করে লিখেছে। মাত্র ২ জন engineer, সাথে OpenAI এর নিজের coding agent Codex। ফলাফল:
- ৬ গুণ কম CPU
- ১৫ গুণ কম memory
এখানে দুটো জিনিস লক্ষ্য করার মতো:
- API বদলায়নি। যেহেতু Habitat আগেই একটা আলাদা service আর তার API সহজ, তাই ভেতরের ভাষা পুরো বদলে ফেললেও product গুলোর কিছু জানার দরকার পড়েনি। Library থেকে service বানানোর সেই পুরোনো সিদ্ধান্তই এই rewrite কে সম্ভব করেছে।
- সঠিক সময়ে শোধ। প্রথম দিনেই Rust এ লিখতে গেলে team গুলো মাসের পর মাস আটকে থাকতো। আগে সমস্যা মিটিয়েছে, system কী করে সেটা পুরোপুরি বুঝেছে, তারপর গতি বাড়িয়েছে।
তোমার কাজে কী নেবে
তুমি হয়তো আজ প্রতি সেকেন্ডে ৭ কোটি request সামলাও না। কিন্তু এই সিদ্ধান্তগুলো ছোট system এও খাটে:
| শিক্ষা | ছোট project এ কীভাবে |
|---|---|
| Shared logic অনেক জায়গায় ছড়ালে service বানাও | একই auth বা payment code পাঁচটা app এ copy না করে একটা ছোট service বা API দাও |
| জেনে-বুঝে tech debt নাও | "এখন সহজ পথে, পরে optimize" ঠিক আছে, কিন্তু সেটা লিখে রাখো আর শোধের সময় ঠিক করো |
| Average না, p99 দেখো | Monitoring এ p95/p99 যোগ করো, সবচেয়ে ধীর endpoint গুলো খোঁজো |
| ক্ষমতা কমিয়ে security | Public API তে যেকোনো filter বা যেকোনো query চালাতে দিও না; সীমা, pagination আর timeout রাখো |
| আগে কাজ করাও, তারপর দ্রুত করো | পরিষ্কার API রাখলে পরে ভেতরটা বদলানো সহজ |
লেখাটা কাজে লাগলো?
Vote একবারই দেওয়া যায়, পরে বদলানো যায় না।