소개: DNS 지연 시간의 원인과 완화
웹페이지가 더 복잡해짐에 따라 수많은 도메인의 리소스를 참조하는 경우, DNS 조회가 탐색 환경에서 심각한 병목 현상을 유발할 수 있습니다. 클라이언트가 네트워크를 통해 DNS 리졸버를 쿼리해야 할 때마다 리졸버가 쿼리해야 하는 근접도와 네임서버 수에 따라 지연 시간이 상당히 많을 수 있습니다 (3개를 초과하는 경우는 드물지만 발생할 수 있음). 예를 들어 다음 스크린샷은 Page Speed 웹 성능 측정 도구에서 보고한 시간을 보여줍니다. 각 막대는 페이지에서 참조된 리소스를 나타내고 검은색 세그먼트는 DNS 조회를 나타냅니다. 이 페이지에서는 페이지가 로드되는 처음 11초 동안 13회의 조회를 수행합니다. 여러 조회가 동시에 실행되지만 이 스크린샷을 보면 5회의 연속 조회 시간이 필요하며 이는 총 11초의 페이지 로드 시간 중 몇 초를 차지합니다.
DNS 지연 시간에는 두 가지 구성요소가 있습니다.
- 클라이언트 (사용자)와 DNS 확인 서버 간의 지연 시간입니다. 대부분의 경우 이러한 현상은 클라이언트 머신과 서버 머신 간의 지리적 거리, 네트워크 정체, 패킷 손실 및 긴 재전송 지연 시간 (평균 1초), 과부하된 서버, 서비스 거부 공격 등 네트워크 시스템의 일반적인 왕복 시간(RTT) 제약 조건으로 인해 발생합니다.
- 서버와 다른 네임서버 확인 간의 지연 시간
이 지연 시간 원인은 주로 다음과 같은 요인으로 인해 발생합니다.
- 캐시 부적중 리졸버의 캐시에서 응답을 제공할 수 없지만 다른 네임서버를 재귀적으로 쿼리해야 하는 경우, 특히 권한 서버가 지리적으로 멀리 떨어져 있는 경우 추가된 네트워크 지연 시간이 상당히 길어집니다.
- 언더프로비저닝 DNS 리졸버가 과부하되면 DNS 확인 요청 및 응답을 큐에 추가해야 하며, 패킷을 삭제하고 재전송하기 시작할 수 있습니다.
- 악성 트래픽. DNS 서비스가 초과 프로비저닝되더라도 DoS 트래픽으로 인해 서버에 과도한 부하가 발생할 수 있습니다. 마찬가지로 Kaminsky 스타일 공격에는 캐시를 우회하고 해결을 위해 나가는 요청이 필요한 쿼리를 사용하여 리졸버를 플러딩할 수 있습니다.
캐시 부적중 요인은 DNS 지연 시간의 가장 큰 원인이라고 생각하며 아래에서 자세히 설명합니다.
캐시 부적중
리졸버에 로컬 리소스가 풍부하더라도 원격 네임서버와의 통신과 관련된 근본적인 지연을 방지하기는 어렵습니다. 즉, 서버 측에서 캐시 적중 시간이 0이 될 만큼 리졸버가 충분히 잘 프로비저닝되었다고 가정하면 캐시 부적중이 지연 시간 측면에서 매우 높은 비용으로 유지됩니다. 누락을 처리하려면 리졸버가 하나 이상의 외부 네임서버와 통신해야 하지만 종종 두 개 이상의 외부 네임서버와 통신해야 합니다. Googlebot 웹 크롤러를 작동한 결과 응답하는 네임서버의 평균 확인 시간은 130ms입니다. 하지만 요청의 4~6% 가 UDP 패킷 손실과 서버에 연결할 수 없어 타임아웃됩니다. 패킷 손실, 데드 네임서버, DNS 구성 오류 등의 장애를 고려하면 실제 평균 엔드 투 엔드 확인 시간은 300~400ms입니다. 그러나 편차가 크고 롱테일이 많습니다.
캐시 부적중 비율은 DNS 서버마다 다를 수 있지만 캐시 부적중은 근본적으로 피하기가 어려운데 그 이유는 다음과 같습니다.
- 인터넷 규모와 성장 간단히 말해, 신규 사용자 및 신규 사이트 증가를 통해 인터넷이 성장함에 따라 대부분의 콘텐츠가 한계로 관심을 끕니다. 일부 사이트 (및 결과적으로 DNS 이름)는 매우 인기가 있지만 대부분은 일부 사용자만 관심을 가지고 액세스되는 경우가 드물기 때문에 대부분의 요청은 캐시 부적중을 초래합니다.
- TTL (수명) 값이 낮습니다. DNS TTL 값이 낮아지는 추세는 확인 시 더 자주 조회해야 함을 의미합니다.
- 캐시 격리 DNS 서버는 일반적으로 다른 머신에 쿼리를 무작위로 할당하는 부하 분산기 뒤에 배포됩니다. 그 결과, 개별 서버는 공유 풀에서 캐시된 해상도를 재사용하는 대신 개별 캐시를 유지합니다.
완화 조치
Google Public DNS에서는 DNS 조회 시간을 단축하기 위해 여러 가지 방법을 구현했습니다. 일부 접근 방식은 상당히 표준이며 다른 접근 방식은 실험용입니다.
- 악성 트래픽을 포함한 클라이언트 트래픽의 부하를 처리하기 위해 서버를 적절하게 프로비저닝합니다.
- DoS 및 증폭 공격 방지 이는 대부분 보안 문제이며 열린 리졸버보다 폐쇄된 리졸버에 영향을 미치지만, DoS 공격을 방지하면 DNS 서버에 발생하는 추가적인 트래픽 부담을 제거하여 성능상의 이점도 얻을 수 있습니다. 공격 가능성을 최소화하기 위해 사용하는 접근 방식에 관한 자세한 내용은 보안 이점 페이지를 참고하세요.
- 공유 캐싱 부하 분산: 제공 클러스터 전체에서 집계된 캐시 적중률을 향상시킵니다.
- 모든 사용자와 인접할 수 있도록 전 세계 도달 범위 제공
적절한 서빙 클러스터 프로비저닝
DNS 리졸버 캐싱은 권한 네임서버보다 비용이 많이 드는 작업을 실행해야 합니다. 많은 응답을 메모리에서 제공할 수 없기 때문입니다. 대신 다른 네임서버와의 통신이 필요하므로 많은 네트워크 입력/출력이 필요합니다. 또한 개방형 리졸버는 캐시 포이즈닝 시도 (이러한 공격은 특히 캐시에서 해결할 수 없는 가짜 이름에 대한 요청을 전송함)를 증가시키는 캐시 포이즈닝 시도 및 트래픽 부하에 추가되는 DoS 공격에 매우 취약합니다. 리졸버가 적절하게 프로비저닝되지 않아 부하를 감당할 수 없으면 성능에 매우 부정적인 영향을 미칠 수 있습니다. 패킷이 삭제되어 재전송해야 하며 네임서버 요청을 큐에 추가해야 하는 식입니다. 이러한 모든 요인이 지연을 초래합니다.
따라서 DNS 리졸버를 대용량 입력/출력에 맞게 프로비저닝하는 것이 중요합니다. 여기에는 가능한 DDoS 공격 처리가 포함되며, 이 경우 많은 머신을 과도하게 프로비저닝하는 것이 효과적인 해결책입니다. 그러나 머신을 추가할 때 캐시 적중률을 낮추지 않는 것이 중요합니다. 이를 위해서는 아래에서 설명하는 효과적인 부하 분산 정책을 구현해야 합니다.
공유 캐싱을 위한 부하 분산
머신을 추가하여 리졸버 인프라를 확장하면 부하 분산이 제대로 수행되지 않으면 실제로는 역효과를 내고 캐시 적중률을 줄일 수 있습니다. 일반적인 배포에서는 라운드 로빈과 같은 간단한 알고리즘을 사용하여 각 머신에 트래픽을 균일하게 분산하는 부하 분산기 뒤에 여러 머신이 배치됩니다. 결과적으로 각 머신은 자체적인 독립 캐시를 유지하여 캐시된 콘텐츠가 여러 시스템에서 격리됩니다. 각 수신 쿼리가 트래픽의 특성에 따라 임의의 머신에 분산되면 유효 캐시 부적중률이 이에 비례하여 증가할 수 있습니다. 예를 들어 TTL이 긴 이름이 반복적으로 쿼리되면 캐시 부적중률이 클러스터에 있는 머신 수만큼 증가할 수 있습니다. TTL이 매우 짧거나 쿼리 빈도가 매우 낮거나 캐시할 수 없는 응답(TTL 및 오류 0)이 발생하는 이름의 경우 머신을 추가해도 캐시 부적중 발생률은 실제로 영향을 받지 않습니다.
캐시 가능한 이름의 적중률을 높이려면 캐시가 파편화되지 않도록 서버의 부하를 분산하는 것이 중요합니다. Google Public DNS에는 두 가지 수준의 캐싱이 있습니다. 사용자와 매우 가까운 하나의 머신 풀에서는 작은 컴퓨터별 캐시에 가장 많이 사용되는 이름이 포함되어 있습니다. 이 캐시에서 쿼리를 처리할 수 없으면 이름을 기준으로 캐시를 파티션으로 나누는 다른 머신 풀로 쿼리가 전송됩니다. 이 2단계 캐시의 경우 이름이 같은 모든 쿼리는 이름이 캐시되거나 캐시되지 않은 동일한 머신으로 전송됩니다.
넓은 지리적 범위를 위한 서빙 클러스터 분산
폐쇄적인 리졸버에게는 실제로 문제가 되지 않습니다. 개방형 리졸버의 경우 서버가 사용자와 더 가까울수록 클라이언트 측에서 발생하는 지연 시간이 짧아집니다. 또한 네임서버가 일반적으로 DNS 리졸버의 위치에 최적화된 결과를 반환하므로 지리적 범위가 충분하면 엔드 투 엔드 지연 시간이 간접적으로 향상될 수 있습니다. 즉, 콘텐츠 제공업체가 전 세계에서 미러링된 사이트를 호스팅하는 경우 제공업체의 네임서버는 DNS 리졸버에 가장 가까운 IP 주소를 반환합니다.
Google Public DNS는 전 세계 데이터 센터에서 호스팅되며 애니캐스트 라우팅을 사용하여 지리적으로 가장 가까운 데이터 센터로 사용자를 보냅니다.
또한 Google Public DNS는 리졸버가 클라이언트 위치를 네임서버로 전달하는 DNS 프로토콜 확장인 EDNS 클라이언트 서브넷 (ECS)을 지원합니다. 네임서버는 리졸버의 IP 주소가 아닌 실제 클라이언트 IP 주소에 최적화된 위치에 민감한 응답을 반환할 수 있습니다. 자세한 내용은 이 FAQ를 참고하세요. Google Public DNS는 EDNS 클라이언트 서브넷을 지원하는 네임서버를 자동으로 감지합니다.