Skip to main content

Command Palette

Search for a command to run...

Scaling PostgreSQL to power 800 million ChatGPT users

বাংলায় ভাবানুবাদ

Published
11 min read

উল্লেখ্য , এখানে আমি পুরোপুরি লেখকের ভাষা কে তুলে এনেছি । তাই যেখানে 'আমি' কিংবা 'আমরা' আছে , সেটা বুঝতে হবে লেখক অথবা openai টিম । অরিজিনাল ব্লগ এর লিঙ্কঃ https://openai.com/index/scaling-postgresql/

বছরের পর বছর ধরে, PostgreSQL নীরবে কিন্তু অত্যন্ত গুরুত্বপূর্ণ একটি ডেটা সিস্টেম হিসেবে কাজ করে আসছে, যা ChatGPT এবং OpenAI-এর API-এর মতো মূল পণ্যগুলোকে ভিতর থেকে শক্তি জোগাচ্ছে। আমাদের ব্যবহারকারীর সংখ্যা দ্রুত বাড়ার সঙ্গে সঙ্গে, ডেটাবেসের ওপর চাপও সমানভাবে বহুগুণ বেড়েছে। গত এক বছরে আমাদের PostgreSQL-এর ওপর লোড ১০ গুণেরও বেশি বৃদ্ধি পেয়েছে, এবং এই বৃদ্ধি এখনও দ্রুত গতিতে চলমান।

এই ক্রমবর্ধমান চাহিদা সামাল দিতে আমাদের প্রোডাকশন ইনফ্রাস্ট্রাকচার উন্নত করার প্রচেষ্টার মধ্যেই আমরা একটি নতুন উপলব্ধিতে পৌঁছাই: PostgreSQL এমনভাবে স্কেল করা সম্ভব, যা অনেকের ধারণার চেয়েও অনেক বড় read-heavy ওয়ার্কলোড নির্ভরযোগ্যভাবে সামলাতে পারে। ক্যালিফোর্নিয়া বিশ্ববিদ্যালয়, বার্কলির একদল বিজ্ঞানীর হাতে তৈরি হওয়া এই সিস্টেমটি আমাদের সক্ষম করেছে একটি মাত্র প্রধান Azure PostgreSQL Flexible Server ইনস্ট্যান্স⁠ এবং বিশ্বজুড়ে বিভিন্ন অঞ্চলে ছড়িয়ে থাকা প্রায় ৫০টি read replica ব্যবহার করে বিপুল বৈশ্বিক ট্রাফিক পরিচালনা করতে। এই লেখাটি সেই গল্প—কীভাবে আমরা শক্তিশালী অপ্টিমাইজেশন এবং দৃঢ় ইঞ্জিনিয়ারিংয়ের মাধ্যমে OpenAI-এ PostgreSQL স্কেল করেছি, যাতে ৮০০ মিলিয়ন ব্যবহারকারীর জন্য প্রতি সেকেন্ডে লক্ষ লক্ষ কোয়েরি পরিচালনা করা যায়; পাশাপাশি আমরা পথচলায় যে গুরুত্বপূর্ণ শিক্ষাগুলো পেয়েছি, সেগুলিও এখানে তুলে ধরা হবে।

Cracks in our initial design

ChatGPT চালু হওয়ার পর ট্রাফিক অভূতপূর্ব হারে বৃদ্ধি পায়। এটি সামাল দিতে আমরা খুব দ্রুত অ্যাপ্লিকেশন স্তর ও PostgreSQL ডেটাবেস স্তর—উভয় জায়গায় ব্যাপক অপ্টিমাইজেশন বাস্তবায়ন করি, ইনস্ট্যান্সের সাইজ বাড়িয়ে স্কেল-আপ করি, এবং আরও বেশি রিড রিপ্লিকা যোগ করে স্কেল-আউট করি। এই আর্কিটেকচারটি দীর্ঘ সময় ধরে আমাদের ভালোভাবে সেবা দিয়েছে। নিরবচ্ছিন্ন উন্নয়নের মাধ্যমে এটি ভবিষ্যৎ প্রবৃদ্ধির জন্যও যথেষ্ট সক্ষমতা ধরে রাখছে।

শুনতে অবাক লাগতে পারে যে একটি সিঙ্গেল-প্রাইমারি আর্কিটেকচার OpenAI-এর মতো স্কেলের চাহিদা পূরণ করতে পারে; তবে বাস্তবে এটি কার্যকরভাবে চালানো মোটেও সহজ নয়। আমরা Postgres-এর অতিরিক্ত লোডের কারণে একাধিক SEV ঘটতে দেখেছি, এবং সেগুলোর বেশিরভাগই একই ধরণের প্যাটার্ন অনুসরণ করে: কোনো আপস্ট্রিম সমস্যার কারণে হঠাৎ করে ডেটাবেসের ওপর চাপ বেড়ে যায়—
যেমন, ক্যাশিং লেয়ারে ব্যর্থতার ফলে ব্যাপক ক্যাশ মিস হওয়া, একাধিক টেবিল জুড়ে করা ব্যয়বহুল জয়েনের কারণে CPU সম্পূর্ণভাবে স্যাচুরেট হয়ে যাওয়া, অথবা নতুন কোনো ফিচার চালুর ফলে একসাথে বিপুল পরিমাণ রাইট অপারেশন শুরু হওয়া। রিসোর্স ব্যবহারের মাত্রা বাড়ার সাথে সাথে কোয়েরির লেটেন্সি বৃদ্ধি পায় এবং রিকোয়েস্ট টাইম-আউট হতে শুরু করে। এরপর রিট্রাই আরও বেশি লোড সৃষ্টি করে, যা একটি দুষ্টচক্র তৈরি করে এবং পুরো ChatGPT ও API সার্ভিসের কার্যক্ষমতা মারাত্মকভাবে ক্ষতিগ্রস্ত হওয়ার ঝুঁকি তৈরি করে।

যদিও আমাদের read-heavy ওয়ার্কলোডে PostgreSQL ভালোভাবে স্কেল করে, তবুও উচ্চ write ট্রাফিকের সময় আমরা এখনো বিভিন্ন চ্যালেঞ্জের মুখে পড়ি। এর প্রধান কারণ হলো PostgreSQL-এর multiversion concurrency control (MVCC) পদ্ধতি, যা write-heavy ওয়ার্কলোডের ক্ষেত্রে তুলনামূলকভাবে কম কার্যকর। উদাহরণস্বরূপ, কোনো query যদি একটি tuple বা এমনকি একটি মাত্র field আপডেট করে, তবুও একটি নতুন ভার্সন তৈরি করার জন্য পুরো row কপি করা হয়। উচ্চ write লোডের পরিস্থিতিতে এটি উল্লেখযোগ্য পরিমাণ write amplification সৃষ্টি করে। পাশাপাশি, read amplification-ও বেড়ে যায়, কারণ সর্বশেষ ভার্সনটি পাওয়ার জন্য query-গুলোকে একাধিক tuple ভার্সন (dead tuple) স্ক্যান করতে হয়। MVCC আরও কিছু অতিরিক্ত সমস্যা নিয়ে আসে, যেমন table ও index bloat, index রক্ষণাবেক্ষণে বাড়তি overhead, এবং autovacuum টিউনিংকে জটিল করে তোলা। (এই বিষয়গুলো নিয়ে বিস্তারিত আলোচনা পাওয়া যাবে Carnegie Mellon University-এর Prof. Andy Pavlo-র সঙ্গে আমার লেখা একটি ব্লগে, যার নাম The Part of PostgreSQL We Hate the Most , যা PostgreSQL-এর Wikipedia পাতায়ও উল্লেখ করা হয়েছে।)

Scaling PostgreSQL to millions of QPS

এই সীমাবদ্ধতাগুলো কমানো এবং write pressure হ্রাস করার জন্য আমরা shard করা যায় এমন (অর্থাৎ যেসব workload , Horizontally ভাগ করা সম্ভব), write-heavy workload গুলোকে shard-ভিত্তিক সিস্টেমে—যেমন Azure Cosmos DB—এ মাইগ্রেট করেছি এবং এখনও করে চলেছি। একই সঙ্গে, অপ্রয়োজনীয় write কমানোর জন্য অ্যাপ্লিকেশন লজিক অপ্টিমাইজ করা হয়েছে। বর্তমান PostgreSQL ডিপ্লয়মেন্টে নতুন কোনো টেবিল যোগ করাও আমরা আর অনুমোদন দিচ্ছি না। নতুন workload গুলো ডিফল্টভাবেই shard-ভিত্তিক সিস্টেমে যাচ্ছে।

আমাদের ইনফ্রাস্ট্রাকচার সময়ের সঙ্গে অনেক পরিবর্তিত হলেও PostgreSQL এখনো unsharded অবস্থায় রয়েছে, যেখানে একটি মাত্র primary instance সব write পরিচালনা করে। এর প্রধান কারণ হলো, বিদ্যমান অ্যাপ্লিকেশন workload গুলোকে shard করা অত্যন্ত জটিল ও সময়সাপেক্ষ—এর জন্য শত শত অ্যাপ্লিকেশন endpoint-এ পরিবর্তন আনতে হতো, যা সম্পন্ন করতে মাসের পর মাস, এমনকি বছরেরও বেশি সময় লাগতে পারে। যেহেতু আমাদের বেশিরভাগ workload read-heavy এবং আমরা ইতিমধ্যেই ব্যাপক অপ্টিমাইজেশন বাস্তবায়ন করেছি, তাই বর্তমান আর্কিটেকচারটি ভবিষ্যতের ট্রাফিক বৃদ্ধিও স্বচ্ছন্দে সামাল দেওয়ার মতো যথেষ্ট সক্ষমতা রাখে। ভবিষ্যতে PostgreSQL shard করার সম্ভাবনা পুরোপুরি বাদ দিচ্ছি না, তবে বর্তমান ও আসন্ন বৃদ্ধির জন্য আমাদের যে পর্যাপ্ত সময় ও সক্ষমতা আছে, সে কারণে এটি এখনই অগ্রাধিকার নয়।

পরবর্তী অংশগুলোতে আমরা যে চ্যালেঞ্জগুলোর মুখোমুখি হয়েছি এবং সেগুলো মোকাবিলা ও ভবিষ্যতের outage প্রতিরোধে যে বিস্তৃত অপ্টিমাইজেশনগুলো করেছি, সেগুলো বিস্তারিতভাবে আলোচনা করব—যার মাধ্যমে PostgreSQL-কে তার সীমার শেষ পর্যন্ত নিয়ে গিয়ে প্রতি সেকেন্ডে মিলিয়ন সংখ্যক query (QPS - Query Per Second) স্কেল করা সম্ভব হয়েছে।

Reducing load on the primary

চ্যালেঞ্জ: শুধু একজন writer থাকায়, single-primary সেটআপ write স্কেল করতে পারে না। write spike খুব দ্রুত primary overload করতে পারে এবং ChatGPT ও আমাদের API-এর মতো সার্ভিসে প্রভাব ফেলতে পারে।

সমাধান: আমরা primary-এর লোড যতটা সম্ভব কমিয়ে রাখি—উভয় read এবং write—যাতে এটি write spike সামলানোর জন্য পর্যাপ্ত সক্ষমতা রাখে। Read traffic যেখানেই হওয়া সম্ভব, সেগুলিকে replica-তে সরানো হয়। তবে কিছু read query primary-তে রাখতে হয় কারণ সেগুলো write transaction-এর অংশ। এর জন্য আমরা নিশ্চিত করি যে সেগুলো কার্যকর এবং slow query যেন এড়াতে পারে।

Write traffic-এর জন্য, আমরা shard-able, write-heavy workload গুলোকে shard-ভিত্তিক সিস্টেমে মাইগ্রেট করেছি, যেমন Azure CosmosDB। যেসব workload shard করা কঠিন কিন্তু এখনও high write volume তৈরি করে, সেগুলো মাইগ্রেশন প্রক্রিয়ায় বেশি সময় নিচ্ছে, এবং এই প্রক্রিয়া এখনও চলছে।

আমরা আমাদের অ্যাপ্লিকেশনকেও আগ্রাসীভাবে অপ্টিমাইজ করেছি write load কমানোর জন্য; উদাহরণস্বরূপ, redundant write তৈরি করা অ্যাপ্লিকেশন bug ফিক্স করেছি এবং lazy write প্রবর্তন করেছি যেখানে প্রয়োজন, যাতে traffic spike smoother হয়। এছাড়াও, table field backfill করার সময় আমরা strict rate limit enforce করি, যাতে অতিরিক্ত write pressure তৈরি না হয়।

Query optimization

চ্যালেঞ্জ: আমরা PostgreSQL-এ কয়েকটি ব্যয়বহুল (expensive) query সনাক্ত করেছি। অতীতে, এই query গুলোর volume হঠাৎ বেড়ে গেলে CPU অনেক বেশি ব্যবহার হতো, যার ফলে ChatGPT এবং API request উভয়ই ধীর হয়ে যেত।

সমাধান: কিছু ব্যয়বহুল query, যেমন একাধিক টেবিল join করা query, সম্পূর্ণ সার্ভিসকে উল্লেখযোগ্যভাবে ধীর বা এমনকি ডাউন করে দিতে পারে। তাই PostgreSQL query গুলোকে ধারাবাহিকভাবে optimize করা দরকার, যাতে সেগুলো কার্যকর থাকে এবং সাধারণ OLTP (Online Transaction Processing) anti-pattern এড়ানো যায়।

উদাহরণস্বরূপ, আমরা একবার একটি অত্যন্ত ব্যয়বহুল query সনাক্ত করেছি যা 12টি টেবিল join করেছিল, এবং এই query-এর spike অতীতে high-severity SEV-এর জন্য দায়ী ছিল। সম্ভব হলে জটিল multi-table join এড়ানো উচিত। যদি join অপরিহার্য হয়, আমরা শিখেছি query ভাঙার বিষয় বিবেচনা করতে এবং জটিল join লজিক অ্যাপ্লিকেশন লেয়ারে স্থানান্তর করতে।

এই ধরনের অনেক problematic query , Object-Relational Mapping (ORM) framework দ্বারা তৈরি হয়, তাই তাদের উৎপাদিত SQL সাবধানে পর্যালোচনা করা এবং প্রত্যাশিতভাবে কাজ করছে কি না নিশ্চিত করা গুরুত্বপূর্ণ।

PostgreSQL-এ "long-running idle queries" পাওয়া বেশ সাধারণ। সেগুলো যেন autovacuum ব্লক না করে , সেটার জন্য idle_in_transaction_session_timeout-এর মতো timeout configure করা অত্যাবশ্যক।

Single point of failure mitigation

চ্যালেঞ্জ: যদি একটি read replica ডাউন হয়ে যায়, traffic এখনও অন্য replica-তে রাউট করা যায়। তবে, শুধু একজন writer-এর ওপর নির্ভর করা মানে single point of failure—যদি writer ডাউন হয়, পুরো সার্ভিস প্রভাবিত হয়।

সমাধান: বেশিরভাগ critical request কেবল read query-এর সঙ্গে সম্পর্কিত। Primary-এর single point of failure হ্রাস করতে, আমরা writer থেকে সেই read গুলো replica-তে সরিয়েছি, যাতে primary ডাউন হলেও request গুলো সার্ভিস চালাতে পারে। Write operation এখনও ব্যর্থ হবে, তবে প্রভাব কমে যায়; এটি আর SEV0 নয় কারণ reads রিকুয়েস্ট গুলো এখনও available ।

Primary failure হ্রাস করতে, আমরা primary-কে High-Availability (HA) মোডে চালাই একটি hot standby-এর সঙ্গে, যা একটি continuous synchronized replica এবং সর্বদা traffic handle করতে প্রস্তুত থাকে। যদি primary ডাউন হয় বা maintenance-এর জন্য offline নিতে হয়, আমরা দ্রুত standby promote করতে পারি, downtime সর্বনিম্ন রাখতে। Azure PostgreSQL টিম যথেষ্ট কাজ করেছে যাতে এই failover গুলো খুব high load-এরও মধ্যে নিরাপদ এবং নির্ভরযোগ্য থাকে।

Read replica failure মোকাবিলার জন্য, আমরা প্রতিটি region-এ একাধিক replica deploy করি যথেষ্ট capacity headroom সহ, যাতে একটি replica failure regional outage তৈরি না করে।

Workload isolation

চ্যালেঞ্জ: আমরা প্রায়ই এমন পরিস্থিতির মুখোমুখি হই যেখানে কিছু request, PostgreSQL instance-এ অস্বাভাবিক পরিমাণে resource ব্যবহার করে। এর ফলে একই instance-এ চলা অন্য workload-এর performance ক্ষতিগ্রস্ত হয়। উদাহরণস্বরূপ, নতুন feature launch-এর সময় কিছু অকার্যকর query, PostgreSQL CPU অনেক বেশি ব্যবহার করতে পারে, যা অন্য critical feature-এর request ধীর করে দেয়।

সমাধান: “noisy neighbor” সমস্যাটি কমানোর জন্য, আমরা workload গুলো dedicated instance-এ isolate করি, যাতে resource-intensive request-এর হঠাৎ spike অন্য traffic-কে প্রভাবিত না করে। বিশেষভাবে, আমরা request গুলো low-priority এবং high-priority tier-এ ভাগ করি এবং আলাদা instance-এ রাউট করি। এর ফলে, low-priority workload resource-intensive হলেও high-priority request-এর performance degrade হবে না। আমরা এই একই কৌশল বিভিন্ন product এবং service-এও প্রয়োগ করি, যাতে এক product-এর activity অন্য product-এর performance বা reliability প্রভাবিত না করে।

Connection pooling

চ্যালেঞ্জ: প্রতিটি instance-এর একটি maximum connection limit থাকে (Azure PostgreSQL-এ 5,000)। Connections শেষ হয়ে যাওয়া বা অনেক idle connection জমে যাওয়া সহজ। অতীতে connection storm-এর কারণে সব available connection শেষ হয়ে যাওয়ার ঘটনা ঘটেছে।

সমাধান: আমরা PgBouncer deploy করেছি একটি proxy layer হিসেবে, যা database connection pool করে। Statement বা transaction pooling mode-এ চালালে আমরা connection reuse করতে পারি, ফলে active client connection-এর সংখ্যা অনেক কমে যায়। এটি connection setup latency-ও কমায়: আমাদের benchmark অনুযায়ী, average connection time 50 milliseconds (ms) থেকে কমে 5 ms হয়েছে। Inter-region connection এবং request ব্যয়বহুল হতে পারে, তাই proxy, client, এবং replica একই region-এ co-locate করি, যাতে network overhead এবং connection use time কমানো যায়। এছাড়াও, PgBouncer সাবধানে configure করা প্রয়োজন। Idle timeout-এর মতো setting অত্যন্ত গুরুত্বপূর্ণ, যাতে connection exhaustion এর মত ঘটনা না ঘটে।

প্রতিটি read replica-এর জন্য একটি আলাদা Kubernetes deployment থাকে, যেখানে একাধিক PgBouncer pod চালানো হয়। আমরা একাধিক Kubernetes deployment একই Kubernetes Service-এর পিছনে চালাই, যা pods-গুলোর মধ্যে traffic load-balance করে।

Caching

চ্যালেঞ্জ: Cache miss-এর হঠাৎ spike PostgreSQL database-এ read surge তৈরি করতে পারে, যা CPU saturate করে এবং user request ধীর করে দেয়।

সমাধান: PostgreSQL-এর read pressure কমানোর জন্য, আমরা একটি caching layer ব্যবহার করি যা অধিকাংশ read traffic serve করে। তবে, cache hit rate হঠাৎ কমে গেলে, cache miss-এর burst অনেক request সরাসরি PostgreSQL-এ পাঠায়। এই হঠাৎ database read বৃদ্ধি উল্লেখযোগ্য resource ব্যবহার করে এবং সার্ভিস ধীর করে দেয়।

Cache-miss storm-এর সময় overload এড়াতে, আমরা cache locking (এবং leasing) mechanism প্রয়োগ করি, যাতে একটি নির্দিষ্ট key-এর miss হওয়া data কেবল একবার fetch করা হয়। যদি একই cache key-এ একাধিক request miss করে, তাহলে কেবল একটি request lock নেয় এবং data fetch করে cache update করে। বাকি request গুলো cache update হওয়া পর্যন্ত অপেক্ষা করে, যাতে সবগুলো একই সময়ে PostgreSQL-এ hit না করে। এটি উল্লেখযোগ্যভাবে redundant database read কমায় এবং cascading load spike থেকে সিস্টেমকে রক্ষা করে।

Scaling read replicas

চ্যালেঞ্জ: Primary প্রতিটি read replica-তে Write Ahead Log (WAL) data stream করে। Replica সংখ্যা বাড়ার সঙ্গে primary-কে আরও instance-এ WAL পাঠাতে হয়, যা network bandwidth এবং CPU-এর ওপর চাপ বাড়ায়। এর ফলে replica lag বেড়ে যায় এবং অস্থিতিশীল হয়, যা সিস্টেমকে reliably scale করা কঠিন করে তোলে।

সমাধান: আমরা latency কমানোর জন্য বিভিন্ন geographic region-এ প্রায় ৫০টি read replica চালাই। তবে বর্তমান আর্কিটেকচারে primary-কে প্রতিটি replica-তে WAL stream করতে হয়। যদিও এটি বর্তমানে বড় instance এবং high-network bandwidth-এর সঙ্গে ভালভাবে scale করে, তবে আমরা অনন্তকাল পর্যন্ত replica যুক্ত করতে পারব না, কারণ এতে primary eventually overload হয়ে যাবে।

এই সমস্যার সমাধানে আমরা Azure PostgreSQL টিমের সঙ্গে সহযোগিতা করছি cascading replication নিয়ে, যেখানে intermediate replica গুলো downstream replica-তে WAL relay করে। এই পদ্ধতিতে primary overwhelm না করে শতাধিক replica পর্যন্ত scale করা সম্ভব। তবে এটি additional operational complexity নিয়ে আসে, বিশেষত failover management-এর ক্ষেত্রে। এই feature এখনও testing-এ আছে; production-এ rollout করার আগে আমরা নিশ্চিত করব এটি robust এবং safely failover করতে পারে।

Rate limit

চ্যালেঞ্জ: নির্দিষ্ট এন্ডপয়েন্টে হঠাৎ ট্রাফিক বাড়া, ব্যয়বহুল কুয়েরি বা বারবার পুনরায় চেষ্টা করার ঝুঁকি - দ্রুত গুরুত্বপূর্ণ রিসোর্স যেমন CPU, I/O, এবং কানেকশন শেষ করে দিতে পারে, যা সার্ভিসে বড় ধরনের সমস্যার সৃষ্টি করে।

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

Schema Management

চ্যালেঞ্জ: স্কিমার সামান্য পরিবর্তনও (যেমন কলামের ধরন পরিবর্তন করা) পুরো টেবিলটিকে Rewrite করতে বাধ্য করতে পারে। তাই আমরা অত্যন্ত সতর্কতার সাথে স্কিমা পরিবর্তন করি—শুধুমাত্র lightweight অপারেশনগুলোতে সীমাবদ্ধ থাকি এবং এমন কোনো পরিবর্তন এড়িয়ে চলি যা পুরো টেবিল rewrite ট্রিগার করে।

সমাধান: শুধুমাত্র সাধারণ বা lightweight স্কিমা পরিবর্তনের অনুমতি দেওয়া হয়, যেমন নির্দিষ্ট কিছু কলাম যুক্ত করা বা বাদ দেওয়া যা পুরো টেবিল rewrite এর প্রয়োজন পড়ে না। আমরা স্কিমা পরিবর্তনের ক্ষেত্রে কঠোরভাবে ৫-সেকেন্ডের টাইম-আউট সীমা মেনে চলি। একই সময়ে ইনডেক্স তৈরি বা ডিলিট করার অনুমতি দেওয়া হয়েছে। স্কিমা পরিবর্তন শুধুমাত্র বিদ্যমান টেবিলগুলোর মধ্যেই সীমাবদ্ধ রাখা হয়। যদি কোনো নতুন ফিচারের জন্য বাড়তি টেবিলের প্রয়োজন হয়, তবে সেগুলো PostgreSQL-এর পরিবর্তে বিকল্প শার্ডেড সিস্টেম যেমন Azure CosmosDB-তে রাখতে হবে। টেবিলের কোনো ফিল্ড ব্যাকফিল করার সময়, write spikes রোধ করতে আমরা কঠোর রেট লিমিট প্রয়োগ করি। যদিও এই প্রক্রিয়ায় মাঝে মাঝে এক সপ্তাহের বেশি সময় লাগতে পারে, এটি সিস্টেমের স্থিতিশীলতা নিশ্চিত করে এবং প্রোডাকশনে কোনো নেতিবাচক প্রভাব পড়তে দেয় না।

Results and the road ahead

আমাদের এই প্রচেষ্টা এটিই প্রমাণ করে যে, সঠিক আর্কিটেকচারাল ডিজাইন এবং অপ্টিমাইজেশন থাকলে Azure PostgreSQL ব্যবহার করেই বিশ্বের বৃহত্তম প্রোডাকশন ওয়ার্কলোডগুলো হ্যান্ডেল করা সম্ভব। বর্তমানে আমাদের এই সিস্টেম প্রতি সেকেন্ডে কয়েক মিলিয়ন রিড-হেভি কোয়েরি (QPS) প্রসেস করছে, যা ChatGPT এবং আমাদের API প্ল্যাটফর্মের মতো ক্রিটিক্যাল সার্ভিসগুলোকে নিরবচ্ছিন্ন সাপোর্ট দিচ্ছে। আমরা রেপ্লিকেশন ল্যাগ প্রায় শূন্যে নামিয়ে এনে প্রায় ৫০টি রিড রেপ্লিকা যুক্ত করেছি; ফলে গ্লোবাল রিজিয়নগুলোতে লো-ল্যাটেন্সি নিশ্চিত করার পাশাপাশি ভবিষ্যতের বাড়তি চাপের জন্য পর্যাপ্ত ক্যাপাসিটিও তৈরি করা সম্ভব হয়েছে।

পারফরম্যান্স স্কেলিংয়ের পাশাপাশি আমরা ল্যাটেন্সি কমিয়ে আনা এবং রিলায়েবিলিটি ইমপ্রুভ করার দিকেও সমান গুরুত্ব দিয়েছি। প্রোডাকশনে আমরা কনসিস্টেন্টলি লো ডাবল-ডিজিট মিলিসেকেন্ড p99 ক্লায়েন্ট-সাইড ল্যাটেন্সি এবং 'ফাইভ-নাইনস' (৯৯.৯৯৯%) অ্যাভেইলেবিলিটি বজায় রাখতে সক্ষম হয়েছি। উল্লেখ্য যে, গত ১২ মাসে আমাদের মাত্র একটি SEV-0 পোস্টগ্রেস ইনসিডেন্ট হয়েছে—যা ঘটেছিল ChatGPT ImageGen লঞ্চের সময়, যখন মাত্র এক সপ্তাহে ১০০ মিলিয়নের বেশি নতুন ইউজার যুক্ত হওয়ায় রাইট ট্র্যাফিক হুট করে ১০ গুণেরও বেশি বেড়ে গিয়েছিল।

পোস্টগ্রেস এখন পর্যন্ত আমাদের যেভাবে সাপোর্ট দিয়েছে তাতে আমরা সন্তুষ্ট, তবে ভবিষ্যতের লং-টার্ম গ্রোথ নিশ্চিত করতে আমরা এর সক্ষমতাকে আরও পুশ করছি। যেসব রাইট-হেভি ওয়ার্কলোড সহজেই শার্ডিং করা সম্ভব, সেগুলো আমরা ইতিমধ্যে CosmosDB-র মতো শার্ডেড সিস্টেমে মাইগ্রেট করেছি। বাকি জটিল ওয়ার্কলোডগুলো শার্ড করা কিছুটা চ্যালেঞ্জিং হলেও পোস্টগ্রেস প্রাইমারি ডেটাবেসের ওপর থেকে রাইট লোড কমাতে আমরা সেগুলোও মাইগ্রেট করার কাজ চালিয়ে যাচ্ছি। পাশাপাশি, রিড রেপ্লিকার সংখ্যা নিরাপদে আরও বাড়ানোর লক্ষ্যে আমরা Azure-এর সাথে 'ক্যাসকেডিং রেপ্লিকেশন' এনাবল করার কাজ করছি।

সামনের দিনগুলোতে আমাদের ইনফ্রাস্ট্রাকচারের চাহিদা যত বাড়বে, আমরা শার্ডেড পোস্টগ্রেস কিংবা অল্টারনেটিভ ডিস্ট্রিবিউটেড সিস্টেমের মতো আরও আধুনিক টেকনিক্যাল অ্যাপ্রোচগুলো নিয়ে নিয়মিত কাজ করে যাব।

Scaling PostgreSQL to power 800 million ChatGPT users