Blue-green बनाम canary deployments: API और DB बदलावों को सुरक्षित बनाना
API और डेटाबेस बदलावों के लिए blue-green और canary तैनाती की व्याख्या, स्कीमा माइग्रेशन के दौरान डाउनटाइम जोखिम कम करने के व्यावहारिक कदमों के साथ।

क्यों स्कीमा बदलाव और धीमे मोबाइल अपडेट्स के साथ डिप्लॉयमेंट जोखिम बढ़ता है
एक डिप्लॉय टेस्ट में सही दिख सकता है और असली ट्रैफ़िक पर जाते ही फेल हो सकता है। आम कारण यह है कि सिर्फ़ आपका कोड ही बदल नहीं रहा—आपका API कॉन्ट्रैक्ट और डेटाबेस स्कीमा भी बदल रहे हैं, और ये अक्सर एक ही रफ्तार से नहीं बदलते।
टूटफूट तब होती है जब सिस्टम के अलग-अलग हिस्से "सही" की परिभाषा पर सहमत नहीं होते। नया बैकएंड ऐसे कॉलम की उम्मीद कर सकता है जो अभी मौजूद नहीं है। पुराना बैकएंड ऐसे डेटा लिखता है जिसे नया कोड समझना बंद कर देता है। एक फ़ील्ड का नाम बदलना, वैलिडेशन कड़ा करना, या enum वैल्यू बदलना भी प्रोडक्शन त्रुटियाँ पैदा कर सकता है।
मोबाइल ऐप्स मामले को और गंभीर बना देते हैं क्योंकि पुराने वर्शन लंबे समय तक बने रह सकते हैं। कुछ यूज़र मिनटों में अपडेट कर लेते हैं, कुछ हफ्तों में। इसका मतलब है कि आपका बैकएंड एक साथ कई क्लाइंट जेनरेशंस को सर्व करना होगा। अगर आप ऐसा API भेजते हैं जो सिर्फ़ नए ऐप के साथ काम करता है, तो आप कुछ यूज़र्स के लिए चेकआउट, ऑनबोर्डिंग या बैकग्राउंड सिंक तोड़ सकते हैं और तुरंत नोटिस नहीं कर पाएंगे।
"डाउनटाइम जोखिम" केवल साइट डाउन होना नहीं है। वास्तविक सिस्टम में यह अक्सर आंशिक विफलताओं के रूप में दिखता है:
- कुछ endpoints पर 4xx/5xx एरर में उछाल जबकि बाकी सब कुछ ठीक दिखता है
- साइन-इन्स फेल होना क्योंकि टोकन, रोल्स, या यूज़र रिकॉर्ड उम्मीद के मुताबिक़ नहीं हैं
- मूक डेटा समस्याएँ (गलत डिफ़ॉल्ट, कटे हुए टेक्स्ट, गायब रिलेशनशिप) जो दिनों बाद सामने आती हैं
- बैकग्राउंड जॉब्स अटक जाना और घंटों में घटने वाली कतार बनना
इसीलिए टीमें blue-green vs canary deployments की तुलना करती हैं: आप उस ब्लास्ट रेडियस को घटाने की कोशिश कर रहे हैं जब बदलाव पूरी तरह संगत न हों।
सरल भाषा में Blue-green और Canary
जब लोग blue-green बनाम canary deployments की तुलना करते हैं, तो अक्सर वे एक प्रश्न का उत्तर दे रहे होते हैं: क्या आप एक बड़ा, नियंत्रित स्विच चाहते हैं या छोटा, सतर्क परीक्षण?
Blue-green: दो पूरे वर्शन और एक ट्रैफ़िक स्विच
Blue-green का मतलब है कि आप एक साथ दो पूरे एनवायरनमेंट चलाते हैं। "Blue" वर्तमान वर्शन है जो यूज़र्स को सर्व कर रहा है। "Green" नया वर्शन है, जो पैरेलल में डिप्लॉय और टेस्ट किया जाता है। जब आप तैयार हों, तो आप ट्रैफ़िक को blue से green पर पलट देते हैं।
यह दृष्टिकोण प्रिडिक्टेबिलिटी के लिए अच्छा है। आप नए वर्शन को प्रोडक्शन-जैसे सेटिंग्स में वैधेट कर सकते हैं और फिर एक साफ कटओवर कर सकते हैं।
Rollback भी सरल है: स्विच के बाद कुछ गड़बड़ होने पर ट्रैफ़िक वापस blue पर रूट कर दें। यह लगभग तात्कालिक स्विचबैक जैसा है, लेकिन कैश, बैकग्राउंड जॉब्स और डेटा बदलाव रिकवरी को जटिल बना सकते हैं।
Canary: पहले छोटे प्रतिशत को भेजें
Canary का मतलब है कि नया वर्शन पहले यूज़र्स या रिक्वेस्ट्स के छोटे हिस्से के लिए लाइव होता है। अगर यह स्वस्थ दिखे, तो आप धीरे-धीरे उस प्रतिशत को बढ़ाते हैं जब तक कि यह सभी को सर्व नहीं करने लगे।
Canary उस समय सबसे अच्छा है जब आप असली ट्रैफ़िक के तहत अनजानी व्यवहार को लेकर चिंतित हों। आप बड़े यूज़र बेस को प्रभावित किए बिना शुरुआती मुद्दों को पकड़ सकते हैं।
Rollback का तरीका canary प्रतिशत को फिर से शून्य कर देना (या नए वर्शन को ट्रैफ़िक न देना) होता है। यह आमतौर पर तेज़ है, लेकिन हमेशा साफ नहीं होता—क्योंकि कुछ यूज़र्स ने पहले ही ऐसा डेटा या स्टेट बना लिया हो सकता है जिसे दोनों वर्शन को संभालना होगा।
याद रखने का सरल तरीका:
- Blue-green साफ कटओवर और तेज़ स्विचबैक को तरजीह देता है।
- Canary असली ट्रैफ़िक से सीखना और सीमित ब्लास्ट रेडियस पसंद करता है।
- कोई भी तरीका अपने आप डेटाबेस रिस्क को हल नहीं करता। अगर स्कीमा बदलाव संगत नहीं हैं, तो दोनों असफल हो सकते हैं।
- Canary निगरानी पर निर्भर करता है क्योंकि आप लाइव सिग्नल्स के आधार पर निर्णय लेते हैं।
- Blue-green अक्सर अतिरिक्त क्षमता माँगता है क्योंकि आप दो पूरा स्टैक चलाते हैं।
उदाहरण: अगर आप ऐसा API रिलीज़ करते हैं जो कभी-कभी नया फ़ील्ड लौटाता है, तो canary यह देखने में मदद करेगा कि पुराने क्लाइंट्स अनपेक्षित डेटा पर क्रैश तो नहीं कर रहे। अगर बदलाव के लिए कॉलम रीनेम जरूरी है और पुराना कोड उसे हैंडल नहीं कर सकता, तो blue-green तब भी तबाही नहीं रोकेगा जब तक कि स्कीमा बदलाव दोनों वर्शन के लिए डिजाइन न किया गया हो।
डेटाबेस माइग्रेशन कोड डिप्लॉय से अलग क्या बनाता है
कोड डिप्लॉय अक्सर रोलबैक में आसान होता है। अगर नया वर्शन खराब व्यवहार करे तो आप पुराना बिल्ड फिर से डिप्लॉय कर देते हैं और ज्यादातर चीज़ें पहले जैसी हो जाती हैं।
डेटाबेस बदलाव अलग है क्योंकि यह आपके डेटा की आकृति बदल देता है। एक बार रोज़ री-राइट हो गए, कॉलम ड्रॉप हो गए, या constraints कड़े हो गए—वापसी शायद ही कभी तात्कालिक होती है। भले ही आप एप्लिकेशन को रोलबैक कर दें, वह नए स्कीमा को समझ न पाए।
इसीलिए स्कीमा माइग्रेशन डाउनटाइम रिस्क का ज़्यादातर संबंध डिप्लॉय पद्धति से कम और माइग्रेशन के डिज़ाइन से ज़्यादा होता है।
ऑनलाइन माइग्रेशन के बेसिक सिद्धांत
सबसे सुरक्षित माइग्रेशन वे होते हैं जो पुराने और नए ऐप वर्शन एक साथ चलते समय भी काम करें। पैटर्न सरल है: ऐसा बदलाव करें जिसे अनदेखा किया जा सके, कोड अपडेट करें ताकि वह नया यूज़ करे, और फिर बाद में साफ़-सफाई करें।
एक सामान्य expand-then-contract क्रम इस तरह दिखता है:
- सबसे पहले जोड़ने वाले बदलाव: nullable कॉलम जोड़ें, नया टेबल जोड़ें, ऐसा इंडेक्स जोड़ें जो राइट्स को लॉक न करे।
- ड्युअल व्यवहार: दोनों पुराने और नए में लिखें, या नए से पढ़ें और पुराने पर fallback रखें।
- बैकफिल अलग से: मौजूदा डेटा को छोटे बैच में माइग्रेट करें।
- स्विच ओवर: नया व्यवहार पर ज़्यादातर ट्रैफ़िक ले जाएँ।
- विनाशकारी बदलाव अंत में: पुराने कॉलम हटाएँ, पुराने कोड पाथ हटाएँ, constraints कड़ा करें।
"Big bang" माइग्रेशन रिस्की स्टेप्स को एक ही रिलीज़ में जोड़ देते हैं: लंबे लॉक, भारी बैकफिल, और ऐसा कोड जो मान लेता है कि नया स्कीमा हर जगह मौजूद है।
धीमे मोबाइल अपडेट्स क्यों जोखिम बढ़ाते हैं
मोबाइल क्लाइंट हफ्तों तक पुराने वर्शन पर रह सकते हैं। आपका बैकएंड पुराने रिक्वेस्ट स्वीकार करता रहे और旧 रेस्पॉन्स देता रहे, जबकि डेटाबेस विकसित हो रहा हो।
अगर कोई पुराना ऐप नया फ़ील्ड नहीं भेजता, तो आपका सर्वर अचानक उस फ़ील्ड को डेटाबेस में आवश्यक नहीं बना सकता। आपको एक अवधि चाहिए जहाँ दोनों व्यवहार काम करें।
स्कीमा माइग्रेशन के लिए कौन सी स्ट्रैटेजी डाउनटाइम जोखिम कम करती है
सबसे सुरक्षित विकल्प टूल से ज़्यादा इस बात पर निर्भर करता है: क्या पुराने और नए ऐप वर्शन कुछ समय के लिए एक ही डेटाबेस स्कीमा पर सही तरीके से चल सकते हैं?
अगर जवाब हाँ है, तो blue-green अक्सर सबसे कम डाउनटाइम विकल्प होता है। आप पहले डेटाबेस परिवर्तन तैयार कर सकते हैं, ट्रैफ़िक को पुराने स्टैक पर रख सकते हैं, फिर एक बार में नया स्टैक सर्व करना शुरू कर दें। अगर कुछ गलत दिखे तो आप जल्दी से वापस स्विच कर सकते हैं।
Blue-green तब भी फेल हो सकता है जब नया ऐप तुरंत नए स्कीमा की जरूरत करे। आम उदाहरणों में कॉलम ड्रॉप/रीनाम जो पुराना वर्शन अभी भी पढ़ता है, या ऐसा NOT NULL constraint जोड़ना शामिल है जब ऐप अभी वैल्यू नहीं लिख रहा। उन मामलों में रोलबैक सुरक्षित नहीं हो सकता क्योंकि डेटाबेस पहले ही असंगत हो चुका है।
Canary बेहतर है जब आपको नियंत्रित तरीके से सीखने की ज़रूरत हो। नया वर्शन पहले छोटे सेट में लाइव होता है, जिससे आप edge-cases जैसे गायब इंडेक्स, अनपेक्षित क्वेरी पैटर्न, या बैकग्राउंड जॉब्स के प्रोडक्शन लोड के तहत अलग व्यवहार को पकड़ सकते हैं। ट्रेडऑफ़ यह है कि आपको दोनों वर्शन को एक साथ काम में रखना होगा, जो आमतौर पर बैकवर्ड-कम्पैटिबल डेटाबेस बदलावों का मतलब है।
एक व्यावहारिक निर्णय नियम
Blue-green बनाम canary चुनते समय स्कीमा माइग्रेशन डाउनटाइम रिस्क के लिए:
- जब आप स्कीमा बदलकर उसे additive और संगत रख सकते हैं और मुख्य उद्देश्य तेज़, साफ़ स्विच है तो blue-green चुनें।
- जब आप नहीं जानते कि बदलाव प्रोडक्शन में कैसे व्यवहार करेगा, या आप मानते हैं कि rare data shapes मायने रखेंगे, तो canary चुनें।
- अगर माइग्रेशन तुरंत ब्रेकिंग बदलाव करने को मजबूर करता है, तो blue-green और canary में से कोई न चुनें—योजना बदलें और expand-then-contract अपनाएँ।
"संगत" असल जीवन में कैसा दिखता है
मान लीजिए आप orders टेबल में नया फ़ील्ड जोड़ रहे हैं। एक सुरक्षित रास्ता यह है: कॉलम को nullable के रूप में जोड़ें, ऐसा ऐप डिप्लॉय करें जो इसे लिखे, पुराने rows को बैकफिल करें, और बाद में constraints लागू करें। इस सेटअप में blue-green आपको साफ़ कटओवर देता है, और canary यह बताने में मदद करता है कि कोई कोड पाथ अभी भी पुराने शेप पर टूट रहा है या नहीं।
धीमें मोबाइल अपडेट्स डिप्लॉयमेंट चुनाव कैसे बदलते हैं
वेब यूज़र पेज रिफ्रेश कर लेते हैं। मोबाइल यूज़र नहीं।
iOS और Android पर लोग हफ्तों या महीनों तक पुराने वर्शन पर बने रहते हैं। कुछ कभी अपडेट नहीं करते जब तक ऐप मजबूर न करे, और कुछ डिवाइस लंबे समय के लिए ऑफ़लाइन रहते हैं। मतलब आपका "पुराना" क्लाइंट काफी देर तक आपका API कॉल करता रहेगा। पुराने मोबाइल क्लाइंट आपकी बैकवर्ड-कम्पैटिबिलिटी का स्थायी परीक्षण बन जाते हैं।
यह लक्ष्य को बदल देता है: "डिप्लॉय बिना डाउनटाइम के" से "कई क्लाइंट जेनरेशंस को एक साथ काम करने देने" पर। व्यवहारिक रूप से, मोबाइल अक्सर आपको API के लिए canary-सी सोच की तरफ धकेलता है, भले ही आप इंफ्रास्ट्रक्चर के लिए blue-green इस्तेमाल करें।
बैकवर्ड-कम्पैटिबल परिवर्तन बनाम API वर्शनिंग
अधिकांश समय आप बैकवर्ड-कम्पैटिबल बदलाव चाहते हैं, क्योंकि वे पुराने और नए ऐप्स को एक ही endpoints साझा करने देते हैं।
बैकवर्ड-कम्पैटिबल उदाहरण: नए फ़ील्ड जोड़ना, पुराने और नए पेलोड शेप दोनों स्वीकार करना, मौजूदा रिस्पॉन्स फ़ील्ड रखना, और अर्थ बदलने से बचना।
API वर्शनिंग तब उपयोगी होती है जब व्यवहार बदलना अनिवार्य हो (सिर्फ़ डेटा जोड़ना नहीं), या आपको फ़ील्ड हटानी/रीनाम करनी हो।
उदाहरण: marketing_opt_in जैसा optional फ़ील्ड जोड़ना आमतौर पर सुरक्षित है। price कैसे कैलकुलेट होता है बदलना आमतौर पर सुरक्षित नहीं है।
डिप्रिकेटशन विंडो प्लान करना
अगर आपको ब्रेकिंग बदलाव करना ही है, तो समर्थन समाप्त करना एक प्रोडक्ट निर्णय की तरह लें। उपयोगी डिप्रिकेटशन विंडो को "पुराने वर्शन पर सक्रिय यूज़र्स" के आधार पर मापें, न कि कैलेंडर दिनांक के आधार पर।
एक व्यावहारिक क्रम:
- बैकएंड भेजें जो दोनों पुराने और नए क्लाइंट्स को सपोर्ट करे।
- नया मोबाइल ऐप रिलीज़ करें और ऐप वर्शन के अनुसार अपनाने को ट्रैक करें।
- केवल तभी पुराना व्यवहार चेतावनी दें या प्रतिबंध लगाएँ जब पुराने वर्शन इतनी कम संख्या पर आ जाएँ कि यह सुरक्षित हो।
- पुराना व्यवहार आख़िर में हटाएँ, और रोलबैक प्लान रखें।
चरण-दर-चरण: API + डेटाबेस बदलाव के लिए सुरक्षित रोलआउट पैटर्न
जब आप एक साथ API और डेटाबेस बदलते हैं, तो सबसे सुरक्षित योजना आमतौर पर दो या तीन चरणों वाली होती है। हर कदम अपने आप में सुरक्षित होना चाहिए, भले ही यूज़र पुराने मोबाइल ऐप को हफ्तों तक रखें।
पुराने क्लाइंट तोड़े बिना एक रोलआउट पैटर्न
न्यायिक रूप से additive डेटाबेस बदलाव से शुरू करें। नए कॉलम या टेबल जोड़ें, कुछ भी रीनेम या ड्रॉप करने से बचें, जहां ज़रूरत हो वहाँ nullable रखें, और डिफ़ॉल्ट इस्तेमाल करें ताकि पुराना कोड अचानक constraints का सामना न करे।
फिर ऐसा एप्लिकेशन कोड भेजें जो दोनों शेप सहन करे। पढ़ाई इस तरह हो कि "पुराना फ़ील्ड गायब" और "नया फ़ील्ड मौजूद" दोनों को स्वीकार करे। लिखते समय अभी पुराने फ़ील्ड पर लिखना रखें और वैकल्पिक रूप से नया फ़ील्ड भी लिखें।
एक सामान्य क्रम:
- नया स्कीमा पीस जोड़ें (कॉलम, टेबल, इंडेक्स) बिना पुराने को हटाए।
- ऐसा कोड डिप्लॉय करें जो पुराने या नए दोनों से पढ़े और nulls पर क्रैश न हो।
- मौजूदा rows को छोटे बैच में बैकफिल करें, फिर काउंट, null दर और क्वेरी प्रदर्शन सत्यापित करें।
- राइट पाथ को नए फ़ील्ड पर स्विच करें, fallback पढ़ना रखें।
- जब पुराने मोबाइल वर्शन fade out हो जाएँ, तब पुराने फ़ील्ड और क्लीनअप करें।
बैकफिल और सत्यापन: जहाँ आउटेज छिपते हैं
बैकफिल इसलिए अक्सर फेल होते हैं क्योंकि उन्हें एक जल्दी स्क्रिप्ट समझ लिया जाता है। इन्हें धीरे-धीरे चलाएँ, लोड देखें, और परिणाम सत्यापित करें। अगर नए व्यवहार को किसी इंडेक्स की ज़रूरत है, तो पढ़ने/लिखने को स्विच करने से पहले उसे जोड़ें, बाद में नहीं।
उदाहरण: आप phone_country_code जोड़ते हैं ताकि फ़ॉर्मैटिंग बेहतर हो सके। पहले कॉलम जोड़ें (nullable), API को अपडेट करें ताकि यह इसे स्वीकार करे पर न होने पर भी काम करे, इसे मौजूदा फ़ोन नंबर से बैकफिल करें, और फिर नए साइनअप्स के लिए लिखना शुरू करें। हफ्तों बाद, जब पुराने ऐप वर्शन अधिकांश रूप से चले जाएँ, तब legacy parsing पाथ हटा दें।
दोनों रणनीतियों को सुरक्षित बनाने वाले उपकरण (बिना ज़्यादा जटिलता के)
आपको blue-green या canary को सुरक्षित बनाने के लिए जटिल सेटअप की ज़रूरत नहीं। कुछ आदतें API और डेटाबेस के अलग रफ्तार से बदलने पर आश्चर्य कम कर देती हैं।
ड्युअल-रीड और ड्युअल-राइट (अस्थायी रखें)
ड्युअल-राइट का मतलब है ट्रांज़िशन के दौरान ऐप पुराने और नए दोनों जगह डेटा लिखे (उदाहरण के लिए दोनों users.full_name और नया users.display_name)। ड्युअल-रीड का अर्थ है नए फ़ील्ड से पढ़ना, पर fallback के लिए पुराने को रखना।
यह धीमे क्लाइंट अपडेट्स के लिए समय खरीदता है, पर यह अस्थायी ब्रिज होना चाहिए। तय करें कि इसे कैसे हटाया जाएगा, ट्रैक करें कौन सा पाथ उपयोग हो रहा है (नया बनाम fallback), और बेसिक चेक जोड़ें ताकि दोनों राइट्स सुसंगत रहें।
व्यवहार बदलने के लिए फीचर फ्लैग
फीचर फ्लैग आपको जोखिम भरे व्यवहार को सक्रिय किए बिना कोड डिप्लॉय करने देते हैं। यह दोनों blue-green और canary रोलआउट के लिए मददगार है क्योंकि आप "deploy" और "turn on" को अलग कर सकते हैं।
उदाहरण: नया रिस्पॉन्स फ़ील्ड सपोर्ट करने के लिए कोड भेजें, पर सर्वर को तब तक पुराना शेप रिटर्न करने दें जब तक आप तैयार न हों। फिर नए व्यवहार को छोटे समूह पर चालू करें, एरर देखें, और रैम्प-अप करें। अगर कुछ टूटे, तो फ़्लैग बंद कर दें बिना पूरी रोलबैक के।
कॉन्ट्रैक्ट टेस्टिंग मानसिकता (API एक वादा है)
कई माइग्रेशन घटनाएँ असल में "डेटाबेस समस्याएँ" नहीं होतीं—वे क्लाइंट उम्मीदों की समस्या होती हैं।
API को एक वादा समझें। फ़ील्ड हटाने या अर्थ बदलने से बचें। अनजाने फ़ील्ड्स को optional रखें। जोड़ने वाले बदलाव (नए फ़ील्ड, नए endpoints) आमतौर पर सुरक्षित होते हैं। ब्रेकिंग बदलाव नए API वर्शन का इंतज़ार करें।
भरोसेमंद डेटा माइग्रेशन जॉब्स
स्कीमा माइग्रेशन अक्सर बैकफिल जॉब की ज़रूरत होती है जो डेटा कॉपी करे, वैल्यूज़ कम्प्यूट करे, या क्लीनअप करे। इन जॉब्स को नीरस और दोहराए जाने योग्य बनाएं: दो बार चलाने पर भी सुरक्षित, retry-able, ट्रैक करने में आसान, और ऐसा throttle रखें कि वे लोड spike न करें।
माइग्रेशन के दौरान आउटेज पैदा करने वाली सामान्य गलतियाँ
अधिकांश माइग्रेशन आउटेज तब होते हैं जब किसी रिलीज़ ने मान लिया कि सब कुछ एक साथ आगे बढ़ेगा: सभी सर्विसेज एक साथ डिप्लॉय होंगी, सारा डेटा साफ़ होगा, और सभी क्लाइंट तुरंत अपडेट हो जाएँगे। वास्तविक सिस्टम ऐसे नहीं चलते, खासकर मोबाइल के साथ।
सामान्य फेलर पैटर्न:
- कॉलम बहुत जल्दी ड्रॉप या रीनाम कर देना। पुराना API कोड, बैकग्राउंड जॉब्स, या पुराने मोबाइल ऐप्स अभी भी उसे यूज़ कर सकते हैं।
- मान लेना कि क्लाइंट जल्दी अपडेट होंगे। मोबाइल रिलीज़्स को यूज़र्स तक पहुँचने में समय लगता है।
- पीक घंटों के दौरान लॉकिंग माइग्रेशन चलाना। एक "सरल" इंडेक्स या कॉलम चेंज भी राइट्स को ब्लॉक कर सकता है।
- सिर्फ साफ़ सैंपल डेटा पर टेस्ट करना। प्रोडक्शन डेटा में nulls, अजीब फ़ॉर्मैट्स, डुप्लिकेट्स और legacy वैल्यूज़ होती हैं।
- कोड और डेटा दोनों के लिए कोई असली रोलबैक प्लान न होना। "हम पिछले वर्शन को फिर से डिप्लॉय कर सकते हैं" पर्याप्त नहीं है अगर स्कीमा बदल गया हो।
उदाहरण: आप status को order_status rename करते हैं और नया API डिप्लॉय करते हैं। वेब ऐप काम करता है। पुराने मोबाइल क्लाइंट अभी भी status भेज रहे हैं, और अब API उन रिक्वेस्ट्स को reject कर देता है, जिससे चेकआउट फेल हो जाते हैं। अगर आपने कॉलम ड्रॉप भी कर दिया था, तो व्यवहार बहाल करना तेज़ स्विच नहीं होगा।
एक बेहतर डिफ़ॉल्ट यह है: छोटे, reversible स्टेप्स में बदलें, पुराने और नए पाथ दोनों को साथ रखें, और लिखें कि metrics spike होने पर आप क्या करेंगे (कैसे ट्रैफ़िक वापस रूट करना है, कौन सा फीचर फ़्लैग नए व्यवहार को बंद कर देगा, और अगर बैकफिल खराब हो जाए तो डेटा कैसे सत्यापित और मरम्मत करेंगे)।
डिप्लॉय करने से ठीक पहले एक त्वरित चेकलिस्ट
रिलीज़ से ठीक पहले एक छोटी चेकलिस्ट वे समस्याएँ पकड़ लेती है जो देर रात के रोलबैक का कारण बनती हैं। यह सबसे ज़रूरी है जब आप एक साथ API और डेटाबेस बदल रहे हों, खासकर धीमे मोबाइल अपडेट्स के साथ।
पांच चेक जो ज्यादातर आउटेज रोकते हैं
- Compatibility: पुष्टि करें कि पुराने और नए ऐप वर्शन दोनों एक ही डेटाबेस स्कीमा पर काम करते हैं। एक व्यावहारिक टेस्ट है वर्तमान प्रोडक्शन बिल्ड को स्टेजिंग डेटाबेस पर नया माइग्रेशन लागू करके चलाना।
- Migration order: सुनिश्चित करें कि पहला माइग्रेशन additive है, और विनाशकारी बदलाव (कॉलम ड्रॉप, constraints कड़ा करना) बाद के लिए शेड्यूल करें।
- Rollback: सबसे तेज़ undo परिभाषित करें। Blue-green के लिए यह ट्रैफ़िक वापस स्विच करना है। Canary के लिए 100% ट्रैफ़िक स्थिर वर्शन पर भेजना है। अगर रोलबैक के लिए फिर से माइग्रेशन चाहिए, तो वह सरल नहीं है।
- Performance: केवल सही होना ही नहीं, स्कीमा परिवर्तन के बाद क्वेरी latency भी मापें। एक गायब इंडेक्स किसी endpoint को आउटेज जैसा बना सकता है।
- Client reality: सबसे पुराना सक्रिय मोबाइल ऐप वर्शन पहचानें जो अभी भी आपका API कॉल कर रहा है। अगर कोई मायने खाती प्रतिशतता उस पर है, तो लंबे कम्पैटिबिलिटी विंडो की योजना बनाएं।
एक त्वरित संदेह परिदृश्य
अगर आप preferred_language जैसा नया फ़ील्ड जोड़ रहे हैं, तो पहले डेटाबेस बदलाव nullable के रूप में करें। फिर ऐसा सर्वर कोड भेजें जो इसे होने पर पढ़े पर इसकी आवश्यकता न करे। तभी most traffic अपडेटेड ऐप्स पर आ जाने के बाद इसे required बनाएँ या पुरानी व्यवहार हटाएँ।
उदाहरण: पुराने मोबाइल ऐप्स को तोड़े बिना नया फ़ील्ड जोड़ना
कल्पना करें कि आप एक नया प्रोफ़ाइल फ़ील्ड country जोड़ते हैं और बिज़नेस इसे required करना चाहता है। यह दो जगह टूट सकता है: पुराने क्लाइंट फ़ील्ड नहीं भेजेंगे, और डेटाबेस अगर NOT NULL लागू कर दिया गया तो राइट्स reject करेगा।
सुरक्षित तरीका दो अलग बदलाव है: पहले फ़ील्ड को बैकवर्ड-कम्पैटिबल तरीके से जोड़ें, फिर बाद में "required" लागू करें जब क्लाइंट्स पकड़ में आ जाएँ।
Blue-green के साथ यह कैसा दिखता है
Blue-green में आप नया वर्शन पुराने के साथ साथ चलते देखेंगे। फिर भी डेटाबेस चेंज दोनों वर्शन के लिए संगत होना चाहिए।
एक सुरक्षित फ़्लो:
- माइग्रेशन डिप्लॉय करें (
countryको nullable के रूप में जोड़ें) - green वर्शन डिप्लॉय करें जो missing
countryको fallback के साथ स्वीकार करे - signup, edit profile, checkout जैसे प्रमुख फ्लो को green पर टेस्ट करें
- ट्रैफ़िक स्विच करें
अगर कुछ गलत हुआ, तो वापस स्विच कर दें। कुंजी यह है कि स्विचिंग तभी काम करेगी जब स्कीमा अभी भी पुराने वर्शन को सपोर्ट करता हो।
Canary के साथ यह कैसा दिखता है
Canary में आप नए API व्यवहार को पहले छोटे हिस्से (आमतौर पर 1%–5%) के लिए एक्सपोज़ करेंगे और missing-field वैलिडेशन एरर, लेटेंसी परिवर्तन और अनपेक्षित डेटाबेस फेल्यर्स पर नजर रखेंगे।
एक आम आश्चर्य यह है कि पुराने मोबाइल क्लाइंट profile अपडेट भेजते समय country नहीं भेजते। अगर API इसे तुरंत required मान लेता है तो 400 एरर दिखेंगे। अगर डेटाबेस में NOT NULL लागू है, तो 500s आ सकते हैं।
एक सुरक्षित क्रम:
countryको nullable के रूप में जोड़ें (वैकल्पिक रूप से सुरक्षित डिफ़ॉल्ट जैसे "unknown" के साथ)- पुराने क्लाइंट्स से missing
countryस्वीकार करें - बैकग्राउंड जॉब से मौजूदा यूज़र्स के लिए
countryबैकफिल करें - बाद में "required" लागू करें (पहले API में, फिर डेटाबेस में)
रिलीज़ के बाद दस्तावेज़ीकरण करें कि पुराने क्लाइंट क्या भेज सकते हैं और सर्वर क्या गारंटी देता है। यह लिखित कॉन्ट्रैक्ट अगली माइग्रेशन में वही टूटने से रोकेगा।
अगर आप AppMaster (appmaster.io) के साथ बना रहे हैं, तो वही रोलआउट अनुशासन लागू होता है—हालाँकि आप एक मॉडल से बैकेंड, वेब और नेटिव मोबाइल ऐप्स जेनरेट कर सकते हैं। प्लेटफ़ॉर्म का उपयोग करके additive स्कीमा बदलाव और सहिष्णु API लॉजिक पहले शिप करें, और अपनाने के बाद constraints कड़ा करें।
सामान्य प्रश्न
Blue-green एक साथ दो पूरा वातावरण चलाता है और ट्रैफ़िक को एक बार में स्विच करता है। Canary नया वर्शन पहले छोटे प्रतिशत उपयोगकर्ताओं के लिए जारी करता है और रैम्प-अप करते हुए बढ़ाता है।
जब आप एक साफ़ कटओवर चाहते हैं और आपको भरोसा है कि नया वर्शन मौजूदा डेटाबेस स्कीमा के साथ संगत है, तब blue-green चुनें। यह खासकर तब उपयोगी है जब मुख्य जोखिम एप्लिकेशन कोड का हो, न कि अनजानी प्रोडैक्शन व्यवहार का।
जब आपको असली ट्रैफ़िक से सीखने की ज़रूरत हो—जैसे कि क्वेरी पैटर्न, किन्हीं रियर-केस डेटा पर व्यवहार, या बैकग्राउंड जॉब्स प्रोडक्शन में अलग तरह से चल सकते हैं—तब canary बेहतर होता है। यह बेस्ट रैपिड-रोलआउट की तुलना में ब्लास्ट रेडियस कम करता है, पर आपको मेट्रिक्स पर कड़ी निगरानी रखनी होगी और रोलआउट रोकने के लिए तैयार रहना होगा।
नहीं। अगर स्कीमा बदलने से संगतता टूट जाती है (जैसे कोई कॉलम ड्रॉप या रीनाम जो पुराने कोड अभी भी इस्तेमाल करता है), तो दोनों ही विफल हो सकते हैं। सुरक्षित तरीका है ऑनलाइन माइग्रेशन डिजाइन करना जो पुराने और नए वर्शन दोनों को एक साथ सपोर्ट करे।
मोबाइल यूज़र हफ्तों तक पुराने वर्शन पर रह सकते हैं, इसलिए आपका बैकएंड एक साथ कई क्लाइंट जेनरेशंस को सपोर्ट करना होगा। इससे आपको बैकवर्ड-कम्पैटिबिलिटी लंबे समय तक बनाए रखना पड़ता है और ऐसे बदलाव से बचना चाहिए जिनके लिए हर क्लाइंट को तुरंत अपडेट करना पड़े।
पहले additive (जोड़ने वाले) बदलाव करें जिन्हें पुराना कोड अनदेखा कर सके—जैसे nullable कॉलम या नया टेबल। फिर ऐसा कोड डिप्लॉय करें जो पुराने और नए दोनों डेटा शेप को सहन कर सके, बैकफिल धीरे-धीरे करें, व्यवहार स्विच करें, और तभी पुराने फ़ील्ड हटाएँ या constraints कड़ाई से लागू करें।
पुराने क्लाइंट क्या भेजते हैं और क्या उम्मीद करते हैं इसकी सूची बनाएं, फिर फ़ील्ड्स हटाने या मीनिंग बदलने से बचें। नए वैकल्पिक फ़ील्ड जोड़ें, दोनों तरह की रिक्वेस्ट शेप स्वीकार करें, और "required" वैलिडेशन तब लागू करें जब अपनouncement/अपडेट पर्याप्त हो गया हो।
Dual-write में ट्रांज़िशन के दौरान एप्लिकेशन दोनों—पुराने और नए—फ़ील्ड में लिखती है। Dual-read में पढ़ते समय नया फ़ील्ड प्राथमिकता पाता है और न होने पर fallback पुराने फ़ील्ड पर जाता है। इसे अस्थायी रखें, ट्रैक करें कौन सा पाथ इस्तेमाल हो रहा है, और क्लीनअप की स्पष्ट योजना बनाएं।
फीचर फ्लैग आपको ख़तरनाक व्यवहार बंद रखकर कोड डिप्लॉय करने देते हैं। इससे आप "deploy" और "turn on" अलग कर सकते हैं—पहले कोड भेजें, फिर छोटे समूह पर चालू करके निगरानी करें। अगर एरर बढ़ें तो फ़्लैग बंद कर दें बिना पूरी री-डिप्लॉय के।
आम गलतियाँ: कॉलम बहुत जल्दी ड्रॉप/रीनाम कर देना, clients के वैल्यू भेजने से पहले NOT NULL लागू करना, पीक के समय लॉकिंग माइग्रेशन चलाना। एक और सामान्य गलती है प्रोडक्शन डेटा को सरल टेस्ट डेटा मान लेना—रीयल डेटा में नल, अजीब फॉर्मैट और डुप्लिकेट्स आते हैं।


