DNS — 이름을 주소로 바꾸는 거대한 전화번호부
사람은 naver.com을 기억하지만, 컴퓨터는 223.130.200.107 같은 IP로만 통신한다. 이 둘 사이를 통역하는 게 **DNS(Domain Name System)**다. 그냥 "이름→IP 표"라고 하면 간단해 보이지만 — 전 세계에 수십억 개의 도메인이 있고 매 순간 바뀐다. 이걸 한 대의 서버가 감당할 수는 없다. DNS의 진짜 묘미는 이 거대한 표를 어떻게 전 세계에 나눠 담고, 빠르게 찾고, 갱신하느냐에 있다. 그 답이 계층적 분산 + 캐싱이다.
표를 나눠 담는다 — 계층적 위임
DNS는 이름을 오른쪽부터 점으로 끊어 트리로 관리한다. www.naver.com.은 — 맨 오른쪽 루트(.) → .com(TLD) → naver.com(권한 서버) → 그 안의 www다. 각 단계는 *"그 아래는 내가 모르니, 저 서버에게 물어봐"*라고 위임한다.
루트 서버는 전 세계에 13개 그룹(잘 알려진 고정 IP)이 있고, 그 아래로 책임이 가지처럼 나뉜다. 덕분에 naver.com의 레코드를 바꿀 권한은 naver만 갖고(자기 권한 서버에서), 루트나 .com 서버는 "저쪽으로 가라"는 이정표만 들고 있으면 된다 — 수십억 도메인이 한 곳에 안 모여도 되는 비결이다. (출처: Cloudflare — Recursive DNS.)
누가 발품을 파나 — 재귀 리졸버와 반복 질의
그럼 이 트리를 누가 따라 내려가 답을 찾을까? 보통 우리 컴퓨터는 직접 안 한다 — *"알아서 찾아서 IP만 알려줘"*라고 재귀 리졸버(ISP나 8.8.8.8 같은)에게 통째로 맡긴다(재귀 질의). 그러면 리졸버가 발품을 판다 — 루트에 물어 .com 서버 주소를 받고, .com에 물어 naver의 권한 서버를 받고, 거기서 최종 IP를 받는다(각 단계는 반복 질의). 즉 *클라이언트→리졸버는 재귀(맡김), 리졸버→서버들은 반복(직접 추적)*이다.
매번 발품 팔면 느리다 — 캐싱과 TTL
이 추적을 매 접속마다 하면 느리고 루트 서버가 터진다. 그래서 모든 단계가 캐싱한다 — 리졸버도, OS도, 브라우저도 한 번 알아낸 답을 잠시 저장한다. 얼마나 저장할지는 각 레코드에 붙은 TTL이 정한다. TTL이 길면 캐시가 오래 살아 빠르지만 변경 반영이 느리고, 짧으면 자주 갱신돼 최신성은 좋지만 질의가 잦다 — 전형적인 트레이드오프다(캐시 편의 그 고민과 같다). 자주 보는 레코드 종류는 — A(이름→IPv4), AAAA(이름→IPv6), CNAME(이름→다른 이름의 별칭), MX(메일 서버), TXT(검증·설정), NS(권한 서버 지정)다. (출처: DNS record types.)
실무에서는 — "DNS 바꿨는데 왜 아직 옛날로 가요?" 바로 이 TTL 캐싱 때문이다. 레코드를 바꿔도 전 세계 리졸버 캐시가 옛 TTL이 만료될 때까지 옛 IP를 들고 있어 — 전파(propagation)에 시간이 걸린다. 그래서 서버 이전·도메인 변경 전에는 미리 TTL을 짧게 낮춰 두는 게 정석이다. 또 DNS는 그 자체로 로드밸런싱·장애조치 도구다 — 한 이름에 여러 A 레코드를 두거나(라운드로빈), 지역·상태에 따라 다른 IP를 응답해 트래픽을 분산한다. 디버깅엔
dig·nslookup이 각 단계의 응답을 까 보는 도구다. 그리고 페이지 로딩의 첫 병목이 DNS일 때가 많아, 성능에선 DNS 캐시·프리페치가 의외로 중요하다.
정리하면, DNS는 이름을 IP로 바꾸는데 — 그 거대한 표를 계층적으로 위임해 나눠 담고(루트→TLD→권한 서버), 재귀 리졸버가 발품을 팔아 추적하며(클라이언트는 맡기고, 리졸버는 반복 질의로 추적), 각 단계의 캐싱과 TTL로 빠르고 확장 가능하게 만든다. 그 TTL이 변경 전파 지연의 원인이자 로드밸런싱·장애조치의 지렛대이기도 하다. 이름이 IP로 풀리고 TCP 연결까지 섰으면 — 이제 그 위로 실제 요청과 응답을 주고받을 차례다. 그게 HTTP다.