DNS দিয়ে ট্রাফিক চালানো
Round robin, GeoDNS, EDNS Client Subnet, weighted ও latency রাউটিং, health-checked ফেইলওভার, anycast আর CDN-এর CNAME চেইন — আর DNS কেন দুর্বল load balancer হয়েও সব জায়গায় ব্যবহার হয়।
গল্পে বুঝি
রাজির বিরিয়ানির দোকান এখন একটা চেইন: পুরান ঢাকা, ধানমন্ডি, উত্তরা আর মিরপুরে চারটা শাখা। অর্ডার নেওয়ার জন্য একটাই হটলাইন নাম্বার, আর সেটা ধরেন কল সেন্টারে বসা ফাতিমা। ফাতিমা রান্না করেন না, ডেলিভারিও দেন না। তাঁর একটাই কাজ: কলারকে বলে দেওয়া কোন শাখার নাম্বারে ফোন করে অর্ডার দেবেন। প্রথম দিকে নিয়ম ছিল সহজ, পালা করে: প্রথম কলারকে পুরান ঢাকা, দ্বিতীয়জনকে ধানমন্ডি, তৃতীয়জনকে উত্তরা। কিন্তু দেখা গেল উত্তরার কলারকে পুরান ঢাকার শাখা দিলে বিরিয়ানি ঠান্ডা হয়ে পৌঁছায়।
তাই ফাতিমা কলারের ফোন নাম্বার দেখে এলাকা আন্দাজ করা শুরু করলেন। সমস্যা হলো, অনেক অফিস একটা কেন্দ্রীয় PABX দিয়ে কল করে। মতিঝিলের হেড অফিস থেকে উত্তরার শাখা অফিসের কর্মচারী কল করলেও নাম্বার দেখায় মতিঝিলের। ফাতিমা ভুল শাখায় পাঠান। কিছু অফিস তাই এখন কলের শুরুতে বলে দেয়, “কলটা আসছে উত্তরা সেক্টর সাত থেকে”, পুরো ঠিকানা না, শুধু এলাকা। ফাতিমার আন্দাজ ঠিক হয়, কিন্তু কলারের অবস্থানের একটা টুকরো এখন অন্যের কাছে চলে যায়।
এরপর আসে ভাগাভাগির হিসাব। ধানমন্ডির রান্নাঘর বড়, তাই ফাতিমা দশজনের মধ্যে ছয়জনকে ধানমন্ডি পাঠান। প্রতি ঘণ্টায় খোয়ারিজমি শাখাগুলোতে ফোন দিয়ে দেখেন চুলা জ্বলছে কিনা; মিরপুরের গ্যাস চলে গেলে তালিকা থেকে মিরপুর বাদ। কিন্তু সমস্যা একটা থেকেই যায়: যে কলারকে আধা ঘণ্টা আগে মিরপুরের নাম্বার দেওয়া হয়েছিল, সে নাম্বারটা কাগজে টুকে রেখেছে। ফাতিমা যতই তালিকা বদলান, সে আবার সরাসরি মিরপুরেই ফোন দেবে, কাগজের নাম্বারটা পুরনো হওয়া পর্যন্ত। আর কেউ কেউ তো কাগজটা কখনো ফেলেই দেয় না।
পরে রাজি আরেকটা চালাকি করলেন: চার শাখার রান্নাঘরে একই হটলাইন নাম্বার বসালেন, আর ফোন কোম্পানি কলটা কাছের শাখার টাওয়ার দিয়ে সেই শাখাতেই পৌঁছে দেয়। কাউকে কিছু বলে দিতে হয় না, নেটওয়ার্ক নিজেই কাছেরটা খুঁজে নেয়।
মিলিয়ে নিই: ফাতিমা হলো authoritative DNS সার্ভার, যে শুধু ঠিকানা বলে দেয়, নিজে ট্রাফিক বহন করে না। পালা করে শাখা বলা হলো round robin DNS, ফোন নাম্বার দেখে এলাকা আন্দাজ হলো GeoDNS, আর কেন্দ্রীয় PABX হলো recursive resolver, যার অবস্থান আসল ইউজারের অবস্থান না। “কল আসছে উত্তরা সেক্টর সাত থেকে” হলো EDNS Client Subnet (ECS), আর তাতে প্রাইভেসির যে টুকরো চলে যায় সেটাই এর দাম। দশজনে ছয়জন ধানমন্ডি হলো weighted routing, খোয়ারিজমির ফোন হলো health check, তালিকা থেকে বাদ দেওয়া হলো failover, আর কাগজে টুকে রাখা পুরনো নাম্বার হলো TTL ও ক্লায়েন্ট-সাইড ক্যাশিং, যা ফেইলওভারকে ধীর করে। শেষে চার রান্নাঘরে একই নাম্বার হলো anycast। বাস্তবে প্রতিটা বড় সাইট, CDN আর ক্লাউড DNS প্রোভাইডার ঠিক এই কৌশলগুলো মিলিয়ে ব্যবহার করে।
DNS কীভাবে “রাউট” করে
শুরুতেই একটা কথা পরিষ্কার: DNS কখনো ট্রাফিক বহন করে না। সে শুধু একটা প্রশ্নের উত্তর দেয়, “এই নামের জন্য এই IP-তে যাও।” ট্রাফিক চালানোর সব কৌশল আসলে একটাই প্রশ্নের ভিন্ন ভিন্ন উত্তর: কে জিজ্ঞেস করছে, কখন করছে, আর এই মুহূর্তে কোন সার্ভার সুস্থ, তার ওপর ভিত্তি করে আলাদা উত্তর দেওয়া।
এর একটা সীমা আছে যেটা পুরো চ্যাপ্টার জুড়ে বারবার ফিরে আসবে: উত্তর দেওয়ার পর DNS-এর আর কোনো নিয়ন্ত্রণ নেই। ক্লায়েন্ট সেই উত্তর TTL পর্যন্ত (বা তার চেয়েও বেশি) ক্যাশে রাখে, আর এই সময়ে আপনি যা-ই বদলান, সে জানবে না।
Round robin: একাধিক A রেকর্ড
সবচেয়ে সহজ কৌশল: একই নামে কয়েকটা A রেকর্ড।
; zone file
api.baytalhikma.org. 60 IN A 192.0.2.10
api.baytalhikma.org. 60 IN A 192.0.2.11
api.baytalhikma.org. 60 IN A 192.0.2.12 authoritative সার্ভার বা resolver প্রতিবার ক্রম ঘুরিয়ে দেয়:
$ dig +short api.baytalhikma.org
192.0.2.11
192.0.2.12
192.0.2.10
$ dig +short api.baytalhikma.org
192.0.2.12
192.0.2.10
192.0.2.11 (আউটপুট উদাহরণস্বরূপ।) ধারণা হলো ক্লায়েন্ট তালিকার প্রথমটা নেবে, তাই লোড ছড়িয়ে যাবে।
কেন লোড আসলে সমানভাবে ছড়ায় না
বাস্তবে কয়েকটা কারণে round robin প্রায়ই অসমান হয়:
- resolver ক্যাশ: একটা বড় ISP resolver একবার উত্তর ক্যাশ করে হাজার হাজার ইউজারকে একই ক্রমে দিতে পারে। কিছু resolver ক্যাশ থেকে দেওয়ার সময় ক্রম ঘোরায়, কিছু ঘোরায় না।
- ক্লায়েন্টের নিজের সর্টিং:
getaddrinfo()ক্রমটা হুবহু রাখে না। RFC 6724 (আগে RFC 3484) এর destination address selection নিয়ম ঠিক করে কোন ঠিকানা আগে আসবে: IPv6 না IPv4, কোনটা “কাছের” (scope), আর একটা নিয়মে যে ঠিকানা ক্লায়েন্টের নিজের ঠিকানার সাথে সবচেয়ে লম্বা prefix মেলায় সেটা আগে। ফলে একই সাবনেটের সব ক্লায়েন্ট বারবার একই সার্ভার বেছে নিতে পারে। - লম্বা কানেকশন: HTTP/2, gRPC বা WebSocket কানেকশন ঘণ্টার পর ঘণ্টা খোলা থাকে। নতুন সার্ভার যোগ করলেও পুরনো কানেকশনগুলো সেখানে যায় না।
- ব্যর্থ সার্ভার জানার উপায় নেই: একটা সার্ভার মরে গেলেও DNS তার IP দিতেই থাকে। ভালো ক্লায়েন্ট (ব্রাউজার,
curl) পরের IP চেষ্টা করে, কিন্তু প্রথমটার টাইমআউট পর্যন্ত অপেক্ষা করে। অনেক লাইব্রেরি শুধু প্রথম IP চেষ্টা করে হাল ছেড়ে দেয়।
একাধিক A রেকর্ডের আসল শক্তি load balancing না, redundancy। ক্লায়েন্ট একটায় কানেক্ট করতে না পারলে পরেরটা চেষ্টা করতে পারে। Happy Eyeballs (RFC 8305) ঠিক এই কাজটা IPv6 আর IPv4 মিলিয়ে দ্রুত করে। সমান লোড চাইলে তালিকার পেছনে আসল load balancer রাখুন।
GeoDNS: প্রশ্নকারী কোথায়?
GeoDNS-এ authoritative সার্ভার query-র সোর্স IP দেখে, একটা GeoIP ডেটাবেসে খুঁজে দেশ বা অঞ্চল বের করে, আর সেই অঞ্চলের সার্ভারের IP ফেরত দেয়।
; conceptual policy
cdn.baytalhikma.org from Asia -> 203.0.113.10 (Singapore)
cdn.baytalhikma.org from Europe -> 198.51.100.10 (Frankfurt)
cdn.baytalhikma.org default -> 192.0.2.10 (Virginia) নির্ভুলতার সমস্যা: resolver ইউজার না
authoritative সার্ভার কখনো ইউজারের IP দেখে না। সে দেখে resolver-এর IP। ঢাকার একজন ইউজার যদি একটা পাবলিক resolver ব্যবহার করেন যার ঢাকায় কোনো নোড নেই, authoritative সার্ভার ভাববে প্রশ্নটা এসেছে সিঙ্গাপুর বা অন্য কোথাও থেকে। কোম্পানির VPN দিয়ে বাইরে যাওয়া কর্মচারীর resolver হয়তো অন্য মহাদেশে। ফলে GeoDNS ভুল অঞ্চলের সার্ভার দেয়।
EDNS Client Subnet (ECS)
এর সমাধান ECS (RFC 7871): resolver query-র সাথে EDNS অপশনে ইউজারের IP-র একটা ছোট করা অংশ পাঠায়, সাধারণত IPv4-এ /24 আর IPv6-এ /56। authoritative সার্ভার তখন resolver-এর অবস্থান না, ইউজারের সাবনেট দেখে উত্তর দেয়, আর উত্তরে বলে দেয় এই উত্তর কোন scope-এর জন্য খাটে।
$ dig +subnet=203.0.113.0/24 cdn.baytalhikma.org @ns1.baytalhikma.org
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; CLIENT-SUBNET: 203.0.113.0/24/24
;; ANSWER SECTION:
cdn.baytalhikma.org. 60 IN A 203.0.113.10 (আউটপুট উদাহরণস্বরূপ।) 203.0.113.0/24/24-এর মানে: query-তে /24 পাঠানো হয়েছিল, আর সার্ভার বলছে এই উত্তরটা পুরো /24-এর জন্য ক্যাশ করা যাবে (scope prefix)। scope যদি /16 হতো, resolver উত্তরটা আরও বড় এলাকার সবার জন্য ক্যাশ করতে পারত।
আপনার resolver ECS পাঠায় কিনা Google-এর একটা বিশেষ নাম দিয়ে দেখা যায়:
$ dig +short TXT o-o.myaddr.l.google.com @8.8.8.8
"74.125.178.209"
"edns0-client-subnet 203.0.113.0/24" প্রথম লাইন resolver-এর নিজের IP যেটা দিয়ে Google-এর authoritative সার্ভারে এসেছে, দ্বিতীয় লাইন সেই resolver ECS-এ আপনার কোন সাবনেট পাঠিয়েছে।
ECS-এর দাম
- প্রাইভেসি: আপনার সাবনেট এখন প্রতিটা authoritative সার্ভারের কাছে যায়, শুধু resolver-এর কাছে না। এজন্য কিছু পাবলিক resolver ইচ্ছা করে ECS পাঠায় না। যেমন Cloudflare-এর 1.1.1.1 ঘোষিতভাবে ECS পাঠায় না, আর Google Public DNS পাঠায় (২০২৬ সালের অক্টোবর অনুযায়ী; প্রোভাইডারের নিজের প্রাইভেসি পেজে মিলিয়ে নিন)।
- ক্যাশ ভাঙে: একটা উত্তর আর সব ইউজারের জন্য এক না, প্রতিটা সাবনেটের জন্য আলাদা। resolver-এর ক্যাশ hit rate কমে যায়।
- সব সার্ভার পায় না: resolver সাধারণত শুধু সেই authoritative সার্ভারকে ECS পাঠায় যারা এটা চায় বা যাদের তালিকায় রেখেছে।
Weighted আর latency-ভিত্তিক রাউটিং
Weighted: প্রতিটা রেকর্ডের একটা ওজন থাকে, সার্ভার সেই অনুপাতে উত্তর দেয়। ব্যবহার: নতুন রিজিয়ন বা নতুন ভার্সনে ধীরে ধীরে ট্রাফিক সরানো (৫%, ২৫%, ১০০%), বা বড় আর ছোট ক্লাস্টারের ক্ষমতা অনুযায়ী ভাগ।
; conceptual policy
api.baytalhikma.org weight 90 -> 192.0.2.10 (current fleet)
api.baytalhikma.org weight 10 -> 198.51.100.10 (canary fleet) মনে রাখবেন, ওজনটা DNS উত্তরের অনুপাত, request-এর না। একটা resolver একবার “canary” উত্তর পেলে TTL পর্যন্ত তার পেছনের হাজারো ইউজার canary-তে যাবে। বড় resolver কয়েকটা হলে আসল ভাগ অনেক অসমান হতে পারে।
Latency-ভিত্তিক: প্রোভাইডার আগে থেকে মেপে রাখে কোন নেটওয়ার্ক থেকে কোন রিজিয়ন সবচেয়ে দ্রুত, আর query যে resolver (বা ECS সাবনেট) থেকে আসে তার জন্য সবচেয়ে কম latency-র রিজিয়ন দেয়। ভূগোল আর নেটওয়ার্ক দূরত্ব এক না: ঢাকা থেকে সিঙ্গাপুর আর মুম্বাইয়ের মধ্যে কোনটা দ্রুত, সেটা ম্যাপ দেখে বলা যায় না, সাবমেরিন কেবল আর পিয়ারিং ঠিক করে।
এগুলোর বেশিরভাগ স্ট্যান্ডার্ড DNS ফিচার না, ম্যানেজড DNS প্রোভাইডারের নিজস্ব পলিসি ইঞ্জিন। নিজে চালাতে চাইলে PowerDNS-এর Lua রেকর্ড বা GeoIP ব্যাকএন্ড, অথবা gdnsd-এর মতো সফটওয়্যার আছে।
Health-checked failover আর TTL-এর অঙ্ক
failover রেকর্ডে প্রোভাইডার নিয়মিত সার্ভারগুলোতে health check চালায় (HTTP, TCP)। প্রাইমারি অসুস্থ হলে সে সেকেন্ডারির IP দিতে শুরু করে।
worst-case failover সময়ের অঙ্কটা মনে রাখুন:
worst case = detection time + record TTL + client-side caching + connection reuse
detection = check interval x failure threshold (e.g. 30s x 3 = 90s)
record TTL = 60s
client = whatever the OS, runtime, or app keeps on top of TTL
connections = long-lived keep-alive or HTTP/2 connections to the dead IP এখানে ৯০ + ৬০ = আড়াই মিনিট সবচেয়ে ভালো পরিস্থিতি। তার ওপর:
- কিছু resolver কম TTL মানে না, নিজের একটা ন্যূনতম বসিয়ে দেয়।
- রানটাইম নিজের ক্যাশ রাখে। যেমন Java-র JVM
networkaddress.cache.ttlপ্রপার্টি অনুযায়ী ক্যাশ করে, যা DNS-এর TTL থেকে আলাদা। পুরনো কনফিগারেশনে এটা “চিরকাল” হতে পারে। - অ্যাপ নিজে একবার resolve করে IP মনে রাখলে (কনফিগে বা কানেকশন পুলে), DNS বদলালেও কিছু হয় না যতক্ষণ না রিস্টার্ট হয়।
- যে কানেকশন আগে থেকে খোলা ছিল, মরা সার্ভারের সাথে সেটা টাইমআউট না হওয়া পর্যন্ত আটকে থাকতে পারে।
খুব ছোট TTL সমাধান না। TTL ৫ সেকেন্ড করলে failover দ্রুত হবে না, শুধু প্রতিটা ইউজার প্রায় প্রতিটা request-এ একটা DNS লুকআপের latency খাবে আর আপনার DNS বিল বাড়বে। ৩০ থেকে ৩০০ সেকেন্ড বেশিরভাগ ক্ষেত্রে যুক্তিসঙ্গত। সেকেন্ডের মধ্যে failover দরকার হলে DNS-এর পেছনে একটা স্থির IP রাখুন (anycast বা floating IP সহ load balancer) আর failover সেখানে করুন।
health check নিজেই ভুল করতে পারে
- health checker যদি শুধু একটা লোকেশন থেকে চেক করে, তার নিজের নেটওয়ার্ক সমস্যায় সুস্থ সার্ভারকেও মৃত ঘোষণা করবে। ভালো প্রোভাইডার কয়েকটা লোকেশনের সম্মতি নেয়।
- সব সার্ভার একসাথে “অসুস্থ” হলে কী উত্তর দেবে? বেশিরভাগ প্রোভাইডার তখন সবগুলোই দেয় (fail open), কারণ শূন্য উত্তরের চেয়ে হয়তো-কাজ-করে উত্তর ভালো। এটা জেনে রাখুন।
- health check endpoint শুধু “প্রসেস চলছে” দেখলে চলবে না, ডেটাবেসে পৌঁছাতে পারছে কিনা তাও দেখা উচিত। আবার এত গভীর হলে চলবে না যে একটা নির্ভরতা ধীর হলেই সব রিজিয়ন একসাথে বাদ পড়ে।
Anycast: একই IP, অনেক জায়গায়
anycast-এ একই IP prefix অনেকগুলো ডেটাসেন্টার থেকে BGP দিয়ে ঘোষণা করা হয়। ইন্টারনেটের রাউটিং নিজেই প্রতিটা প্যাকেটকে নেটওয়ার্কের হিসেবে কাছের লোকেশনে পাঠায়। DNS-এ উত্তর একটাই, বৈচিত্র্য আসে নেটওয়ার্ক লেয়ারে।
DNS নিজে anycast-এর সবচেয়ে পুরনো আর সফল ব্যবহারকারী। ১৩টা root সার্ভার “লেটার” আছে, কিন্তু anycast দিয়ে সারা পৃথিবীতে তাদের মোট ২,০৪৯টা instance চলছে (root-servers.org অনুযায়ী, ২০২৬ সালের অক্টোবরে; সংখ্যাটা নিয়মিত বাড়ে)। 1.1.1.1, 8.8.8.8, 9.9.9.9 সবই anycast। প্রায় সব ম্যানেজড DNS প্রোভাইডারের authoritative nameserver-ও anycast।
| বিষয় | GeoDNS | Anycast |
|---|---|---|
| কোথায় সিদ্ধান্ত হয় | DNS উত্তরে | BGP রাউটিংয়ে |
| ইউজার কী দেখে | অঞ্চলভেদে আলাদা IP | সবাই একই IP |
| ফেইলওভারের গতি | detection + TTL + ক্যাশ | BGP withdraw, সাধারণত সেকেন্ড থেকে মিনিট |
| নির্ভুলতার সমস্যা | resolver-এর অবস্থান | BGP পথ সবসময় সবচেয়ে কম latency-র পথ না |
| কী লাগে | GeoIP ডেটাবেস, পলিসি ইঞ্জিন | নিজের IP prefix, ASN, একাধিক PoP-এ BGP সেশন |
anycast-এর একটা দুর্বলতা: BGP পথ মাঝপথে বদলালে একটা TCP কানেকশনের প্যাকেট হঠাৎ অন্য PoP-এ চলে যেতে পারে, যে কানেকশনটা চেনে না। UDP-র এক-প্যাকেট DNS-এর জন্য এটা কোনো সমস্যা না, এজন্যই DNS আর anycast এত ভালো জুটি।
CDN-এর CNAME চেইন
একটা CDN ব্যবহার করলে সাধারণত আপনি নিজের নামকে CDN-এর একটা নামে CNAME করেন। তারপর CDN নিজের DNS দিয়ে ঠিক করে আপনাকে কোন edge দেবে।
$ dig www.baytalhikma.org +noall +answer
www.baytalhikma.org. 300 IN CNAME baytalhikma.cdn-provider.example.
baytalhikma.cdn-provider.example. 60 IN CNAME edge-dac.g.cdn-provider.example.
edge-dac.g.cdn-provider.example. 20 IN A 203.0.113.77
edge-dac.g.cdn-provider.example. 20 IN A 203.0.113.78 (আউটপুট উদাহরণস্বরূপ।) চেইনটা পড়ুন:
- আপনার রেকর্ড (TTL ৩০০): আপনার নিয়ন্ত্রণে, শুধু বলে “এটা CDN-এর কাছে”।
- CDN-এর কাস্টমার নাম (TTL ৬০): CDN জানে কোন কনফিগারেশন আপনার।
- edge নাম আর A রেকর্ড (TTL ২০): এখানে CDN-এর GeoDNS বা latency ম্যাপ resolver/ECS দেখে কাছের edge বেছে নেয়। ছোট TTL কারণ CDN লোড আর স্বাস্থ্য অনুযায়ী দ্রুত বদলাতে চায়।
চেইনের প্রতিটা ধাপ আলাদা লুকআপ হতে পারে (resolver ক্যাশে না থাকলে), তাই লম্বা CNAME চেইন প্রথম লুকআপকে ধীর করে। আর প্রতিটা ধাপের TTL আলাদা, তাই ফলাফলের বয়স ঠিক করে সবচেয়ে ছোট TTL।
ভুল edge পাচ্ছেন মনে হলে দুটো জিনিস তুলনা করুন: dig +short whoami.cloudflare TXT CH @1.1.1.1 বা o-o.myaddr.l.google.com দিয়ে আপনার resolver কোথা থেকে আসছে, আর dig +subnet=আপনার-সাবনেট/24 দিয়ে CDN কী দেয়। প্রায়ই দেখা যায় সমস্যাটা CDN-এ না, resolver-এর অবস্থানে।
Apex সমস্যা আর ALIAS
zone-এর মূল নাম (apex), যেমন baytalhikma.org, সেখানে CNAME রাখা যায় না। কারণ apex-এ সবসময় SOA আর NS রেকর্ড থাকে, আর CNAME-এর নিয়ম হলো একই নামে আর কোনো রেকর্ড থাকতে পারবে না (চ্যাপ্টার ৩)। অথচ CDN বা ক্লাউড load balancer দেয় একটা নাম, স্থির IP না।
সমাধানগুলো:
- ALIAS / ANAME / CNAME flattening: প্রোভাইডার নিজের ভেতরে লক্ষ্য নামটা resolve করে, আর উত্তরে আপনার apex-এর জন্য সরাসরি A/AAAA রেকর্ড দেয়। বাইরে থেকে দেখলে এটা একটা সাধারণ A রেকর্ড। এটা কোনো স্ট্যান্ডার্ড না, প্রোভাইডারের নিজস্ব ফিচার, প্রত্যেকে আলাদা নামে ডাকে (Route 53-এ alias record, Cloudflare-এ CNAME flattening)।
- দুর্বলতা: লক্ষ্য নামটা এখন resolve করছে আপনার DNS প্রোভাইডার, ইউজারের resolver না। CDN যদি GeoDNS করে, সে দেখবে প্রোভাইডারের অবস্থান। ভালো প্রোভাইডার এখানে ECS পাঠায়, সবাই পাঠায় না।
- HTTPS রেকর্ড (RFC 9460): এর AliasMode apex-এ CNAME-এর মতো কাজ করতে পারে, কিন্তু এটা শুধু HTTPS রেকর্ড চায় এমন ক্লায়েন্টের জন্য, আর A রেকর্ড চাওয়া পুরনো ক্লায়েন্ট এটা দেখে না। তাই এখনো A/AAAA লাগে।
- সবচেয়ে সহজ: apex-কে
www-তে HTTP redirect করুন, আরwww-তে CNAME রাখুন। apex-এ তখন শুধু redirect সার্ভারের একটা স্থির A রেকর্ড লাগে।
DNS কেন দুর্বল load balancer, তবু কেন ব্যবহার হয়
দুর্বলতাগুলো একসাথে:
- নিয়ন্ত্রণ ক্যাশে হারায়: উত্তর দেওয়ার পর TTL পর্যন্ত আপনার কিছু করার নেই, আর অনেক ক্লায়েন্ট TTL-ও মানে না।
- দৃশ্যমানতা resolver পর্যন্ত: আপনি দেখেন resolver কতবার জিজ্ঞেস করল, কতজন ইউজার এলো বা কত request হলো না।
- request-লেভেল কিছু নেই: কোন URL, কোন হেডার, কোন সেশন, DNS কিছুই জানে না।
- health check-এর ফাঁক: detection আর ক্যাশ মিলে failover মিনিটের হিসাবে।
তবু DNS ছাড়া চলে না, কারণ একমাত্র DNS-ই ইউজার কানেক্ট করার আগে সিদ্ধান্ত নিতে পারে। একটা আসল load balancer শুধু সেই ট্রাফিক ভাগ করতে পারে যেটা তার কাছে পৌঁছেছে; ঢাকার ইউজারকে ভার্জিনিয়ার load balancer পর্যন্ত যেতে দেওয়ার আগেই সিঙ্গাপুরে পাঠানো DNS-এর কাজ।
তাই প্রোডাকশনে সাধারণ গঠন হলো দুই স্তর:
DNS (coarse, minutes) -> which region / which provider / which anycast IP
Load balancer (fine, ms) -> which healthy instance, per request, with retries DNS দিয়ে বড় সিদ্ধান্ত (রিজিয়ন, প্রোভাইডার, ধীরে ধীরে মাইগ্রেশন), load balancer দিয়ে ছোট আর দ্রুত সিদ্ধান্ত।
ডিবাগিং: এই চ্যাপ্টারের সমস্যাগুলো
লক্ষণ: একটা রিজিয়নের সার্ভার বন্ধ, কিন্তু DNS বদলানোর অনেক পরেও ইউজাররা সেখানে যাচ্ছে। যাচাই: dig +noall +answer api.baytalhikma.org @8.8.8.8 আর @1.1.1.1 দিয়ে দেখুন resolver কী দিচ্ছে আর বাকি TTL কত। resolver নতুন উত্তর দিলে সমস্যা ক্লায়েন্টে: অ্যাপের নিজের DNS ক্যাশ (JVM networkaddress.cache.ttl), কানেকশন পুল, বা কনফিগে লেখা IP। সমাধান: রানটাইম ক্যাশ TTL-এর কাছাকাছি নামান, কানেকশনের সর্বোচ্চ বয়স সেট করুন, আর ভবিষ্যতে failover রিজিয়ন বদলের আগে TTL কমিয়ে রাখুন।
লক্ষণ: বাংলাদেশের ইউজাররা ইউরোপের সার্ভারে যাচ্ছে। যাচাই: ইউজারের মেশিনে dig +short TXT o-o.myaddr.l.google.com চালান। প্রথম লাইনের IP কোথাকার? ECS লাইন আছে? resolver দূরের হলে আর ECS না থাকলে GeoDNS সেই resolver-এর অবস্থান দেখছে। সমাধান: latency/GeoDNS পলিসিতে ECS চালু করুন, বা anycast-ভিত্তিক সমাধানে যান যেখানে resolver-এর অবস্থান গুরুত্বপূর্ণ না।
লক্ষণ: weighted রাউটিংয়ে ১০% canary সেট করেছেন, কিন্তু মেট্রিকে ৩০% দেখাচ্ছে। এটা প্রত্যাশিত আচরণ: ওজন DNS উত্তরের, request-এর না। কয়েকটা বড় resolver canary উত্তর পেলে তাদের পেছনের সব ইউজার যায়। সূক্ষ্ম ভাগ দরকার হলে load balancer লেভেলে করুন।
লক্ষণ: round robin-এ একটা সার্ভার অন্যগুলোর চেয়ে অনেক বেশি লোড পাচ্ছে। যাচাই: ক্লায়েন্টগুলো কোন সাবনেটে, আর getent ahosts api.baytalhikma.org কোন ক্রম দেয় সেটা কয়েকটা মেশিনে দেখুন। RFC 6724-এর longest-prefix নিয়ম বা লম্বা কানেকশন প্রায়ই কারণ। সমাধান: DNS-এর পেছনে load balancer, বা ক্লায়েন্ট-সাইডে নিজে র্যান্ডমাইজ করা।
লক্ষণ: apex ডোমেইন CDN-এ পয়েন্ট করতে গিয়ে প্রোভাইডার বলছে “CNAME not allowed”। এটা DNS-এর নিয়ম, প্রোভাইডারের দোষ না। প্রোভাইডারের ALIAS/flattening ফিচার ব্যবহার করুন, অথবা apex থেকে www-তে redirect দিন।
লক্ষণ: CDN-এর পেছনে সাইট মাঝে মাঝে ধীর, প্রথম লোড বিশেষভাবে। যাচাই: dig +trace www.baytalhikma.org বা dig +noall +answer +stats দিয়ে CNAME চেইনের দৈর্ঘ্য আর প্রতিটা ধাপের query time দেখুন। তিন-চার ধাপের চেইন, যার প্রতিটা আলাদা TLD-তে, প্রথম লুকআপে কয়েকশো মিলিসেকেন্ড যোগ করতে পারে। সমাধান: অপ্রয়োজনীয় ধাপ বাদ দিন, আর পেজে dns-prefetch/preconnect ব্যবহার করুন।
মূল শিক্ষা
- DNS ট্রাফিক বহন করে না, শুধু প্রশ্নের উত্তর বদলায় — কে জিজ্ঞেস করছে, কখন, আর কে সুস্থ, তার ভিত্তিতে।
- একাধিক A রেকর্ড মূলত redundancy, সমান load balancing না; resolver ক্যাশ, RFC 6724 সর্টিং আর লম্বা কানেকশন ভাগকে অসমান করে।
- GeoDNS দেখে resolver-এর অবস্থান, ইউজারের না। ECS এটা ঠিক করে, কিন্তু ইউজারের সাবনেট ফাঁস করে আর ক্যাশ ভাঙে।
- weighted ওজন DNS উত্তরের অনুপাত, request-এর না।
- failover-এর worst case = detection + TTL + ক্লায়েন্ট ক্যাশ + খোলা কানেকশন। খুব ছোট TTL এর সমাধান না; সেকেন্ডের failover চাইলে স্থির IP-র পেছনে করুন।
- anycast সিদ্ধান্তটা DNS থেকে BGP-তে সরিয়ে দেয়, আর DNS নিজেই এর সবচেয়ে বড় ব্যবহারকারী।
- apex-এ CNAME চলে না; ALIAS/flattening প্রোভাইডারের নিজস্ব সমাধান, আর
www-তে redirect সবচেয়ে সহজ। - DNS মোটা দাগের সিদ্ধান্তের জন্য, load balancer সূক্ষ্ম সিদ্ধান্তের জন্য — দুটো মিলিয়ে ব্যবহার করুন।