Round Robin DNS को समझना
(blog.hyperknot.com)- OpenFreeMap ऑपरेटर ने अलग-अलग क्षेत्रों के कई VPS को एक ही subdomain के A records में जोड़कर Round Robin DNS कॉन्फ़िगर किया, और यह प्रयोग किया कि browser और Cloudflare असल में कौन-सा server चुनते हैं
- अलग load balancer के बिना load distribution और failover की उम्मीद की जा सकती है, लेकिन वास्तविक नतीजे client के address sorting और retry तरीके पर बहुत निर्भर करते हैं
- अमेरिका, यूरोप और सिंगापुर के 3 VPS पर test में Chrome और Firefox में startup पर कोई random server चुनकर उसी पर टिके रहने की प्रवृत्ति दिखी, जबकि Safari और curl बार-बार request के बाद नज़दीकी EU server पर converge हो गए
- अगर कुछ servers offline हों, तो browsers और curl जल्दी से alternate server पर switch हो गए, लेकिन Cloudflare proxy के ज़रिए आने वाली requests client IP के हिसाब से तय किए गए origin का उपयोग जारी रख सकती हैं, जिससे 521 error आ सकता है
- अगर Cloudflare offline origin या कम latency वाले server को सही से नहीं चुनता, तो Round Robin DNS आधारित distribution user location की परवाह किए बिना slow server से connect करा सकता है
Round Robin DNS का basic idea
- आम VPS-based website में DNS provider पर एक A record जोड़कर traffic को किसी specific IP पर भेजा जाता है
- Round Robin DNS में एक ही subdomain के लिए कई server IPs specify किए जाते हैं
- उदाहरण में
rr-direct.hyperknot.comऔरrr-cf.hyperknot.comपर कई A records सेट किए गए हैं
- उदाहरण में
- इस setup में कई servers में load बाँटने और offline server से बचने के व्यवहार की उम्मीद की जा सकती है
- ज़्यादातर DNS providers पर इसे अलग load balancer के बिना सेट किया जा सकता है, इसलिए यह सरल और लगभग free approach है
- Cloudflare जैसी services की load balancing feature की cost अधिक हो सकती है
Client किस criteria से server चुन सकता है
- संबंधित standards के रूप में RFC 8305 Happy Eyeballs और RFC 6724 सामने आते हैं
- RFC 8305 का address sorting section बताता है कि अगर stateful client के पास हर address path के expected round-trip time (RTT) का record है, तो destination address selection rule में कम RTT वाले address को prefer करने वाला rule जोड़ना चाहिए
- प्रयोगकर्ता ने इसे इस behavior के रूप में समझा
- Server online है या offline, यह check करना
- Online servers को ping time के आधार पर sort करना
Experiment setup
- दुनिया के 3 regions में VPS बनाए गए
- अमेरिका
- यूरोप
- सिंगापुर
- Cloudflare में 3 proxied A records और 3 unproxied A records सेट किए गए
- हर server nginx के साथ वही response structure देता है
- सभी path requests
color.pngपर rewrite होती हैं /server/etc/hostnameकोtext/plainके रूप में return करता है
- सभी path requests
color.pngएक 1px PNG file है और हर server का color अलग है- US: हरा
- EU: नीला
- SG: लाल
- Hostnames
test-eu,test-us,test-sgसे अलग किए गए हैं - Test location यूरोप में है, इसलिए expected behavior है कि सबसे नज़दीकी EU server चुना जाए
- HTML test page 10x10 grid में random images भरकर server selection result को visualize करता है
जब सभी servers online हों, तब client-wise behavior
- Chrome कई locations में से कुछ हद तक random तरीके से एक को चुनता है, फिर एक बार चुने गए server पर टिके रहने की tendency दिखाता है
- कुछ घंटों बाद selection को फिर evaluate करता है
- Test में यह कई घंटों तक सबसे slow Singapore server पर fixed भी रहा
- HTTP/2 न इस्तेमाल करने पर कभी-कभी यह दो servers के बीच randomly चुनते हुए pattern भी बनाता है
- Firefox भी Chrome जैसा ही behavior करता है
- Startup पर random location चुनता है
- Browser restart करने पर कोई दूसरी random location चुन सकता है
- Safari हमेशा सबसे नज़दीकी server को सही ढंग से चुनता है
- Server थोड़ी देर offline रहकर वापस आ जाए, तब भी कुछ refresh के बाद फिर EU server ढूँढ लेता है
- curl भी नज़दीकी server की तरफ correct हो जाता है
- पहली run में ऐसा न भी हो, लेकिन command दो बार चलाने पर हमेशा सबसे नज़दीकी server पर चला जाता है
- उदाहरण में पहली request
test-usथी, अगली requesttest-euमें बदल गई
Cloudflare proxy के ज़रिए behavior
- Cloudflare client IP के आधार पर random location चुनता है और फिर लगातार उसी location का उपयोग करता है
- Observed behavior
client_ip_hash modulo server_numजैसा है - Home IP से कुछ भी करने पर Cloudflare अमेरिका server से connect करता है
curl https://rr-cf.hyperknot.com/serverका resulttest-usआता है
- Mobile hotspot से हमेशा EU server से connect होता है
- कई VPS पर वही curl command चलाने पर, हर VPS दुनिया की किसी random location से connect होता है, लेकिन हमेशा उसी server का उपयोग करता है
- Example result
test-sgहै
- Example result
कुछ servers offline होने पर अंतर
- अमेरिका server पर
service nginx stopसे nginx बंद करने के बाद behavior check किया गया - Chrome, Firefox, Safari, curl सभी offline server को detect करके दूसरा server चुनते हैं
- Loading के दौरान server बंद करने पर भी 1 second से कम में correction हो जाने जितना alternate connection तेज़ी से काम करता है
- Cloudflare offline server को detect नहीं करता
- Client IP के लिए एक बार तय किए गए server को online status की परवाह किए बिना access करता रहता है
- अगर वह server offline है, तो user को error मिलता है
- curl result
error code: 521है
Cloudflare पर सवाल और limitations
- Cloudflare का offline origin detect न कर पाना शायद network का bug है, ऐसा माना गया
- Cloudflare docs के zero downtime failover के आधार पर, इसे browsers और curl जैसा behave करना चाहिए, ऐसा निष्कर्ष निकाला गया
- कम-से-कम offline server detect होना चाहिए
- Safari की तरह सबसे कम latency वाला server चुन सके तो और बेहतर होगा
- मौजूदा behavior में अगर 1 अमेरिका server और 1 न्यूज़ीलैंड server हों, तो 50% अमेरिकी users को न्यूज़ीलैंड server से response मिल सकता है
- Safari users के लिए Cloudflare इस्तेमाल करना, Cloudflare न इस्तेमाल करने की तुलना में धीमा हो सकता है
- संबंधित HN discussion में Cloudflare CEO और CTO ने जवाब दिया
- Experiment को चलते रखने के लिए यह भी पूछा गया कि क्या कोई ऐसा serverless platform है जो दुनिया भर में 3 VPS की cost के बिना HTTPS और Round Robin DNS support करता हो
1 टिप्पणियां
Hacker News की राय
हम्म, मैंने authoritative DNS टीम से कहा है कि वे समझाएं कि यहां क्या हो रहा है
पक्का जवाब मिलते ही HN पर बता दूंगा। कोड देखे कई साल हो गए हैं, और इस दौरान बहुत से लोग लगातार इसमें बदलाव करते रहे हैं :-)
मेरा अंदाजा है कि यह उस व्यवहार से जुड़ा है जिसमें client IP और backend server की affinity बनाए रखने की कोशिश की जाती है, जैसा लेखक ने ब्लॉग में बताया है। मुख्य सवाल यह है कि “अगर backend server डाउन हो जाए तो क्या उस affinity को तोड़ देना चाहिए”; और जानकारी मिलने पर मैं अपने कमेंट के reply में लिखूंगा
इस समस्या के शुरुआती समाधानों में से एक SRV DNS record था। यह MX record जैसा था, लेकिन सिर्फ email नहीं बल्कि सभी services पर लागू करने का इरादा था
MX और SRV records में client के लिए आजमाए जाने वाले servers की सूची और priority बताई जा सकती थी, और SRV में load balancing के लिए
weightparameter भी था। लेकिन SRV ने लगभग सभी standard protocols को hijack कर सभी clients से SRV check करवाने वाली राजनीतिक लड़ाई से बचने के लिए यह नियम रखा कि इसे सिर्फ तभी इस्तेमाल किया जाए जब संबंधित protocol standard SRV के उपयोग को स्पष्ट रूप से बताए। इसलिए तकनीकी रूप से HTTP client SRV इस्तेमाल नहीं कर सकता। बाद में HTTP/2 और उसके बाद के HTTP standards बनाते समय भी Google आदि की तरफ से आए अनुचित तर्कों के कारण नए HTTP protocol में SRV को specify नहीं किया जा सका। नए development के लिए SRV लगभग मर चुका है, और लगता है यह सिर्फ कुछ पुराने standards में ही इस्तेमाल होता हैनया load balancing समाधान HTTPS और SVCB DNS records लगता है। मेरी समझ में, इसे उन लोगों ने standardize किया जो TLS 1.3 handshake जल्दी शुरू कर round trips कम करने के लिए DNS में अतिरिक्त parameters डालना चाहते थे। SVCB record type HTTPS जैसा ही है, लेकिन SRV की तरह generalized रूप है। HTTPS और SVCB में SRV और MX वाले priority parameters हैं, लेकिन SRV का
weightparameter नहीं है। Standard प्रकाशित हो चुका है और कुछ browsers में support आ गया लगता है, लेकिन सभी ने इसे enabled नहीं किया है। निकट भविष्य में browsers वास्तव में क्या करेंगे, यह देखना होगाGeoDNS को anycast के साथ या उसके बजाय इस्तेमाल करने वाले CDN में routing problems पैदा कर सकने वाले CNAME flattening जैसे hacks की जरूरत नहीं रहती। अगर आपने किसी platform को apex domain के बजाय
wwwsubdomain इस्तेमाल करने की सलाह देते देखा है, तो यही वजह है; और Akamai द्वारा GeoDNS इस्तेमाल किए जाने के कारण HTTPS record standardization को push करने का यह भी एक कारण थालोग अक्सर domain apex पर website host करना चाहते हैं, इसलिए ऐसे records का न होना खास तौर पर खलता है। हालांकि अगर DNSSEC पर भरोसा नहीं किया जा सकता, तो MX style records को सुरक्षित रूप से इस्तेमाल करना मुश्किल हो सकता है
DNS load balancing में सचमुच गंदे edge cases हैं। मैंने Go HTTP/2 client के round-robin DNS इस्तेमाल करने की स्थिति संभाली है, और दिक्कत आई थी
Go HTTP/2 client पहले connect हो सकने वाले server को लगातार reuse करता है और DNS को फिर से resolve नहीं करता। इस वजह से pool में नया server जोड़ने पर भी client उसे discover नहीं कर पाता
खास तौर पर pathological case यह है कि अगर सभी backends डाउन हो जाएं और फिर पहला backend दोबारा ऊपर आ जाए, तो सारे clients उसी server पर चिपक जाते हैं और हटते नहीं। दूसरे servers ऊपर आने के बाद भी वे पहले server से जुड़े रहते हैं, इसलिए नए connection बनाने वाले clients बहुत कम होते हैं
grpc-goमें भी ऐसी ही समस्या आती है। gRPC DNS resolver backend connection टूटने पर ही दोबारा resolve करता है। इसलिए gRPC clients किसी एक host पर इकट्ठा होकर वहीं बने रह सकते हैं। Server side परMAX_CONNECTION_AGEसेट करने का सुझाव भी है, ताकि कुछ समय बाद periodically clients को disconnect किया जाए और client DNS को फिर से resolve करेकाश service discovery के लिए कोई बेहतर standard solution होता। अंत में शायद सबसे अच्छा यही किया जा सकता है कि virtual IP आधारित per-request load balancer implement किया जाए और load balancer health checks करे। लेकिन यह भी समस्या को सिर्फ उस system की तरफ धकेलता है जो virtual IP implement करता है। लगता है assumption यह है कि routing system backends की तुलना में अपेक्षाकृत static होता है, और वहीं से फायदा मिलता है
bare metal में यह कैसे किया जाता है, जानने की उत्सुकता है। AWS/GCP आदि में internal load balancers होते हैं, यह पता है, लेकिन इसे implement करने का नुस्खा क्या है, यह जानना चाहता हूं। संबंधित blog posts या whitepapers की सिफारिश भी अच्छी होगी
“अगर एक server offline हो जाए तो क्या होगा? मान लें US server को रोकते हैं:
service nginx stop” कहा गया था, लेकिन इस तरह test नहीं करना चाहिएClient connection refused देखता है और अगले IP पर चला जाता है। लेकिन असल में server बिल्कुल response न दे सकता है, या connection accept करके चुप रह सकता है
तब आपको client timeout पर निर्भर रहना पड़ता है, और reliability बढ़ाने के लिए round-robin DNS अचानक काफी कम आकर्षक लगने लगता है
Service रोकना planned operation है, और उस case में पहले DNS update करके handle किया जा सकता है
SIG_STOPयाip/nftablesकाDROPकहीं ज्यादा realistic test है“जैसा कि आप देख सकते हैं, सभी क्लाइंट इसे सही ढंग से detect करते हैं और वैकल्पिक सर्वर चुनते हैं” यही इसका उलझा हुआ core है। विश्वसनीयता क्लाइंट की तरफ तय होती है
उदाहरण के लिए,
systemd-resolvedकभी यह कहते हुए कि वह तकनीकी रूप से जितना हो सके उतना सही व्यवहार कर रहा है, हमेशा सबसे छोटा IP address लौटाता था। तर्क यह था कि DNS round robin अच्छी तरह परिभाषित नहीं है, इसलिए हमेशा सबसे छोटा IP लौटाना भी गलत नहीं है। हंगामे के बाद यह बदला, लेकिन जहां तक मुझे पता है Debian 11 उस व्यवहार में बंधा हुआ था, या लंबे समय तक ऐसा ही थासाथ ही, मैंने ऐसे बहुत से applications भी देखे हैं जिनका retry behavior बेहद खराब है या है ही नहीं। वे ऐसे चलते हैं जैसे “एक connection refused आया, सब cancel करो, exit करो और फिर कभी कोशिश मत करो।” तब कुल requests का 20–30% जलकर खत्म हो जाता है
अगर कोई दूसरा विकल्प न हो तो यह स्वीकार्य समाधान है। लेख में जैसा कहा गया है, अगर आपके पास browser जैसा अच्छा HTTP client है जिसमें कुछ retries configured हैं, तो DNS round robin health checks वगैरह वाले वास्तविक load balancer को खोजने के लिए ठीक है और 100% success rate दे सकता है
लेकिन DNS round robin load balancer नहीं है, और load balancer बेहतर होता है
पहले जहां मैं काम करता था, वहां करोड़ों records और 60-second TTL वाला internal DNS server था, और इसका उपयोग customers की incoming connections को network के अंदर सही resources तक ले जाने वाले custom internal routing system में होता था। सच में यह शानदार था। Routing changes DDNS update जितने simple थे, और
NOTIFYसे सभी child servers तक changes push कर दिए जाते थे, जिससे पूरी propagation की average delay 60 seconds से कम थी। इससे और जटिल tools बनाना आसान हुआ, और ऐसा control panel भी बना जिससे एक button से single server से लेकर पूरे datacenter तक को service से बाहर किया जा सकता थाउस system में निश्चित रूप से rough edges थे, लेकिन उस तरह के system के लिए यह तेज, inspect करने में आसान, और अपेक्षाकृत bulletproof था
failover भी ऐसा ही है। अगर एक region down हो जाए, तो क्या आप चाहते हैं कि traffic दूसरे regions में बराबर फैल जाए, या next-nearest पड़ोसी region में जमा हो जाए? अगर यह behavior महत्वपूर्ण है, तो traffic management का control अपने पास रखना चाहिए, किसी और को नहीं देना चाहिए
आजकल उस “कोई दूसरा विकल्प नहीं” वाली स्थिति तक पहुंचने से काफी पहले ही चुनने के लिए दूसरे solutions मौजूद हैं
“कई servers में load बांट सकता है, और कौन-सा server offline है यह अपने आप detect करके online server चुन सकता है” वाले वाक्य में DNS automatic offline detection पर सावधानी से आपत्ति करूं तो, default state में round robin DNS केवल load balancing के लिए ही उपयोगी है
जब तक client में smart logic नहीं डाला जाता, availability state detection के मामले में अपने आप कुछ नहीं होता। लेख का introduction इस बात को कुछ हद तक बताता है, लेकिन अर्थ समझने के लिए मुझे कई बार पढ़ना पड़ा। निष्पक्ष होकर कहूं तो यह मेरी समझ की समस्या भी हो सकती है। उसके बाद लेख का बाकी हिस्सा पढ़ा तो वह पूरा उसी smart logic के बारे में था
अगर browser ने जो 1/N server record चुना है वह उपलब्ध नहीं है, तो protocol level पर automatic recovery या retry नहीं होता
साथ में “related fun”: Java का DNS TTL [1] और
.equals()[2] behavior भी मत भूलिए[1] https://stackoverflow.com/questions/1256556/how-to-make-java...
[2] https://news.ycombinator.com/item?id=21765788 (5 साल पहले, 168 comments)
TTL को ignore करने वाले clients भी होते हैं, लेकिन वे काफी rare हैं
सर्वर डाउन हो जाए तो दुनिया भर में फैले और कैश किए गए IP address बचे रहते हैं, और लोगों को उन addresses पर पहुंचने से रोका नहीं जा सकता
https://www.cloudflare.com/learning/dns/glossary/round-robin...
load balancing की भी लागत होती है, और load balancer connection को हल्के या साफ़ तौर पर बिगाड़ भी सकते हैं। कुछ providers में load balancer की availability हमारे hosts से भी खराब रही है
अगर client आपके control में है, तो platform DNS API call करके IP list लेना, उसे ठीक से shuffle करना और round-robin तरीके से इस्तेमाल करना भी समझदारी है। DNS खराब होने की स्थिति के लिए client binary में कुछ reliably allocated IP डाल सकें तो और बेहतर। लेकिन DNS आम तौर पर खराब नहीं होता, और cluster update करते समय हर बार नया config या binary deploy किए बिना operational changes के लिए अच्छा काम आता है
अगर client browser है, तो default behavior काफी ठीक है। आम तौर पर IP को क्रम से इस्तेमाल करता है, इसलिए यह समस्या बन सकता है [1], लेकिन बाकी मामलों में retry behavior अच्छा है। connection refused मिले तो तुरंत दूसरा IP try करता है, और timeout हो तो कम से कम कुछ दूसरे IP try करता है। यह ideal नहीं है, इसलिए browser के लिए load balancer इस्तेमाल करूंगा, और संभव हो तो कम से कम initial page load के लिए तो ऐसा ही करूंगा। WebSocket आदि के लिए DNS round robin और कुछ हद तक समझदार JS client logic इस्तेमाल किया जा सकता है। फिर भी पूरे site के लिए DNS round robin इस्तेमाल करना संभव है
अगर client browser भी नहीं है और आपके control में भी नहीं है, तो बस किस्मत पर निर्भर रहना होगा
यह बात 100% मानता हूं कि कभी-कभी मानकर चलना पड़ता है कि किसी ने DNS caching resolver बनाते समय TTL field को seconds नहीं, days के रूप में interpret किया है। ऐसे resolver के पीछे के clients को DNS update करते समय समस्या होगी। लेकिन अगर load balancer DNS name के पीछे है और कभी उसका address बदलना पड़े, तो वही समस्या तब आएगी, और उस समय आपके पास अनुभव भी नहीं होगा
[1] RFC में से एक सुझाव देता है कि OS API को responses को prefix match के आधार पर sort करना चाहिए। अगर IP prefix hierarchical हों और सबसे पास की network distance वाले server को चुनने का proxy हों, तो यह समझ में आ सकता है। लेकिन असलियत में संख्या के हिसाब से पास-पास के
/24अक्सर network पर पास नहीं होते। अगर server addresses बहुत फैले हुए हैं, तो कुछ client IPs का traffic संख्या में मिलते-जुलते server IPs की ओर झुकता दिख सकता हैबेशक, कुछ लोग local DNS गलत configure करेंगे या खराब client इस्तेमाल करेंगे ही। broken setup वाले लोगों के लिए outage स्वीकार करनी होगी, या उसी datacenter के किसी दूसरे server को IP reassign करना होगा
नमस्ते। मैं Cloudflare का CTO हूं। हमने Cloudflare के सभी free accounts में बदलाव deploy किया है ताकि वे paid accounts जैसा ही behavior करें
यहां बताई गई समस्या ठीक कर दी गई है, और सभी account types में Zero Downtime Failover काम करना चाहिए। क्या आप फिर से test कर सकते हैं?
इसे लिखकरまとめने के लिए धन्यवाद। खुशी है कि हम यह behavior सबके लिए बदल सके
लेख को भी उसी के मुताबिक update करूंगा। इसे free accounts पर भी लागू करने के लिए धन्यवाद; यह शानदार नतीजा है
इसका dark remix version fast flux hosting है, और कई bulletproof hosting providers यही तरीका इस्तेमाल करते हैं
https://unit42.paloaltonetworks.com/fast-flux-101/
यह उल्लेख करना उचित हो सकता है कि Zero Downtime Failover Pro या उससे ऊपर की feature है
मुझे याद है कि पहले जब origin server protection docs plan levels के हिसाब से अलग-अलग थे, तब भी इसे इसी तरह document किया गया था। इसलिए behavior या retries अलग दिख सकते हैं