মূল কনটেন্টে যান
OpenAI

১১ সেপ্টেম্বর, ২০২৬

ইঞ্জিনিয়ারিং

এক বিলিয়নেরও বেশি ChatGPT ব্যবহারকারীর সেবায় অনলাইন স্টোরেজের দ্রুত স্কেলিং

অভূতপূর্ব প্রবৃদ্ধি মোকাবিলায় আমরা যেভাবে Python-এ আমাদের অ্যাপ্লিকেশনের স্টোরেজ প্ল্যাটফর্ম Habitat-কে উপযোগী করে তুলেছিলাম.

জন লি, চাওমিন ইয়ু এবং বেন রেইস, মেম্বার্স অব টেকনিক্যাল স্টাফ

লোডিং…

কেউ লগইন করুক, তার Codex সেটিংস পরীক্ষা করুক কিংবা ChatGPT‑এ নতুন কোনো কথোপকথন শুরু করুক, OpenAI-এর প্রতিটি পণ্যই ডেটার দ্রুত ও নির্ভরযোগ্য অ্যাক্সেসের ওপর নির্ভরশীল. কোনো পণ্য প্রতিক্রিয়া দেখানোর আগে এই ধরনের প্রতিটি ক্রিয়ার জন্য আলাদা আলাদা অনেকগুলো ডেটা অনুসন্ধানের প্রয়োজন হতে পারে. এই অনুরোধগুলো যদি ধীরগতির হয়, তবে পণ্যটিও মন্থর মনে হয়. আর এই অনুরোধগুলো ব্যর্থ হলে পণ্যটি পুরোপুরি অকেজো হয়ে পড়ে.

Habitat হলো এমন একটি অনলাইন স্টোরেজ প্ল্যাটফর্ম যা আমরা তৈরি করেছি যাতে OpenAI-এর পণ্যগুলো তাদের প্রয়োজনীয় তথ্য দ্রুত ও নির্ভরযোগ্যভাবে অ্যাক্সেস করতে পারে. Habitat এখন প্রতি সেকেন্ডে 70 মিলিয়নেরও বেশি অনুরোধ পরিচালনা করে এবং প্রায় 40টি ভৌগোলিক অঞ্চলজুড়ে প্রতি সপ্তাহে এক বিলিয়নেরও বেশি মানুষের ব্যবহৃত পণ্যগুলোকে সচল রাখে. 2023 সালের DevDay-তে GPTs চালুর সময় Habitat-এর প্রথম যাত্রা শুরু হয়েছিল একটি একক ডেটাবেসের সাথে যুক্ত সাধারণ পাইথন ক্লায়েন্ট-সাইড লাইব্রেরি হিসেবে. আজ এটি একটি জটিল ডিস্ট্রিবিউটেড সিস্টেম যা 500 পেটাবাইটের বেশি ডেটা প্রক্রিয়াকরণ করে.

চিত্র 01 · Habitat কী?

অনলাইন স্টোরেজ প্ল্যাটফর্ম

OpenAI-এর পণ্যগুলো যাতে প্রয়োজনীয় তথ্য দ্রুত ও নির্ভরযোগ্যভাবে অ্যাক্সেস করতে পারে, সেজন্য আমরা যে অনলাইন স্টোরেজ প্ল্যাটফর্মটি তৈরি করেছি তা-ই হলো Habitat.

  • অনুরোধ
  • রেসপন্স
  • পরিবর্তন (CDC)

Client

অনলাইন স্টোরেজ প্ল্যাটফর্ম

স্টোরেজ রিসোর্স

  • ChatGPT
  • API
  • Codex
  • অভ্যন্তরীণ সার্ভিসসমূহ
  • আরও অনেক কিছু

Habitat

  • ক্যাশিংক্যাশ
  • ACL নীতিমালাঅনুমোদন
  • প্লেসমেন্ট ও ডাটা রেসিডেন্সিডাটা রেসিডেন্সি
  • এনক্রিপশনডাটা সুরক্ষা
  • আইসোলেশনমাল্টি-টেন্যান্সি
  • রেট লিমিটিংরিকোয়েস্ট শেপিং
  • রাউটিংস্কিমা লুকআপ · ডাটা রেসিডেন্সি
  • Azure Cosmos DBঅনলাইন স্টোরেজ
  • Nanobaseঅনলাইন স্টোরেজ
  • Valkeyক্যাশ
  • Blob স্টোরেজস্টোরেজ রিসোর্স
CDC সার্ভিসসমূহচেঞ্জ ডেটা ক্যাপচার
  • Databricks
  • Rockset
  • Kafka
  • আরও অনেক কিছু

এই বিপুল পরিসরে অবকাঠামো নির্মাণ ও পরিচালনা করা একেবারেই সহজ কাজ নয়, তবে তা অসম্ভব কোনো চ্যালেঞ্জও ছিল না. আমাদের অবস্থাকে অনন্য করে তুলেছিল সেই অভাবনীয় গতি, যার মাধ্যমে বিপুল গ্রাহক বৃদ্ধি এবং পণ্যের চাহিদা মেটানোর পাশাপাশি একই সঙ্গে একটি পরিপক্ব প্ল্যাটফর্ম গড়ে তোলার জন্য আমাদের স্কেল করতে হয়েছিল. সাধারণত সিস্টেম ইঞ্জিনিয়াররা 10x স্কেল মাথায় রেখে পরিকাঠামো তৈরি করেন এবং আশা করেন তা পরবর্তী 10x-এর প্রস্তুতি নেওয়ার সময় পর্যন্ত কয়েক বছর টিকে থাকবে. কিন্তু আমাদের ক্ষেত্রে বিগত তিন বছর ধরে বছরওয়ারি প্রবৃদ্ধি ছিল 10x-এরও বেশি. ফলে Habitat তৈরি ও পরিচালনা করা ছিল মূলত কৌশলগত সিদ্ধান্ত ও সময়োপযোগী পদক্ষেপের একটি ধারাবাহিক প্রক্রিয়া: মৌলিক পরিকাঠামোয় বিনিয়োগের সুযোগ নিশ্চিত করতে স্টোরেজ এবং কম্পিউট ক্ষমতার সংকট সামলানোর পাশাপাশি বর্তমান স্ট্যাক থেকে সর্বোচ্চ সুফল পাওয়ার জন্য প্রতিটি উপাদানকে সর্বনিম্ন স্তরে গিয়ে নিখুঁতভাবে অনুধাবন করা.

  • 70M+

    প্রতি সেকেন্ডে অনুরোধ

  • 1B+

    প্রতি সপ্তাহে মানুষ

  • 500 PB+

    ডাটা

OpenAI যত বড় হয়েছে, Habitat-কেও সেই তালে তাল মিলিয়ে বড় হতে হয়েছে: প্রথমে অত্যন্ত স্পর্শকাতর ট্রাফিকের জন্য যথেষ্ট নির্ভরযোগ্য হওয়া, তারপর বৈশ্বিক ব্যবহারকারীদের জন্য কাঙ্ক্ষিত গতি অর্জন করা এবং পরিশেষে মহাবিপুল স্কেলে অত্যন্ত দক্ষতার সাথে পরিচালিত হওয়া. অনলাইন স্টোরেজের স্কেলিং সম্পর্কিত দুই পর্বের ধারাবাহিক ব্লগের এটি প্রথম কিস্তি. এই লেখায় আমরা তুলে ধরব কীভাবে Habitat ধাপে ধাপে বিকশিত হয়েছে, কেন আমরা এটিকে লাইব্রেরি থেকে সার্ভিসে রূপান্তর করেছি এবং কীভাবে একটি অপ্রচলিত সার্ভিং স্ট্যাকের ভাষায়—Python-এ—লেখা একটি সার্ভিসকে একটি নির্ভরযোগ্য স্টোরেজ প্ল্যাটফর্ম স্তরে সম্প্রসারিত করেছি.

পরবর্তী লেখায় আমরা সবিস্তারে তুলে ধরব কীভাবে আমরা ব্যাপক স্কেলেও মাল্টি-টেন্যান্সির নির্ভরযোগ্যতা নিশ্চিত করেছি, রিড পারফরম্যান্স অপ্টিমাইজ করার ক্ষেত্রে আমাদের বহুস্তরীয় কৌশল কী ছিল এবং নজিরবিহীন চাহিদা নির্ভরযোগ্যভাবে সামলাতে Azure Cosmos DB-এর সাথে আমাদের অংশীদারিত্ব কীভাবে আরও বড় করেছি.

Habitat কী?

Habitat-এর সূচনা হয়েছিল একটি সহজ ভাবনা থেকে: প্রোডাক্ট ইঞ্জিনিয়ারদের ডেটাবেস ব্যবস্থাপনা নিয়ে অযথা ভাবতে হবে না. 2023 সালের DevDay-তে ChatGPT‑এর মূল সার্ভারের সাথে সংযুক্ত একটি ছোট Python লাইব্রেরি হিসেবে Habitat-এর প্রথম আত্মপ্রকাশ ঘটে, যা GPTs পরিচালনায় ভূমিকা রেখেছিল. এটি মূলত অল্প কিছু অপারেশনে সহায়তা করত, যা নেপথ্যে Azure Cosmos DB-র ডেটাবেস অ্যাপ্লিকেশনের সাথে যুক্ত ছিল.

লাইব্রেরিটির কাজ ছিল প্রোডাক্ট টিমগুলোকে ভেতরের খুঁটিনাটি না জেনেও সহজে ডেটা সংরক্ষণ ও পুনরুদ্ধারের সুবিধা করে দেওয়া. Habitat বাকি সব প্রয়োজনীয় কাজ সামলে নিত: কী ধরনের ডেটা নিয়ে কাজ হচ্ছে, তা কোথা থেকে আসবে (বা কোথায় যাবে), সেই অনুরোধের অনুমোদন আছে কি না এবং এ জাতীয় অন্যান্য বিষয়.

প্রোডাক্ট ইঞ্জিনিয়ারদের স্কিমা লুকআপ, রাউটিং, অথোরাইজেশন, এনক্রিপশন, সিরিয়ালাইজেশন, রিকোয়েস্ট শেপিং কিংবা কানেকশন পুলিং নিয়ে ভাবার কোনো প্রয়োজন ছিল না. ডেটা ঠিক কোথা থেকে আসছে, Azure Cosmos DB, ক্যাশ নাকি অন্য কোনো স্টোরেজ থেকে, তা নিয়েও তাদের মাথা ঘামাতে হতো না.

চিত্র 02 · Habitat সার্ভিস

Habitat-এর অনুরোধ প্রবাহের সহজ চিত্র

স্টোরেজ লজিককে একটি স্বতন্ত্র সার্ভিসে বিভক্ত করে আমরা অ্যাপ্লিকেশন মোতায়েন, পর্যবেক্ষণ ও প্ল্যাটফর্ম উন্নয়নের একটি একক নিয়ন্ত্রণ কেন্দ্র প্রতিষ্ঠা করেছি.

  • অনুরোধ
  • রেসপন্স

ক্লায়েন্ট

OpenAI

Azure Cosmos DB

Habitat ক্লায়েন্ট SDK
envoy
  • habitat-serviceপ্রক্রিয়া 1
  • habitat-serviceপ্রক্রিয়া 2
  • habitat-serviceপ্রক্রিয়া 3
habitat-envoy
  • habitat-cosmos-db-us0
  • habitat-cosmos-db-us1
  • habitat-cosmos-db-eu0

এই Python লাইব্রেরিটি অত্যন্ত সফল হয়েছিল এবং নিজস্ব তত্ত্বাবধানে Postgres ও Azure Cosmos DB ব্যবহারের ওপর কোনো কেন্দ্রীয় বিধিনিষেধ না থাকা সত্ত্বেও OpenAI-এর প্রোডাক্ট ইঞ্জিনিয়ারদের মধ্যে Habitat দ্রুত গ্রহণযোগ্যতা অর্জন করে নেয়.

প্রোডাক্টের প্রয়োজনীয়তা বাড়ার সাথে সাথে ক্লায়েন্ট-সাইড ক্যাশিং, কম্প্রেশন কিংবা এনক্রিপশনের মতো সুবিধাগুলো এই যৌথ লাইব্রেরিতে অন্তর্ভুক্ত করা প্রোডাক্ট ডেভেলপারদের জন্য খুবই সহজ হয়ে উঠেছিল.

একাধিক জটিল পণ্যকে আরও ভালোভাবে সহায়তা দিতে একটি সার্ভিস তৈরি করা

2025 সালের মাঝামাঝি এসে ক্লায়েন্ট-সাইড রূপায়ন হিসেবে Habitat তার চূড়ান্ত সীমাবদ্ধতায় পৌঁছে যায়. Habitat স্তরটি আরও জটিল হয়ে ওঠায় এবং OpenAI-এর মোট সার্ভিসের সংখ্যা ক্রমাগত বৃদ্ধি পাওয়ায় ব্যাকওয়ার্ড-কমপ্যাটিবল প্রোটোকল পরিবর্তন করা অসম্ভব হয়ে পড়েছিল.

উদাহরণস্বরূপ, একবার আমরা বিভিন্ন অঞ্চলে বিস্তৃত Azure Cosmos DB অ্যাকাউন্টের একটি সেটে মাইগ্রেট করে আমাদের সবচেয়ে গুরুত্বপূর্ণ ডেটাসেটগুলোর জন্য যেকোনো একক অঞ্চলের সিস্টেম বিপর্যয়ের প্রভাব কমাতে চেয়েছিলাম. এই পরিবর্তনটি করতে হলে ক্লায়েন্টে বাড়তি রাউটিং লজিক যোগ করতে হতো, যা সাময়িকভাবে একটি ফিচার ফ্ল্যাগের আড়ালে নিষ্ক্রিয় রাখা হয়; এরপর সমস্ত ক্লায়েন্টে তা পৌঁছে গেছে কি না নিশ্চিত করে ফিচার ফ্ল্যাগটি চালু করতে হতো.

কয়েক ডজন সার্ভিস জুড়ে সমন্বিতভাবে এটি মোতায়েন করতে এবং প্রতিটি দলের সাথে আলাদাভাবে কাজ করতে বেশ কয়েক দিন সময় লেগেছিল. এটি সক্রিয় করার আগে আমরা বুঝলাম যে শার্ডিং লজিক সঠিক কি না তা নিশ্চিত করতে আমাদের কিছুটা শ্যাডোয়িং যুক্ত করা প্রয়োজন. সেটি মোতায়েন করতেও আরও দুই দিন সময় লেগে গেল. এর মাঝে ভুল চোখে পড়া কোনো ত্রুটি সমাধান করতে? আরও দুই দিন. পরিশেষে যখন আমরা ফ্ল্যাগটি সক্রিয় করার পুরোপুরি প্রস্তুতি নিলাম, তখনই একটি দল তাদের নিজস্ব কোনো অপ্রাসঙ্গিক কারণে সার্ভিসটিকে ত্রুটিযুক্ত পুরোনো ক্লায়েন্টে ফিরিয়ে নিল—যার ফলে যে বিপর্যয়টি এড়াতে আমরা প্রাণান্তকর চেষ্টা করছিলাম, ঠিক সেটাই ঘটে গেল.

ক্লায়েন্ট লাইব্রেরিতে যেকোনো পরিবর্তনের জন্য কয়েক ডজন সার্ভিস জুড়ে জটিল সমন্বয় সাধনের প্রয়োজন হতো, যা ক্রমেই ভঙ্গুর, অদক্ষ এবং পরিচালনাগত ব্যর্থতার ঝুঁকিপূর্ণ হয়ে উঠেছিল. ভবিষ্যতে মোতায়েনের ক্ষেত্রে এই ধরনের পরিচালনাগত জটিলতা দূর করতে আমরা Habitat-কে নিজস্ব সার্ভিসে রূপান্তর করার সিদ্ধান্ত নিই.

স্টোরেজ লজিককে একটি স্বতন্ত্র সার্ভিসে আলাদা করে নেওয়ার মাধ্যমে আমরা অ্যাপ্লিকেশন মোতায়েন, পর্যবেক্ষণ এবং প্ল্যাটফর্মের সার্বিক উন্নয়নের জন্য একটি একক নিয়ন্ত্রণ কেন্দ্র স্থাপন করতে সক্ষম হই. খণ্ড খণ্ড আপডেট ব্যবস্থাপনার পরিবর্তে আমরা কেন্দ্রীয়ভাবে উন্নয়নমূলক কাজগুলো সম্পাদন করতে পারতাম, যা প্রতিটি OpenAI পণ্যে তাৎক্ষণিক সুবিধা এনে দিত.

একটি কেন্দ্রীভূত সার্ভিস আমাদের সবচেয়ে শক্তিশালী ডেটা সুরক্ষা এবং গোপনীয়তার মানদণ্ড বজায় রাখার একক নিয়ন্ত্রণও এনে দেয়. Habitat সার্ভিসেই আমরা কেন্দ্রীয়ভাবে অ্যাক্সেস কন্ট্রোল নীতিমালা প্রয়োগ করতে পারি, অডিট লগ তৈরি করতে পারি এবং Azure Cosmos DB-র মতো অন্তর্বর্তী স্টোরেজ রিসোর্সে প্রবেশাধিকার নিয়ন্ত্রণ করতে পারি. ব্যবহারকারীর ডেটা সুরক্ষিত রাখা এবং বাইরের, ভেতরের কিংবা কোনো অনাকাঙ্ক্ষিত প্রতিনিধির অননুমোদিত প্রবেশাধিকার প্রতিহত করতে Habitat অত্যন্ত গুরুত্বপূর্ণ ভূমিকা পালন করে.

ব্যাপক পরিসরে একটি Python সার্ভিস চালু করা

আমরা জানতাম যে আমাদের একটি সার্ভিস প্রয়োজন, তবে সার্ভিস হিসেবে ব্যবহারের বাড়তি ওভারহেড থাকা সত্ত্বেও আমরা এখনই Python ছেড়ে যেতে চাইনি. লোকাল লাইব্রেরি এক্সিকিউশনের তুলনায় উচ্চ-থ্রুপুট সার্ভিসে Python ব্যবহারের ফলে নেটওয়ার্ক লেটেন্সি বৃদ্ধি পেয়েছিল এবং CPU ও মেমোরি স্কেলিং সংক্রান্ত খরচ উল্লেখযোগ্য পরিমাণে বেড়েছিল. তদুপরি, আমরা অনুধাবন করতে পেরেছিলাম যে 100x স্কেলে Python-এর এমন অদক্ষতা গ্রহণযোগ্য হবে না, যার ফলে শেষ পর্যন্ত এটি নতুন করে লিখে ফেলা প্রায় নিশ্চিত ছিল.

তবে আমরা এটিকে টেকনিক্যাল ঋণের একটি কৌশলগত অনুপ্রবেশ হিসেবে বিবেচনা করেছিলাম. তখন আমাদের মূল লক্ষ্য খরচ বা রিসোর্স অপ্টিমাইজেশন ছিল না, বরং প্রোডাক্ট ডেভেলপারদের বাধাগুলো দূর করা এবং প্ল্যাটফর্মের স্থিতিশীলতা অর্জন করাই প্রধান ছিল. স্বল্পমেয়াদে একটি Python সার্ভিসের কার্যক্ষমতার এই আপস মেনে নেওয়ার মাধ্যমে আমরা আরও তাৎক্ষণিক চ্যালেঞ্জগুলোকে অগ্রাধিকার দিতে, আমাদের মূল API-গুলো প্রতিষ্ঠা করতে এবং একটি শক্তিশালী অবকাঠামো তৈরি করতে সক্ষম হয়েছিলাম.

আমরা একটি সুচিন্তিত বাজিও ধরেছিলাম যে আমাদের নিজস্ব কোডিং মডেলগুলোর দ্রুত অগ্রগতি ভবিষ্যতের প্রযুক্তিগত পথকে সহজ করবে. আমাদের ধারণা ছিল, যখন Python থেকে সম্পূর্ণ মাইগ্রেশন জরুরি হয়ে পড়বে, তখন Codex ও GPT সেই মাইগ্রেশনটি সম্ভব করে তুলবে. শেষ পর্যন্ত সেই বাজিটিই সঠিক প্রমাণিত হয়েছিল.

Habitat-কে একটি Python সার্ভিস হিসেবে পরিচালনা করা পারফরম্যান্সের দিক থেকে পুরোপুরি আদর্শ ছিল না, কিন্তু তা ছিল একটি অনিবার্য সিদ্ধান্ত. Python আমাদের দ্রুত কাজ এগিয়ে নিতে দেয়, কিন্তু তার অর্থ এই নয় যে আমরা সতর্কতা ভুলে গিয়ে কার্যক্ষমতা আশঙ্কাজনকভাবে ধীর হওয়া মেনে নেব. যখন একজন সাধারণ ব্যবহারকারীর একটি অনুরোধেই শত শত ডেটাবেস কল তৈরি হয়, তখন সবচেয়ে ধীরগতির ডেটাবেস কলটিই ব্যবহারকারীর অভিজ্ঞতা নষ্ট করে. আমরা দেখেছি যে, এই স্কেলে একটি Python সার্ভিস চালানোর মূল চ্যালেঞ্জই হলো লেটেন্সির এই দীর্ঘসূত্রতা সামলানো.

asyncio বিলম্ব ট্র্যাক করা

Asyncio মূলত Python-কে I/O-নির্ভর কাজগুলো একসঙ্গে সম্পাদন করতে সহায়তা করে, কিন্তু এটি Python GIL এড়িয়ে CPU প্যারালেলিজম প্রদানে সক্ষম নয়. I/O-ভারী রিকোয়েস্ট প্রক্সির পাশাপাশি Habitat আরও অনেক CPU-ভারী দায়িত্ব ও ব্যাকগ্রাউন্ড টাস্ক সামলায়: রাউটিং, কম্প্রেশন, এনক্রিপশন, চেকসামিং, ডাউনস্ট্রিম হেলথ চেকিং, রিকোয়েস্ট শ্যাডোয়িং এবং হেজিং.

আমাদের সার্ভিসে প্রচুর পরিমাণে CPU-নির্ভর কাজ এবং ব্যাকগ্রাউন্ড টাস্ক থাকায় asyncio শিডিউলিং বিলম্ব সহজেই অনুরোধের লেটেন্সিকে মারাত্মকভাবে বাড়িয়ে দিতে পারে. প্রাথমিক সার্ভিসটি চালু করার আগে টিউনিংয়ের সময় p99 এবং তার চেয়েও ধীরগতির অনুরোধগুলোর ক্ষেত্রে আমরা লক্ষ্য করেছিলাম যে, ডাউনস্ট্রিম স্টোরেজ দ্রুত প্রতিক্রিয়া জানালেও, রেসপন্স পার্স করার দায়িত্বে থাকা coroutine-টি নতুন করে শিডিউল হওয়ার অপেক্ষায় অনুরোধগুলো প্রায়ই থমকে থাকত.

চিত্র 03 · asyncio বিলম্ব ট্র্যাক করা

কনকারেন্সি এবং CPU প্যারালেলিজম এক বিষয় নয়

Python asyncio একসঙ্গে একাধিক অনুরোধ প্রক্রিয়া করার সুবিধা দিলেও, একবারে CPU থ্রেডে কেবল একটি একক অনুরোধই সম্পাদিত হয়. ফলে যখন প্রচুর CPU কাজের প্রয়োজন পড়ে, তখন এটি অনুরোধ প্রক্রিয়াকরণের সময়ে ব্যাপক বিলম্ব তৈরি করে.

CPU অনুরোধ/প্রতিক্রিয়া প্রক্রিয়াকরণPython network read/writeCosmos-এর জন্য অপেক্ষা

কম CPU কাজ

সংক্ষিপ্ত Python ধাপ; I/O অপেক্ষা একে অপরের সাথে মিলে যায়

উচ্চ CPU কাজ

দীর্ঘ Python ধাপ প্রস্তুত রেসপন্সগুলোকে অপেক্ষায় রাখে

0.0 / 40 কাল্পনিক ইউনিট

OpenAI-তে পরিচালিত Python সার্ভিসগুলোর জন্য আমরা দেখেছি যে মেমোরি, CPU, নেটওয়ার্ক এবং ডিস্ক ব্যবহারের সাধারণ মানদণ্ডগুলো পরিমাপের পাশাপাশি asyncio লুপটি পর্যবেক্ষণ করা এবং তা কতটা ব্যস্ত রয়েছে তা দেখে সেই অনুযায়ী টিউন করা অত্যন্ত গুরুত্বপূর্ণ.

নির্দিষ্ট সময় পরপর ব্যাকগ্রাউন্ড টাস্ক শিডিউল করে এবং প্রত্যাশিত ও বাস্তব এক্সিকিউশন সময়ের ব্যবধান রেকর্ড করার মাধ্যমে আমরা কার্যকরভাবে ইভেন্ট লুপ শিডিউলিংয়ের বিলম্ব রিয়েল টাইমে পরিমাপ করতে সক্ষম হই. উচ্চ ব্যবহার এবং অনেক জটিল কাজের ক্ষেত্রে প্রসেস প্রতি মাঝারি সংখ্যক যুগপৎ অনুরোধও উল্লেখযোগ্য শিডিউলিং বিশৃঙ্খলা তৈরির জন্য যথেষ্ট, যা শত শত মিলিসেকেন্ড এবং কিছু বিরল ক্ষেত্রে কয়েক সেকেন্ড পর্যন্ত হতে পারে.

ফলস্বরূপ, আমরা প্রতিটি প্রক্রিয়ার মাধ্যমে কেবল অল্প সংখ্যক যুগপৎ অনুরোধ পরিচালনার কৌশল গ্রহণ করি এবং তার পরিবর্তে ব্যাপকভাবে Python ওয়ার্কার প্রসেসের সংখ্যা বাড়িয়ে তুলি.

আমাদের ফিচার ফ্ল্যাগ কনফিগারেশনে অতিরিক্ত বিলম্ব কমিয়ে আনা

আমাদের প্রাথমিক সার্ভিসটি চালু করার সময় লাইভ সার্ভিসের CPU প্রোফাইলিংয়ের মাধ্যমে আমরা উচ্চমাত্রার asyncio বিলম্বের (এবং এর ফলে সৃষ্ট টেল ল্যাটেন্সির) একটি মূল কারণ খুঁজে পাই: Statsig-এর মাধ্যমে আমাদের ফিচার ফ্ল্যাগ কনফিগারেশনের নিয়মিত JSON পার্সিং (Statsig মূলত এমন একটি টুল যা ফিচার ফ্ল্যাগ পরিচালনা করে, এবং A/B টেস্ট বা অন্যান্য কাজে ব্যবহার করা যায়).

ডিফল্টভাবে Statsig এমনভাবে কনফিগার করা ছিল যেন এটি কোনো বিরতি ছাড়াই প্রতি মিনিটে আপডেট কনফিগ খোঁজে, এবং সেই কনফিগে প্রতিটি সার্ভিসের সমস্ত প্রোডাকশন রুল অন্তর্ভুক্ত ছিল. অন্যদিকে, উচ্চ CPU ব্যবহার নিশ্চিত করতে এবং বিলম্ব কমাতে প্রতি পডে সর্বোচ্চ 8টি পর্যন্ত Python প্রসেস চালানোর একটি স্থাপত্যগত সিদ্ধান্ত নেওয়া হয়েছিল. ফলে প্রতি মিনিটে প্রতিটি পডের এমন একটি মুহূর্ত আসত যখন তার সমস্ত কর্মী চলমান অনুরোধগুলোর প্রক্রিয়াকরণ থামিয়ে একটি বিশাল কনফিগারেশন ফাইল পার্স করতে নিজেদের CPU শক্তি অপচয় করত.

CPU প্রোফাইলিংয়ের মাধ্যমে মূল সমস্যাটি চিহ্নিত করার পর এর সমাধান ছিল বেশ সহজ: একটি অপেক্ষাকৃত ছোট ও সুনির্দিষ্ট কনফিগ মোতায়েন করা, রিফ্রেশ করার মধ্যবর্তী সময় বাড়ানো এবং এ ধরনের ব্যাকগ্রাউন্ড কাজে কিছুটা পরিবর্তনশীল বিরতি যুক্ত করা.

লোড ভারসাম্য রাখা এবং সংযোগ পুল পরিচালনা করা

asyncio-র বিলম্ব কম রাখতে, সার্ভার প্রসেসগুলো জুড়ে অনুরোধের ভারসাম্য ঠিক রাখাও অত্যন্ত জরুরি; টিউনিং ছাড়া সংযোগ পুলিং এর বিপরীত প্রভাবও ফেলতে পারে.

ক্লায়েন্ট-সাইড সংযোগ পুলিং থাকলে, একসঙ্গে অনেক অনুরোধ পাঠানো একটি ক্লায়েন্ট প্রসেস হয়তো কেবল কয়েকটি সার্ভার সংযোগ তৈরি করে এবং ফলে নিজের সব লোড অল্প কিছু প্রসেসের ওপর ফেলে দেয়. লোড ভারসাম্যের পদ্ধতিতে পরিবর্তন আনার আগে, আমাদের সেবায় ব্যবহারের ক্ষেত্রে ব্যাপক তারতম্য দেখা যেত; কিছু টেইল প্রসেস গড়ে 5-10 গুণ বেশি সমসাময়িক অনুরোধ সামলাচ্ছিল.

একটি অপ্রত্যাশিত ঘটনায় আমরা এটি লক্ষ্য করি: সেবার যে অংশটিতে অতিরিক্ত চাপ পড়ছিল তার ক্লায়েন্ট বন্ধ করার পরেও, ট্রাফিকের হঠাৎ চাপ কমে যাওয়ার অনেকক্ষণ পর পর্যন্ত কিছু প্রসেসের কার্যক্ষমতা ব্যাহত ছিল. প্রকৃতপক্ষে, আমরা দেখি সেই প্রসেসগুলো ক্রমাগত অবনতির শিকার হচ্ছিল এবং পুনরায় চালু না করা পর্যন্ত আরও বেশি অনুরোধ গ্রহণ করছিল. কোনো একটি পড অতিরিক্ত চাপে পড়লে, কিছু আচরণ সেই ওভারলোডেড পডেই আরও ট্রাফিক পাঠাচ্ছিল. এটি এমন এক ধরনের ব্যর্থতা, যা আমাদের কিছু সহকর্মী আগের কাজ থেকেই জানতেন: মেটাস্টেবল ব্যর্থতা(একটি নতুন উইন্ডোতে খোলে).

আমাদের সন্দেহ ছিল সংযোগ পুলই দায়ী, তাই সংযোগ পুনঃব্যবহারের সর্বোচ্চ সময়সীমা বেঁধে দিয়ে আমরা এই সন্দেহ পরীক্ষা করি; এটি আসলেই অবনতি সীমিত করে এবং আমাদের তদন্তের দিকটি নিশ্চিত করে. আরও তদন্তে দেখা যায় যে Python-এর aiohttp TCPConnector পূর্বনির্ধারিতভাবে LIFO সংযোগ পুনঃব্যবহার করে: পরবর্তী অনুরোধের জন্য সবচেয়ে সম্প্রতি ফেরত আসা সংযোগটি বেছে নেওয়া হয়. সাধারণত এটি একটি যৌক্তিক পদ্ধতি: সাম্প্রতিক সংযোগগুলো আবার ব্যবহার করলে অতিরিক্ত সংযোগগুলো নিষ্ক্রিয় হয়ে বন্ধ হওয়ার সুযোগ পায়, যা ট্রাফিকের চাপ সামলাতে তৈরি সংযোগগুলোর রক্ষণাবেক্ষণ খরচ কমায়. তবে এই ক্ষেত্রে, এটি আমাদের জন্য একটি মেটাস্টেবল ব্যর্থতা তৈরি করেছিল. অনুরোধের তীব্র চাপের সময়, ধীরগতির অতিরিক্ত চাপে থাকা সার্ভারগুলোতে পাঠানো অনুরোধগুলোর সংযোগ পুলে দেরিতে ফিরত এবং পরবর্তী অনুরোধগুলো বারবার সেগুলোকেই বেছে নিত, যা হিমশিম খাওয়া পডগুলোতে ট্রাফিক আরও কেন্দ্রীভূত করছিল. FIFO পুনঃব্যবহার ব্যবহারের জন্য সংযোগ পুলে প্যাচ প্রয়োগ করায় এই প্রতিক্রিয়া চক্রটি ভেঙে যায় এবং স্থিতিশীল অবস্থায় অনুরোধের তারতম্যও কমে আসে.

চিত্র 04A · ক্লায়েন্ট-সাইড সংযোগ পুলিং

LIFO নতুন কাজ আবার ধীরগতির প্রসেসে পাঠায়

অনুরোধের তীব্র চাপের পর, ধীরগতির সার্ভারগুলো সবার শেষে পুলে সংযোগ ফেরত দেয়. LIFO সেই একই ধীরগতির সার্ভারগুলোতে আরও বেশি কাজ কেন্দ্রীভূত করতে উৎসাহ দেয়.

প্রাথমিক একটি চাপ A, B এবং তুলনামূলক ধীর প্রসেস C-তে পৌঁছায়.

চিত্র 04B · ক্লায়েন্ট-সাইড সংযোগ পুলিং

FIFO সংযোগ পুনর্ব্যবহারের প্রতিক্রিয়া চক্র ভেঙে দেয়

হঠাৎ চাপ বাড়ার পরেও FIFO বেশি সংখ্যক সক্রিয় সংযোগ ধরে রাখে, তবে সব সার্ভার জুড়ে কাজের চাপ সমভাবে বণ্টন করে.

প্রাথমিক একটি চাপ A, B এবং তুলনামূলক ধীর প্রসেস C-তে পৌঁছায়.

বর্তমানে, সংযোগ পুলিং এবং সার্ভারের লোড বুঝে আরও ভালো ভারসাম্য রক্ষার জন্য আমরা মূলত পুরো OpenAI অবকাঠামো জুড়ে Istio এবং Envoy-এর ওপর নির্ভর করি, যা সমস্যাটি পুরোপুরি এড়িয়ে চলতে সাহায্য করে.

ডাউনস্ট্রিম রিসোর্সের ওপর অতিরিক্ত চাপ এড়ানো

asyncio-র বিলম্ব কম রাখার টিউনিং এবং প্রচুর সংখ্যক Python প্রসেস থাকার একটি পার্শ্বপ্রতিক্রিয়া হলো, বিপুল সংখ্যক সংযোগ দিয়ে ডাউনস্ট্রিম নির্ভরতাগুলোকে সহজেই অতিরিক্ত চাপে ফেলে দেওয়া যায় (যা “thundering herd” নামে পরিচিত).

নিয়মিত দৈনিক ডিপ্লয়মেন্ট—যদি ধীরগতির হওয়ার জন্য টিউন না করা হয়—সংযোগ চক্রের কারণে উল্লেখযোগ্য CPU অপচয় ঘটাতে পারে. অথবা সংযোগের লিক NAT গেটওয়েকে পূর্ণ করে নেটওয়ার্ক অচল করে দিতে পারে. এগুলো অন্যান্য সেবার ক্ষেত্রেও সাধারণ সমস্যা, তবে তুলনামূলকভাবে বহু গুণ বেশি প্রসেস থাকায় এই সমস্যাগুলো শুরু হওয়ার ঝুঁকি অনেক বেড়ে যায়; প্রায়ই নেটওয়ার্ক সংক্রান্ত রিসোর্সগুলো এমনভাবে পূর্ণ হয়ে যায় যা ক্লায়েন্টরা কেবল থ্রুপুটের ভিত্তিতে একটি স্থিতিশীল অবস্থায় আশা করে না.

আমরা সংযোগ ফ্যান-ইন সর্বোচ্চ করতেও Envoy-এর ওপর নির্ভর করি. মাল্টিপ্লেক্সিংয়ের সুবিধা নিতে Python-এর HTTP/1 সংযোগগুলোকে HTTP/2-তে আপগ্রেড করতে এবং এরপর সেই সংযোগগুলো পুল করে সেগুলোর স্থায়িত্ব বাড়াতে আমরা এটি ব্যবহার করি. Envoy আমাদের সীমা এবং সার্কিট ব্রেকার বাস্তবায়নের একটি কেন্দ্রীয় স্থানও দেয়, যা প্রতিটি পৃথক Python প্রসেসে কার্যকর করা কঠিন হতো.

চিত্র 05 · সংযোগ ফ্যান-ইন

একই অনুরোধ, কম সংযোগ

সংযোগ পুলিং এবং HTTP/2 সংযোগ মাল্টিপ্লেক্সিং ডাউনস্ট্রিমের ওপর সংযোগের চাপ কমাতে সাহায্য করে.

অনুরোধরেসপন্সনিষ্ক্রিয় কিপ-অ্যালাইভ

Habitat কেন কম কাজ করে

Python-কে এত দূর স্কেল করতে পারার অন্যতম একটি কারণ ছিল Habitat-এর সুনির্দিষ্ট সীমাবদ্ধ API, যা অনুরোধের খরচকে সবসময় অনুমেয় রাখে. ক্লায়েন্টদের যথেচ্ছ SQL কোয়েরি তৈরি করতে দেওয়ার বদলে, যা বড় টেবিল স্ক্যান বা বহু টেবিলের মধ্যে অনাকাঙ্ক্ষিত সংযোগ ঘটাতে পারে, Habitat একটি সহজ NoSQL API প্রদান করে. তুলনামূলক শক্তিশালী API না রাখার এই সিদ্ধান্তটি ছিল Habitat-এর নকশায় একটি সুচিন্তিত আপস.

আমাদের লক্ষ্য হলো সাধারণ, অনুমেয় এবং স্থিতিশীল কাজের অনুরোধের জন্য সিস্টেমকে অপ্টিমাইজ করা. আমাদের অভিজ্ঞতা বলে, এ ধরনের সিস্টেমগুলো স্কেল করা অত্যন্ত সহজ এবং এগুলোর ভুল বা অপব্যবহার হওয়ার ঝুঁকিও খুব কম. অনাকাঙ্ক্ষিত বিস্তার ঘটায় এমন অনুরোধগুলো পরিচালনা করা অত্যন্ত ঝুঁকিপূর্ণ: এগুলো আইসোলেশন ও লোড ব্যালেন্সিংকে জটিল করে তোলে এবং এমন চরম বিলম্ব তৈরি করে যা সার্ভিস ও ক্লায়েন্ট উভয়ের পক্ষেই সামলানো কঠিন হয়ে পড়ে.

Habitat এবং Azure Cosmos DB-তে যাওয়ার পূর্বে OpenAI-এর বেশিরভাগ অনলাইন ডেটা Postgres-এ সংরক্ষিত ছিল. সে সময়ে প্রোডাকশনে পাঠানোর আগেই সমস্ত কোয়েরি ও স্কিমার পরিবর্তনগুলো পরীক্ষা করে সেগুলো ইনডেক্স করা ডেটার বিপরীতে সঠিকভাবে কাজ করছে কি না তা নিশ্চিত করা সহজ ছিল. দল ও পণ্যের পরিধি বড় হওয়ার সাথে সাথে এই বিষয়টি দ্রুত নিয়ন্ত্রণহীন হয়ে পড়ে এবং ঘনঘন সিস্টেম বিভ্রাটের কারণ হয়ে দাঁড়ায়, যেখানে একটি গুরুত্বপূর্ণ পাথে চালিত একক ব্যয়বহুল নতুন কোয়েরি পুরো ডেটাবেসকেই নিষ্ক্রিয় করে দিত.

এখানে মূল সমস্যাটি ছিল খরচের ভারসাম্যের অভাব: এমন SQL কোয়েরি লেখা খুবই সহজ ও সুলভ যা চালানো অত্যন্ত ব্যয়বহুল এবং জটিল. Habitat-এ আমরা এটি এড়িয়ে চলি এবং ব্যয়বহুল কোয়েরির প্রভাব ক্লায়েন্ট-সাইডেই অত্যন্ত স্পষ্ট করে তুলি. Habitat-কে অতিরিক্ত ভারাক্রান্ত করতে পারে এমন কোনো অনির্দিষ্ট কোয়েরি এখানে নেই, এবং জটিল সংযোগ ও গ্রাফ ট্রাভার্সালের জন্য প্রোডাক্ট দলগুলোকেই কিছু কাঠখড় পোড়াতে হয়, যা সার্বিকভাবে আরও দক্ষ আর্কিটেকচার তৈরির ক্ষেত্রে সহায়তা করে.

Habitat ক্লায়েন্ট-সংজ্ঞায়িত অবজেক্ট ও এজ টাইপের ওপর ভিত্তি করে তৈরি একটি NoSQL API প্রদান করে, যা TAO(একটি নতুন উইন্ডোতে খোলে) দ্বারা অনুপ্রাণিত. ক্লায়েন্টরা আগেই অবজেক্ট ও এজ এবং তাদের পারস্পরিক সম্পর্ক নির্ধারণ করে দেয়, কিন্তু প্রতিটি টাইপের ভেতরের তথ্য নয়. এর ফলে গঠিত সম্পর্কগুলো দেখতে গ্রাফের মতো মনে হলেও নির্দিষ্ট অবজেক্টের সরাসরি এজ খোঁজা ছাড়া Habitat নিজস্বভাবে গতানুগতিক কোনো গ্রাফ ট্রাভার্সাল কোয়েরি সমর্থন করে না.

আমরা এই গ্রাফটিকে এমনভাবে বিভাজন করি যাতে প্রতিটি অবজেক্ট এবং তার সংশ্লিষ্ট এজগুলো স্টোরেজ-লেভেলের একই পার্টিশনে অবস্থান করে; তবে অবজেক্টগুলো এবং তাদের এজ নির্দেশিত দূরবর্তী অবজেক্টগুলোকে ডেটাবেস-লেভেলে একই স্থানে রাখার জন্য আমরা কোনো বাড়তি প্রয়াস চালাই না. এর ফলাফল হলো মডেলটি সহজে অনুভূমিকভাবে স্কেল করার উপযোগী হয়ে ওঠে, কিন্তু গ্রাফ ট্রাভার্সাল অদক্ষ থেকে যায়; কারণ অবজেক্টগুলোর মধ্যে একটি সাধারণ ট্রানজিশনের জন্যও ভিন্ন ভিন্ন অঞ্চলে সংরক্ষিত দুটি সম্পূর্ণ আলাদা Azure Cosmos DB অ্যাকাউন্ট থেকে ডেটা আনতে হতে পারে.

যেসব ক্লায়েন্টের আরও জটিল কোয়েরি পরিচালনার প্রয়োজন পড়ে, তাদের জন্য আমরা Rockset-এর মাধ্যমে Habitat-এর একটি অফলাইন সেকেন্ডারি ভিউ প্রদান করি. আমরা চেইঞ্জ ডেটা ক্যাপচার (CDC) ব্যবহার করে অনলাইন স্টোরেজের পরিবর্তনগুলোকে প্রায় তাৎক্ষণিকভাবে আলাদা করা Rockset ইনস্ট্যান্সে প্রবাহিত করি. প্রতিটি ক্লায়েন্ট দল তাদের জটিল কোয়েরির প্রয়োজন অনুযায়ী নিজস্ব Rockset ইনস্ট্যান্স স্কেল করার দায়িত্ব পালন করে.

Rockset ব্যবহারের এই ব্যবস্থাটি আমাদের ক্লায়েন্টদের কাজে কিছুটা বাড়তি ধাপ যুক্ত করে, তবে বর্তমান প্রেক্ষাপটে এটিই সবচেয়ে যথোপযুক্ত সিদ্ধান্ত: সাধারণ কোয়েরিগুলোকে ডিফল্ট রাখা এবং যাদের জটিল কোয়েরি প্রয়োজন তাদের জন্য একটি বিকল্প পথ খোলা রাখা. এই আর্কিটেকচার আমাদের অনলাইন স্টোরেজকে পাঠ-ভারী বিশ্লেষণাত্মক ও অনুসন্ধানী কাজের চাপ থেকে মুক্ত ও সুরক্ষিত রাখে.

Python থেকে Rust-এ মাইগ্রেট করা

Python-এ নতুন করে কোড লেখার কাজটি এক বছর পিছিয়ে দেওয়ায় আমাদের তীব্র প্রবৃদ্ধির সময় আরও জরুরি ও প্রভাব বিস্তারকারী চ্যালেঞ্জগুলোতে মনোযোগ দেওয়া সম্ভব হয়েছিল. প্ল্যাটফর্মটি পরিপক্ব হয়ে ওঠার সাথে সাথে এবং আমাদের প্রবৃদ্ধির গতি ক্রমাগত বাড়তে থাকায়, পাশাপাশি কোর সংখ্যার দিক থেকে OpenAI-এর দ্বিতীয় বৃহত্তম সার্ভিস (এবং আমাদের Envoy ফুটপ্রিন্টের দিক থেকে চতুর্থ) হওয়ায়, অবশেষে Python ছেড়ে এগিয়ে যাওয়ার সঠিক সময় উপস্থিত হয়েছিল. সর্বোচ্চ ব্যবহারের সময়েও Python আমাদের প্রতি সেকেন্ডে 20 মিলিয়নেরও বেশি অনুরোধ সামলাতে সাহায্য করেছে.

2026 সালের Q2-তে মাত্র দুইজন প্রকৌশলী, Codex এবং GPT‑5.5 ব্যবহার করে আমরা পুরো সার্ভিসটি Rust-এ নতুন করে লিখতে সক্ষম হয়েছিলাম. এই নতুন Rust সার্ভিসটি এখন আমাদের প্রোডাকশনের 95% অনুরোধ পরিচালনা করছে; আগামী কয়েক সপ্তাহের মধ্যে আমরা Python-এর ব্যবহার পুরোপুরি বন্ধ করে দেব. আমাদের ডেটা প্রমাণ করে যে এই Rust সার্ভিসটি পূর্বের Python সংস্করণের তুলনায় CPU ব্যবহারের ক্ষেত্রে 6x বেশি দক্ষ এবং মেমোরির ক্ষেত্রে 15x বেশি সাশ্রয়ী, যার ফলে এর সামগ্রিক ও দীর্ঘমেয়াদী বিলম্ব লক্ষণীয়ভাবে কমে গেছে. ভবিষ্যতে একটি ব্লগের মাধ্যমে আমরা আমাদের আরও অভিজ্ঞতা তুলে ধরার পরিকল্পনা করছি.

আমাদের ডাটাবেস লেয়ার Azure Cosmos DB অপ্টিমাইজ করা

Python এবং বর্তমানে Rust সার্ভিসটি Habitat-এর কেবল একটি ক্ষুদ্র অংশমাত্র. এক বিলিয়নের বেশি ChatGPT ব্যবহারকারীকে নিরবচ্ছিন্ন সেবা দিতে কীভাবে আমরা দ্রুত আমাদের অনলাইন স্টোরেজ স্কেল করেছি তা ব্যাখ্যার দ্বিতীয় পর্বে আমরা স্টোরেজ লেয়ার নিয়ে আলোচনা করব, এবং Habitat কীভাবে 500 পেটাবাইটের বেশি ডেটা এবং প্রতি সেকেন্ডে 70 মিলিয়নের বেশি অনুরোধ পরিচালনা করে তা তুলে ধরব.

আপনি যদি অত্যাধুনিক স্কেলের OLTP সিস্টেমে কাজ করতে চান এবং এ ধরনের প্রকৌশলে আগ্রহী হন, তবে আমাদের টিমের এই উন্মুক্ত পদটি দেখতে পারেন.

লেখকবৃন্দ

Jon Lee, Chaomin Yu, Ben Ries