समस्या और दायरा
PostgreSQL का उपयोग करने वाला एक ऑर्डर प्लेटफ़ॉर्म 100 स्टेटलेस API इंस्टेंस और 20 बैकग्राउंड वर्कर्स चलाता है। डेटाबेस में max_connections को 500 पर सेट किया गया है। माइग्रेशन, घटना प्रतिक्रिया (incident response), और परिचालन टूल्स के लिए 50 के रिज़र्व की आवश्यकता होती है, जिससे पूरे एप्लिकेशन के लिए 450 कनेक्शन का बजट बचता है। पीक ट्रैफ़िक 6,000 अनुरोध प्रति सेकंड है, लगभग 70% अनुरोध डेटाबेस को एक्सेस करते हैं, और एप्लिकेशन ट्रेस दिखाते हैं कि एक डेटाबेस ऑपरेशन औसतन 40 मिलीसेकंड के लिए कनेक्शन रखता है। API अनुरोधों के लिए एंड-टू-एंड p99 लक्ष्य 800 मिलीसेकंड है।
वर्तमान में प्रत्येक प्रोसेस का पूल 10 का है, इसलिए यह डिप्लॉयमेंट सैद्धांतिक रूप से 100 × 10 + 20 × 10 = 1,200 डेटाबेस सत्र बना सकता है। पीक के समय कनेक्शन अधिग्रहण का टाइमआउट शुरू हो जाता है। कभी-कभी डेटाबेस CPU केवल 55% होता है; अन्य समय में, लॉक प्रतीक्षा और क्वेरी विलंबता (latency) भी बढ़ जाती है। एक प्रारंभिक पूल आवंटन, टाइमआउट नीति, और कनेक्शन जीवनचक्र डिज़ाइन करें। बताएं कि एक कम आकार के स्थानीय पूल, कनेक्शन लीक, लंबे ट्रांज़ैक्शन, बजट से परे रेप्लिका स्केलिंग, और डेटाबेस के अंदर ओवरलोड में कैसे अंतर किया जाए।
इंस्टेंस की संख्या, थ्रूपुट, 40-मिलीसेकंड होल्ड समय, और 500-कनेक्शन की सीमा साक्षात्कार की मान्यताएं हैं, PostgreSQL, HikariCP, या PgBouncer के लिए सार्वभौमिक प्रदर्शन के दावे नहीं। वर्तमान बैकएंड साक्षात्कार मार्गदर्शन अभी भी सिस्टम डिज़ाइन में प्रदर्शन, विश्वसनीयता, और परिचालन विचारों का मूल्यांकन करता है, और 2026 में एक समर्पित डेटाबेस कनेक्शन-पूल डिज़ाइन प्रश्न प्रकाशित किया गया था। मुख्य कौशल एप्लिकेशन रेप्लिका के बीच डेटाबेस समवर्तीता और संसाधन स्वामित्व का प्रबंधन करना है, इसलिए यह श्रेणी बैकएंड है।
इंटरव्यूअर क्या मूल्यांकन कर रहा है
पहला संकेत पूल को समवर्ती प्रवेश नियंत्रण (concurrency admission control) के रूप में देखना है, यह न मानकर कि अधिक कनेक्शन से अधिक थ्रूपुट प्राप्त होता है। PostgreSQL का max_connections पूरे डेटाबेस के लिए होता है, और इसे बढ़ाने से संसाधन आवंटन बढ़ता है। एक इंस्टेंस पर स्वतंत्र रूप से कॉन्फ़िगर की गई संख्या को API रेप्लिका, वर्कर्स, शेड्यूल्ड जॉब्स और रोलिंग रिलीज़ के दौरान अस्थायी रेप्लिका से गुणा किया जाना चाहिए।
दूसरा संकेत Little के नियम का उपयोग परिमाण-क्रम (order-of-magnitude) की जांच के लिए करना है, बिना किसी औसत को क्षमता के उत्तर के रूप में प्रस्तुत किए। औसत डेटाबेस आगमन दर 6,000 × 70% = 4,200 ऑपरेशंस प्रति सेकंड है। औसत कनेक्शन ऑक्यूपेंसी लगभग 4,200 × 0.04 = 168 है। यह केवल स्थिर-अवस्था (steady-state) औसत समवर्तीता का वर्णन करता है। बर्स्ट्स, p99 होल्ड समय, लॉक प्रतीक्षा, ट्रांज़ैक्शन पुनरावृत्ति (retries), और रेप्लिका के बीच लोड असंतुलन के लिए अभी भी माप और लोड परीक्षणों की आवश्यकता है।
तीसरा संकेत दोनों पक्षों के साक्ष्यों के साथ कतार का पता लगाना है। एप्लिकेशन को सक्रिय, निष्क्रिय (idle), और लंबित (pending) संख्या, अधिग्रहण विलंबता और टाइमआउट, तथा कनेक्शन होल्ड समय को प्रदर्शित करना चाहिए। डेटाबेस को pg_stat_activity स्थिति, wait_event, सक्रिय प्रश्न, निष्क्रिय ट्रांज़ैक्शन, और कनेक्शन का स्रोत प्रदर्शित करना चाहिए। पूल को इसलिए बढ़ाना क्योंकि "कनेक्शन अधिग्रहण का समय समाप्त हो गया" केवल कतार को एप्लिकेशन से डेटाबेस में स्थानांतरित कर सकता है।
अंत में, उत्तर में विफलता की सीमाओं को परिभाषित किया जाना चाहिए। एक मजबूत डिज़ाइन अनुरोध की समय-सीमा (request deadlines), कनेक्शन लीक, लंबे ट्रांज़ैक्शन, रोलिंग रिलीज़, ऑटोस्केलिंग, डेटाबेस पुनरारंभ, पुराने कनेक्शन, और PgBouncer सत्र व ट्रांज़ैक्शन पूलिंग के बीच के अंतर को कवर करता है। यह उन सत्र-विशिष्ट (session-scoped) सुविधाओं को भी नामित करता है जो ट्रांज़ैक्शन पूलिंग के साथ सुरक्षित नहीं हो सकती हैं।
उत्तर देने से पहले स्पष्टीकरण हेतु प्रश्न
- क्या 500 की सीमा एक प्राइमरी पर लागू होती है या एक बड़े क्लस्टर पर? रीड रेप्लिका, फेलओवर लक्ष्य, और परिचालन
एक्सेस के अलग-अलग बजट हो सकते हैं। उन डेटाबेस के लिए अलग से पूल की गणना करें जो वास्तव में प्रत्येक वर्कलोड को पूरा करते हैं।
- अधिकतम रेप्लिका संख्या क्या है? क्या 100 API इंस्टेंस सामान्य हैं या ऑटोस्केलिंग की अधिकतम सीमा? एक रोलिंग रिलीज़
अस्थायी रूप से पुराने और नए रेप्लिका को एक साथ चला सकती है। केवल स्थिर-अवस्था रेप्लिका पर आधारित कॉन्फ़िगरेशन किसी रिलीज़ या घटना के दौरान बजट से अधिक हो सकता है।
- कनेक्शन होल्ड समय का वितरण क्या है? 40 मिलीसेकंड का औसत p95, p99, ट्रांज़ैक्शन के अंदर नेटवर्क
कॉल, या लॉक प्रतीक्षा को नहीं दिखाता है। लंबी पूंछ (long tail) कतारबद्धता और टाइमआउट को नियंत्रित करती है, इसलिए इसे रूट, टास्क, और ट्रांज़ैक्शन लेबल द्वारा विभाजित करें।
- क्या बैकग्राउंड कार्य कतारबद्ध हो सकता है या समवर्तीता को सीमित कर सकता है? लंबी बैच नौकरियों को छोटे API
अनुरोधों के साथ स्वतंत्र रूप से प्रतिस्पर्धा नहीं करनी चाहिए। अलग-अलग पूल उपयोगी हैं, लेकिन प्रत्येक पूल अभी भी 450 के समान वैश्विक बजट को साझा करता है।
- टाइमआउट के बाद क्या रिट्राई होते हैं? बिना बैकऑफ़ के तत्काल रिट्राई ठीक उसी समय आगमन दर को बढ़ा देते हैं जब
डेटाबेस धीमा हो जाता है। अधिग्रहण टाइमआउट अनुरोध की समय-सीमा के भीतर फिट होना चाहिए और प्रवेश नियंत्रण, बैकऑफ़, या एक परिभाषित विफलता प्रतिक्रिया के साथ काम करना चाहिए।
- एप्लिकेशन कौन-सी सत्र-विशिष्ट (session-scoped) सुविधाओं का उपयोग करता है? अस्थायी टेबल,
LISTEN, सत्र सलाहकार लॉक (advisory locks),
क्रॉस-ट्रांज़ैक्शन SET स्थिति, और prepared-statement का व्यवहार इस बात को प्रभावित करते हैं कि क्या PgBouncer ट्रांज़ैक्शन पूलिंग सुरक्षित है।
- कनेक्शन प्रॉक्सी कहाँ चलेगी? एक PgBouncer इंस्टेंस एक क्षमता और उपलब्धता सीमा बनाता है।
प्रति-नोड साइडकार्स, एक समर्पित प्रॉक्सी टियर, और एक प्रबंधित प्रॉक्सी के अलग-अलग विफलता मोड होते हैं।
30-सेकंड उत्तर रूपरेखा
"मैं एक वैश्विक बजट के साथ शुरुआत करूँगा। 500 में से 50 कनेक्शन आरक्षित करने पर अनुप्रयोगों के लिए 450 शेष बचते हैं; वर्तमान प्रति-प्रक्रिया सीमा बढ़कर 1,200 हो जाती है। 168 की औसत समवर्तीता केवल एक स्केल जांच है। एक प्रारंभिक आवंटन प्रत्येक API इंस्टेंस को 2 और प्रत्येक वर्कर को 4 दे सकता है, जो 170 के हेडरूम के साथ कुल 280 होता है, फिर पीक लोड के तहत इसे ट्यून करें। अधिग्रहण टाइमआउट 800-मिलीसेकंड के अनुरोध की समय-सीमा के भीतर होना चाहिए। मैं पूल की लंबित संख्या, अधिग्रहण विलंबता, और होल्ड समय की तुलना pg_stat_activity और प्रतीक्षा घटनाओं से करूँगा। यदि पूल कतारबद्ध होता है जबकि डेटाबेस में हेडरूम है, तो विषमता (skew), लीक, और स्थानीय सीमाओं का निरीक्षण करें। यदि क्वेरी या लॉक पहले से ही ख़राब हो रहे हैं, तो पूल का आकार न बढ़ाएं। ऑटोस्केलिंग को बजट की पुनर्गणना करनी चाहिए, और PgBouncer ट्रांज़ैक्शन पूलिंग के लिए एक सत्र-स्थिति ऑडिट की आवश्यकता होती है।"
चरण-दर-चरण गहन विश्लेषण
एक वैश्विक कनेक्शन बजट स्थापित करें
बजट को एक स्पष्ट इनवेरिएंट (invariant) के रूप में लिखें:
application_connection_cap
= max_connections
- operations_reserve
= 500 - 50
= 450सभी API, वर्कर, माइग्रेशन, प्रशासन, और रोलिंग-रिलीज़ पूल सीमाओं का योग 450 या उससे कम रहना चाहिए। यदि अन्य एप्लिकेशन उसी डेटाबेस का उपयोग करते हैं, तो उनके बजट को भी घटाएं। ऑपरेशंस रिज़र्व सामान्य ट्रैफ़िक के लिए अतिरिक्त थ्रूपुट नहीं है। यह किसी घटना के दौरान डेटाबेस से कनेक्ट करने, निरीक्षण करने और मरम्मत करने की क्षमता को सुरक्षित रखता है।
औसत समवर्तीता जांच है:
database_arrival_rate = 6,000 × 70% = 4,200 operations/second
average_in_flight = 4,200 × 0.04 seconds = 168यह तुरंत दिखाता है कि 1,200 कनेक्शन औसत वर्कलोड द्वारा उचित नहीं हैं और कुल 20 कनेक्शन संभवतः बहुत कम हैं। यह अंतिम पूल आकार का उत्पादन नहीं करता है क्योंकि औसत बर्स्ट्स, p99 होल्ड समय, ट्रांज़ैक्शन रिट्राई, और कतारबद्धता प्रतिक्रिया को छिपाते हैं। अंतिम संख्या को सेवा SLO, टिकाऊ सक्रिय डेटाबेस समवर्तीता, और लोड परीक्षणों को संयोजित करना चाहिए।
एक प्रारंभिक आवंटन प्रस्तावित करें जिसका परीक्षण किया जा सके
एक रूढ़िवादी प्रारंभिक बिंदु प्रति API इंस्टेंस 2 कनेक्शन और प्रति वर्कर 4 है:
API cap = 100 × 2 = 200
worker cap = 20 × 4 = 80
allocated = 280
app headroom = 450 - 280 = 1704 का वर्कर आवंटन केवल एक प्रारंभिक पृथक सीमा है, ऐसा मान नहीं जो सीधे "लंबे जॉब्स" से आता हो। वास्तविक मान प्रत्येक वर्कलोड के होल्ड-समय वितरण, आगमन दर, और समवर्तीता सीमा का पालन करने चाहिए। दो सौ अस्सी एक उम्मीदवार है जो वैश्विक बजट का सम्मान करता है और जिसका लोड-परीक्षण किया जा सकता है; शेष 170 को स्वचालित रूप से आवंटित नहीं किया जाना चाहिए। यदि API रेप्लिका बढ़कर 200 हो जाती हैं, तो प्रति रेप्लिका 2 रखने से 400 की खपत होती है, और वर्कर्स के 80 कुल मिलाकर 450 से अधिक हो जाते हैं। स्केलिंग को प्रति-इंस्टेंस सीमा को कम करना चाहिए, अधिकतम रेप्लिका को सीमित करना चाहिए, या अधिक केंद्रीकृत सर्वर-कनेक्शन बजट लागू करने के लिए प्रॉक्सी का उपयोग करना चाहिए।
केवल इसलिए एक बड़ा minimumIdle सेट न करें ताकि प्रत्येक प्रक्रिया के पास हमेशा अतिरिक्त कनेक्शन हों। निष्क्रिय सत्र अभी भी वैश्विक सीमा का उपभोग करते हैं। एक पूल आवश्यकतानुसार एक कठिन अधिकतम (hard maximum) तक बढ़ सकता है। क्या इसे न्यूनतम संख्या में निष्क्रिय कनेक्शन बनाए रखने चाहिए, यह मापे गए कनेक्शन-स्थापना लागत और बर्स्ट विलंबता द्वारा उचित होना चाहिए।
अधिग्रहण टाइमआउट और कनेक्शन जीवनकाल सेट करें
अधिग्रहण टाइमआउट शेष अनुरोध की समय-सीमा से कम होना चाहिए। 800-मिलीसेकंड के p99 लक्ष्य के साथ, एक थ्रेड कनेक्शन के लिए 30 सेकंड तक प्रतीक्षा नहीं कर सकता है। एक पहला परीक्षण अधिग्रहण को 100 से 200 मिलीसेकंड दे सकता है और इसे मापे गए कतार वितरण से समायोजित कर सकता है। वह सीमा एक परिदृश्य डिज़ाइन विकल्प है, न कि एक सार्वभौमिक लाइब्रेरी अनुशंसा। टाइमआउट के बाद, एक पहचानने योग्य ओवरलोड त्रुटि लौटाएं और अपस्ट्रीम प्रवेश नियंत्रण या जिटर बैकऑफ़ का उपयोग करें। बिना किसी सीमा के तुरंत पुनः प्रयास न करें।
अधिकतम कनेक्शन जीवनकाल डेटाबेस, प्रॉक्सी, या नेटवर्क द्वारा लगाए गए किसी भी जबरन जीवनकाल से छोटा होना चाहिए, और इसमें जिटर शामिल होना चाहिए ताकि कई कनेक्शन एक साथ समाप्त न हों। कीपअलाइव (Keepalive) एक निष्क्रिय कनेक्शन के लिए है जिसे वैध रहना चाहिए और इसे अधिकतम जीवनकाल की तुलना में अधिक बार चलना चाहिए। प्रत्येक कनेक्शन को उधार लेने से पहले परीक्षण करने से एक राउंड ट्रिप जुड़ती है और इसके लिए माप की आवश्यकता होती है। इससे भी महत्वपूर्ण बात यह है कि डेटाबेस पुनरारंभ या फेलओवर के बाद पहले विफल ऑपरेशन को सही ढंग से संभालें और केवल आइडेम्पोटेंट व्यावसायिक संचालन का पुनः प्रयास करें।
निर्धारित करें कि क्या एप्लिकेशन पूल बाधा (bottleneck) है
प्रत्येक पूल को सेवा, इंस्टेंस और वर्कलोड लेबल के साथ कम से कम इन मेट्रिक्स को प्रदर्शित करना चाहिए:
- कॉन्फ़िगर किया गया अधिकतम, सक्रिय, निष्क्रिय, और लंबित;
- p50, p95, और p99 अधिग्रहण विलंबता और टाइमआउट गणना;
- रूट, टास्क या ट्रांज़ैक्शन द्वारा टैग किया गया कनेक्शन होल्ड समय;
- कनेक्शन निर्माण, बंद, विफल सत्यापन, और पुनर्निर्माण दरें;
- सैद्धांतिक कुल सीमा: कॉन्फ़िगर किया गया पूल अधिकतम गुणा वर्तमान रेप्लिका गणना।
संयोजनों की व्याख्या करें, पृथक मूल्यों की नहीं। बढ़ती लंबित संख्या और अधिग्रहण विलंबता के साथ सक्रिय कनेक्शन सीमा पर पिन किए गए हैं, जबकि डेटाबेस में अभी भी टिकाऊ सक्रिय-कनेक्शन और CPU हेडरूम है, यह एक छोटे स्थानीय पूल, विषम ट्रैफ़िक, या कनेक्शन को बहुत लंबे समय तक रखने वाले कुछ ऑपरेशनों का संकेत दे सकता है। यदि अनुरोध समाप्त होने के बाद सक्रिय उधार कभी नहीं गिरते हैं, या एप्लिकेशन कोड में स्टैक बने रहते हैं, तो हो सकता है कि कनेक्शन वापस न किया गया हो। कनेक्शन निर्माण और बंद होने में अचानक वृद्धि जीवनकाल बेमेल, प्रॉक्सी टाइमआउट, या नेटवर्क समस्या का संकेत दे सकती है।
संरचित कनेक्शन स्कोप का उपयोग करें ताकि सफलता, त्रुटि, रद्दीकरण, और प्रारंभिक-वापसी (early-return) पथ सभी कनेक्शन को छोड़ दें। लीक डिटेक्शन थ्रेशोल्ड किसी पथ का पता लगाने में मदद कर सकते हैं, लेकिन वे होल्ड-टाइम वितरण और कोड समीक्षा की जगह नहीं लेते हैं। एक थ्रेशोल्ड जो बहुत छोटा है, वैध लंबे ट्रांज़ैक्शन को लीक के रूप में लेबल करेगा।
डेटाबेस ओवरलोड को अलग करने के लिए PostgreSQL साक्ष्य का उपयोग करें
PostgreSQL प्रति सर्वर प्रक्रिया एक pg_stat_activity पंक्ति को उजागर करता है। इसे application_name, क्लाइंट एड्रेस, स्थिति, और प्रतीक्षा घटना द्वारा समूहित करें। इसके साथ प्रारंभ करें:
SELECT application_name, state, wait_event_type, wait_event, count(*)
FROM pg_stat_activity
WHERE datname = current_database()
GROUP BY application_name, state, wait_event_type, wait_event
ORDER BY count(*) DESC;फिर उन सत्रों को खोजें जो ट्रांज़ैक्शन के अंदर निष्क्रिय रहते हैं:
SELECT pid, application_name, xact_start, state_change, wait_event_type, wait_event
FROM pg_stat_activity
WHERE state = 'idle in transaction'
ORDER BY xact_start;यदि सक्रिय सत्र, क्वेरी विलंबता, लॉक प्रतीक्षा, या I/O कनेक्शन संख्या बढ़ने के साथ खराब होते हैं, तो बाधा प्रश्नों, ट्रांज़ैक्शन या डेटाबेस संसाधनों में है। पूल को बड़ा करने से विवाद (contention) बढ़ता है। यदि डेटाबेस 500 सत्रों के करीब है लेकिन कई निष्क्रिय एप्लिकेशन सत्र हैं, तो प्रति-इंस्टेंस निष्क्रिय पूल्स ने बजट का उपभोग कर लिया है; उन्हें छोटा करें या मल्टीप्लेक्सिंग पेश करें। यदि idle in transaction बना रहता है, तो ट्रांज़ैक्शन सीमाओं की मरम्मत करें क्योंकि वे सत्र एक कनेक्शन का उपभोग करते हैं और लॉक बनाए रख सकते हैं या वैक्यूम प्रगति को रोक सकते हैं।
कुल सत्र समानांतर निष्पादन के समान नहीं हैं। निष्क्रिय सत्र और लॉक की प्रतीक्षा कर रहे सत्रों के लिए अलग-अलग स्पष्टीकरण की आवश्यकता होती है। 55% पर CPU अतिरिक्त डेटाबेस क्षमता साबित नहीं करता है: लॉक विवाद, स्टोरेज विलंबता, एक हॉट पार्टीशन, या एक सीरियल निष्पादन पथ कम कुल CPU पर भी कार्य को अवरुद्ध कर सकता है।
वर्कलोड को अलग करें और स्केलिंग का ध्यान रखें
जब छोटे API अनुरोध और लंबे वर्कर्स एक पूल साझा करते हैं, तो कुछ बैच जॉब्स हेड-ऑफ-लाइन ब्लॉकिंग का कारण बन सकते हैं। उन्हें अलग पूल और अलग समवर्ती कतारें दें, जैसे कि इस परिदृश्य में 200/80 का विभाजन। अलगाव विलंबता की रक्षा करता है; यह एक बड़ा बजट नहीं बनाता है। एक वर्कर पूल को निष्क्रिय होने पर सिकुड़ने की अनुमति दी जानी चाहिए, और नौकरियों को स्वयं एक समवर्ती सीमा की आवश्यकता होती है।
ऑटोस्केलर को डेटाबेस बजट का पता होना चाहिए। सबसे सरल कठिन बाधा है:
max_replicas × pool_size_per_replica + other_pool_caps <= 450रोलिंग डिप्लॉयमेंट maxSurge शामिल करें। यदि रेप्लिका गणना व्यापक रूप से बदलती है, तो एक निश्चित प्रति-इंस्टेंस सीमा कुछ रेप्लिका के साथ क्षमता बर्बाद करती है और कई के साथ बजट से अधिक हो जाती है। एक छोटे निश्चित पूल प्लस अनुरोध कतारबद्धता का उपयोग करें, या नियंत्रित संख्या में सर्वर कनेक्शन पर कई क्लाइंट सत्रों को मल्टीप्लेक्स करने के लिए PgBouncer का उपयोग करें। दोनों ही मामलों में, डेटाबेस के अंदर सक्रिय समवर्तीता को सीमित करना जारी रखें।
तय करें कि क्या PgBouncer का उपयोग करना है
PgBouncer सत्र पूलिंग क्लाइंट सत्र समाप्त होने तक उसी सर्वर कनेक्शन को बनाए रखता है। यह PostgreSQL सत्र व्यवहार का अच्छी तरह से समर्थन करता है लेकिन कम मल्टीप्लेक्सिंग प्रदान करता है। ट्रांज़ैक्शन पूलिंग केवल एक ट्रांज़ैक्शन की अवधि के लिए एक सर्वर कनेक्शन प्रदान करती है। यह निष्क्रिय क्लाइंट्स को सर्वर कनेक्शन रखने से रोक सकता है, लेकिन यह इस धारणा को हटा देता है कि अगला ट्रांज़ैक्शन उसी सर्वर सत्र का उपयोग करता है।
ट्रांज़ैक्शन पूलिंग से पहले, क्रॉस-ट्रांज़ैक्शन SET/RESET, LISTEN, सत्र सलाहकार लॉक, अस्थायी टेबल, और अन्य सत्र स्थिति का ऑडिट करें। यदि एप्लिकेशन को उन सेमेन्टिक्स की आवश्यकता है, तो सत्र पूलिंग बनाए रखें, चयनित पथों को एक अलग प्रत्यक्ष पूल दें, या स्थिति को एक ट्रांज़ैक्शन के अंदर स्थानांतरित करें। केवल कम कनेक्शन संख्या ही सफलता सिद्ध नहीं करती है। प्रॉक्सी कतारबद्धता, प्रॉक्सी विफलता, प्रमाणीकरण, कनेक्शन पुनर्निर्माण, और डेटाबेस फेलओवर का परीक्षण करें।
विफलता परीक्षणों के साथ क्षमता लूप को बंद करें
क्रमबद्ध लोड के साथ शुरुआत करें, प्रति सेकंड 6,000 अनुरोधों की ओर बढ़ें, फिर बर्स्ट्स और ऑटोस्केलिंग जोड़ें। प्रत्येक चरण पर एंड-टू-एंड p95/p99, अधिग्रहण विलंबता, लंबित गणना, होल्ड समय, सक्रिय डेटाबेस सत्र, लॉक प्रतीक्षा, क्वेरी विलंबता, CPU, और I/O रिकॉर्ड करें। प्रारंभिक 200/80 विभाजन के आसपास कई उम्मीदवार आवंटनों की तुलना करें और पता लगाएं कि थ्रूपुट कहाँ बढ़ना बंद हो जाता है या डेटाबेस विलंबता और कतारबद्धता खराब होने लगती है।
प्रतिकूल परीक्षणों में एक इंजेक्टेड पथ शामिल होना चाहिए जो कनेक्शन वापस नहीं करता है, कई ट्रांज़ैक्शन जो कनेक्शन को सेकंडों के लिए रखते हैं, लॉक विवाद, रोलिंग रिलीज़ के दौरान चलने वाले पुराने और नए रेप्लिका, एक डेटाबेस पुनरारंभ, मौजूदा सर्वर कनेक्शन को छोड़ने वाला एक प्रॉक्सी, और वर्कर बैकलॉग का एक बर्स्ट। पास होने का मतलब "कोई त्रुटि नहीं" नहीं है। वैश्विक कनेक्शन बजट के तहत, सिस्टम को तेजी से विफल होना चाहिए या लोड कम करना चाहिए, मेट्रिक्स को कतार की पहचान करनी चाहिए, और पुनर्प्राप्ति को एक कनेक्शन तूफान नहीं बनाना चाहिए।
उच्च गुणवत्ता वाला नमूना उत्तर
"मैं प्रति-इंस्टेंस संख्या चुनने से पहले 500 डेटाबेस कनेक्शन को बजट में विभाजित करूँगा। संचालन के लिए 50 आरक्षित करने से अनुप्रयोगों के लिए 450 शेष बचते हैं। वर्तमान 120 प्रक्रियाएं 10 प्रत्येक के साथ 1,200 की सैद्धांतिक सीमा बनाती हैं, इसलिए रोलिंग रिलीज़ और बर्स्ट डेटाबेस सीमा से अधिक हो सकते हैं।
प्रॉम्प्ट प्रति सेकंड 4,200 डेटाबेस ऑपरेशन और 40-मिलीसेकंड का औसत होल्ड समय देता है। Little का नियम लगभग 168 औसत समवर्ती संचालन देता है। मैं इसका उपयोग केवल एक स्केल जांच के रूप में करूँगा, p99 क्षमता के रूप में नहीं। एक प्रारंभिक आवंटन 100 API रेप्लिका में से प्रत्येक को 2 कनेक्शन और 20 वर्कर्स में से प्रत्येक को 4 दे सकता है, जो कुल 280 होता है और एप्लिकेशन हेडरूम के 170 कनेक्शन छोड़ता है। मैं वास्तविक होल्ड-टाइम वितरण, बर्स्ट्स और लॉक विवाद के साथ 280 के आसपास के उम्मीदवारों का लोड-परीक्षण करूँगा। ऑटोस्केलिंग अधिकतम और रोलिंग-रिलीज़ रेप्लिका सूत्र में शामिल हैं; अन्यथा 200 API रेप्लिका प्लस वर्कर पूल 450 से अधिक हो जाते हैं।
अधिग्रहण टाइमआउट 800-मिलीसेकंड के अनुरोध की समय-सीमा के भीतर होना चाहिए। मैं 100 से 200 मिलीसेकंड का परीक्षण करके शुरुआत करूँगा। एप्लिकेशन की ओर से मैं सक्रिय, निष्क्रिय, लंबित, अधिग्रहण विलंबता, टाइमआउट गणना, होल्ड समय, और कनेक्शन पुनर्निर्माण की निगरानी करूँगा। PostgreSQL में मैं एप्लिकेशन नाम से pg_stat_activity को समूहित करूँगा और सक्रिय, निष्क्रिय, निष्क्रिय-इन-ट्रांज़ैक्शन, और प्रतीक्षा घटनाओं का निरीक्षण करूँगा। यदि डेटाबेस में टिकाऊ हेडरूम होने पर पूल कतारबद्ध होता है, तो रेप्लिका विषमता, स्थानीय सीमा, और अप्रयुक्त (unreleased) कनेक्शन का निरीक्षण करें। यदि प्रश्न, लॉक, या I/O पहले से ही ख़राब हो रहे हैं, तो एक बड़ा पूल केवल डेटाबेस समवर्तीता को बढ़ाता है। यदि max_connections के पास अधिकांश सत्र निष्क्रिय हैं, तो प्रति-इंस्टेंस निष्क्रिय पूल को छोटा करें या उन्हें प्रॉक्सी के माध्यम से मल्टीप्लेक्स करें।
मैं छोटे API और लंबे वर्कर्स को उनके योग को 450 के तहत रखते हुए अलग-अलग पूल और समवर्ती सीमाओं के साथ अलग करूँगा। यदि PgBouncer की आवश्यकता है, तो मैं मोड को जानबूझकर चुनूंगा: सत्र पूलिंग अधिक अनुकूलता बनाए रखती है; ट्रांज़ैक्शन पूलिंग अधिक आक्रामक रूप से मल्टीप्लेक्स करती है लेकिन इसके लिए LISTEN, सत्र सलाहकार लॉक, अस्थायी टेबल, और क्रॉस-ट्रांज़ैक्शन SET के ऑडिट की आवश्यकता होती है। अंत में, मैं चरणबद्ध लोड, बर्स्ट्स, एक लीक, लंबे ट्रांज़ैक्शन, लॉक विवाद, रोलिंग डिप्लॉयमेंट, डेटाबेस पुनरारंभ, और प्रॉक्सी डिस्कनेक्ट के साथ p99, कतारबद्धता, कुल कनेक्शन, और पुनर्प्राप्ति को मान्य करूँगा।"
सामान्य गलतियाँ
- प्रत्येक इंस्टेंस को 20 कनेक्शन सौंपना → रेप्लिका संख्या बदलने पर कुल सत्र अनियंत्रित हो जाते हैं →
पहले डेटाबेस-व्यापी बजट को परिभाषित करें और इसे सभी पूल्स और अधिकतम रेप्लिका के बीच विभाजित करें।
- औसत से ठीक 168 कनेक्शन कॉन्फ़िगर करना → बर्स्ट्स, p99 होल्ड समय, लॉक प्रतीक्षा, और आवंटन ग्रैन्युलैरिटी
गायब हैं → Little के नियम का उपयोग स्केल जांच के रूप में करें, फिर वितरण और लोड परीक्षणों के साथ निर्णय लें।
- जब भी अधिग्रहण का समय समाप्त हो, पूल बढ़ाएं → एप्लिकेशन कतार डेटाबेस लॉक, I/O, या CPU
कतारों में जा सकती है → पूल लंबित और डेटाबेस सक्रिय सत्रों, प्रतीक्षा घटनाओं, और क्वेरी विलंबता का एक साथ निरीक्षण करें।
- केवल डेटाबेस CPU को देखना → लॉक, स्टोरेज विलंबता, और हॉट स्पॉट कम CPU पर कनेक्शन को ब्लॉक कर सकते हैं →
स्थिति और प्रतीक्षा घटना द्वारा सत्रों की व्याख्या करें।
- निष्क्रिय कनेक्शनों पर ध्यान न देना → कई रेप्लिका में निष्क्रिय पूल पहले
max_connectionsको समाप्त कर सकते हैं →
पूल कैप गुणा रेप्लिका गणना की निगरानी करें और न्यूनतम निष्क्रिय को नियंत्रित करें।
- Idle-in-transaction को सामान्य idle मानना → ट्रांज़ैक्शन लॉक रख सकता है, पुराना स्नैपशॉट बनाए रख सकता है, और
सफाई में बाधा डाल सकता है → ट्रांज़ैक्शन प्रारंभ और कोड सीमाओं का पता लगाएं और उचित टाइमआउट लागू करें।
- प्रत्येक वर्कलोड को एक पूल में रखना → लंबे वर्कर्स उन कनेक्शनों पर कब्जा कर लेते हैं जिनकी छोटे API को आवश्यकता होती है →
वैश्विक बजट से अधिक किए बिना विलंबता प्रोफ़ाइल द्वारा पूल्स और कतारों को अलग करें।
- PgBouncer को अपनाना और डिफ़ॉल्ट रूप से ट्रांज़ैक्शन पूलिंग करना → सत्र की स्थिति ट्रांज़ैक्शन के बीच गायब हो सकती है या
अन्य सर्वर कनेक्शन पर उतर सकती है → पूलिंग मोड का चयन करने से पहले संगतता का ऑडिट करें।
- सभी कनेक्शन त्रुटियों को तुरंत पुनः प्रयास करना → डेटाबेस पुनर्प्राप्ति को कनेक्शन तूफान और उच्च आगमन दर का सामना करना पड़ता है →
रिट्राई सीमित करें, जिटरेड बैकऑफ़ जोड़ें, और केवल आइडेम्पोटेंट संचालन का पुनः प्रयास करें।
- केवल स्थिर अवस्था का परीक्षण करना → रोलिंग रिलीज़, स्केलिंग, लंबे ट्रांज़ैक्शन, और डेटाबेस पुनरारंभ बजट और
जीवनचक्र विफलताओं को उजागर करते हैं → उन्हें स्वीकृति मैट्रिक्स में शामिल करें।
अनुवर्ती प्रश्न
अनुवर्ती 1: अधिक कनेक्शन सिस्टम को धीमा क्यों बना सकते हैं?
डेटाबेस CPU, कैश, लॉक, और स्टोरेज बैंडविड्थ सीमित हैं। टिकाऊ सक्रिय समवर्तीता से परे, अधिक कनेक्शन कॉन्टेक्स्ट स्विचिंग, कैश विवाद, और लॉक प्रतीक्षा को बढ़ाते हैं। प्रत्येक क्वेरी धीमी हो जाती है, जिससे कनेक्शन होल्ड समय बढ़ जाता है और सकारात्मक प्रतिक्रिया (positive feedback) बनती है। एक छोटा पूल एप्लिकेशन में बंधी हुई कतार प्रदान करता है, जिसे प्रत्येक अनुरोध को डेटाबेस में प्रवेश करने की अनुमति देने की तुलना में नियंत्रित करना आमतौर पर आसान होता है। पूल अभी भी इतना छोटा नहीं होना चाहिए कि यह टिकाऊ डेटाबेस क्षमता को अप्रयुक्त छोड़ दे।
अनुवर्ती 2: यदि API 200 इंस्टेंस तक स्केल हो जाए तो क्या बदलता है?
प्रति इंस्टेंस 2 कनेक्शन रखने से 400 API कनेक्शन बनेंगे; वर्कर्स के 80 कुल मिलाकर 450 से अधिक हो जाएंगे। प्रत्येक API पूल को घटाकर 1 करें और वर्कर बजट को पुन: आवंटित करें, अधिकतम रेप्लिका और रोलिंग-रिलीज़ सर्ज को सीमित करें, या PgBouncer के साथ क्लाइंट्स को मल्टीप्लेक्स करें। निर्णय के लिए बर्स्ट कतारबद्धता और टिकाऊ डेटाबेस समवर्ती परीक्षणों का उपयोग करें। एक ऑटोस्केलर डाउनस्ट्रीम डेटाबेस क्षमता की अनदेखी करते हुए केवल CPU को नहीं देख सकता है।
अनुवर्ती 3: आप वास्तव में धीमी क्वेरी के बजाय लीक को कैसे सिद्ध करते हैं?
एक लीक अक्सर सक्रिय उधार के रूप में प्रकट होता है जो केवल बढ़ता है, लगातार लंबित अनुरोध, और एक अनुरोध जो पहले ही समाप्त हो चुका है जबकि उसका डेटाबेस सत्र निष्क्रिय हो सकता है। प्रत्येक उधार को रूट, टास्क, और नमूना स्टैक के साथ संबद्ध करें; अनुरोध जीवनकाल के साथ होल्ड समय की तुलना करें; और अपवाद, रद्दीकरण, और प्रारंभिक-वापसी पथों का निरीक्षण करें। यदि PostgreSQL सत्र सक्रिय रहता है या किसी लॉक पर प्रतीक्षा करता है, तो इसे लीक के रूप में लेबल करने से पहले क्वेरी और ट्रांज़ैक्शन की व्याख्या करें।
अनुवर्ती 4: क्या आप HikariCP के पूल-आकार सूत्र को सीधे लागू कर सकते हैं?
(core_count × 2) + effective_spindle_count HikariCP के दस्तावेज़ीकरण में एक प्रारंभिक अनुमान (heuristic) है, जो स्पष्ट रूप से इसके आसपास लोड-परीक्षण करने के लिए कहता है। SSDs, कैश हिट दर, क्वेरी प्रकार, और एक रिमोट डेटाबेस परिणाम को बदलते हैं। इससे भी महत्वपूर्ण बात यह है कि जब एक डेटाबेस कई एप्लिकेशन रेप्लिका द्वारा साझा किया जाता है, तो किसी भी डेटाबेस-स्तरीय उम्मीदवार को अभी भी उनके बीच विभाजित किया जाना है। यह सूत्र 450 के वैश्विक बजट या वास्तविक SLO साक्ष्य की जगह नहीं ले सकता है।
अनुवर्ती 5: क्या PgBouncer ट्रांज़ैक्शन पूलिंग के साथ Prepared Statements हमेशा असमर्थित होते हैं?
प्रत्येक संस्करण और कॉन्फ़िगरेशन में कोई पूर्ण दावा न करें। परिनियोजित संस्करण, प्रोटोकॉल-स्तरीय prepared-statement समर्थन, और ड्राइवर सेटिंग्स के विरुद्ध PgBouncer के फीचर मैट्रिक्स को मान्य करें। ट्रांज़ैक्शन पूलिंग अभी भी यह गारंटी नहीं देती है कि दो ट्रांज़ैक्शन एक ही सर्वर सत्र का उपयोग करते हैं। वास्तविक सत्र सेमेन्टिक्स को सूचीबद्ध करें जिस पर एप्लिकेशन निर्भर करता है, एकीकरण परीक्षणों में उन्हें सत्यापित करें, और फिर प्रत्येक पथ के लिए ट्रांज़ैक्शन पूलिंग, सत्र पूलिंग, या एक सीधा पूल चुनें।
अनुवर्ती 6: पूल बढ़ाने के बाद अधिग्रहण विलंबता गिर गई, लेकिन एंड-टू-एंड p99 बढ़ गया। क्यों?
कतार एप्लिकेशन पूल से डेटाबेस में स्थानांतरित हो गई। अधिक प्रश्नों के एक साथ प्रवेश करने से लॉक विवाद, I/O, या CPU कतार क्वेरी निष्पादन समय को बढ़ाती है। एक बेहतर अधिग्रहण मीट्रिक का मतलब बेहतर उपयोगकर्ता विलंबता नहीं है। एंड-टू-एंड p99, डेटाबेस क्वेरी अवधि, प्रतीक्षा घटनाओं, और थ्रूपुट की तुलना करें, और सबसे कम कुल विलंबता और स्थिर हेडरूम वाले समवर्ती बिंदु को चुनें।