Trawling

Cloudflare, DNS 캐시 저장 구조 바꿔 운영 메모리 약 100TB 절감

Cloudflare는 1.1.1.1과 Gateway DNS 등을 뒷받침하는 Big Pineapple의 DNS 캐시 저장 방식을 바꿔 운영 환경 전체의 메모리 사용 집계를 약 100TB 줄였다고 밝혔습니다. 무작위 생성 항목을 채운 벤치마크에서는 항목당 메모리가 953바이트에서 420바이트로 감소했고, 삽입 처리량은 43% 늘고 조회 지연은 19% 줄었습니다. 운영 환경의 메모리 집계와 벤치마크 성능은 서로 다른 측정 결과입니다.

Cloudflare 블로그에 글을 쓴 Sebastiaan Neuteboom은 2026년 8월 27일, 회사의 DNS 플랫폼 Big Pineapple에서 캐시 항목을 메모리에 저장하는 방식을 바꿔 전체 운영 환경의 메모리 사용 집계를 약 100TB 줄였다고 밝혔습니다. Big Pineapple은 1.1.1.1과 Gateway DNS, DNS Firewall, AS112 등 여러 Cloudflare DNS 서비스를 뒷받침하며, 한 시점에 2500억 개가 넘는 DNS 캐시 항목을 저장합니다. 이 규모에서는 항목 하나에서 1바이트를 줄여도 전체 메모리 사용량이 250GB 넘게 감소합니다.

DNS 캐시는 조회한 도메인 이름과 유형 등에 대한 응답을 저장합니다. 같은 조회가 들어오면 저장된 답을 활용하고, 항목 수가 한도에 이르면 오래됐거나 덜 쓰이는 항목을 내보내 자리를 만듭니다. 캐시 키는 조회 이름과 유형 등을 식별하고, 값에는 DNS 응답의 답변·권한·추가 레코드와 TTL, 적중 횟수 같은 정보가 담깁니다. 클라이언트 네트워크에 따라 권한 서버의 답이 달라지는 ECS가 쓰이면 같은 조회에도 여러 응답을 저장해야 해 메모리 부담이 커집니다.

Cloudflare가 먼저 손본 부분은 저장 후 바뀌지 않는 데이터에 남는 여유 공간입니다. Rust의 Vec와 String은 데이터 주소와 현재 길이뿐 아니라, 내용을 늘릴 때 쓸 용량도 기록합니다. 캐시에 넣은 DNS 응답은 이후 수정하지 않으므로 이 용량 정보와 앞으로 늘어날 공간이 필요하지 않습니다. 회사는 캐시 항목에 쓰던 Vec와 String 필드 8개를 고정 크기로 다루는 Box 형식으로 바꿨습니다. 용량 정보가 사라져 항목마다 64바이트를 줄였고, 앞으로 늘어날 공간으로 남겨 둔 메모리도 덜 썼습니다.

응답의 답변·권한·추가 레코드는 각각 별도 목록에 저장하는 대신 하나의 목록에 모았습니다. 목록마다 따로 저장하던 포인터와 길이 정보 대신 각 구역의 시작 위치를 2바이트 오프셋으로 표시해 항목당 28바이트를 절약했습니다. Rust 구조체에서 필드를 정렬할 때 생기는 빈 공간도 줄이도록 불리언 값 여러 개를 하나의 비트 플래그로 묶었습니다.

각 DNS 레코드에는 그 레코드가 속한 도메인 이름이 붙습니다. 이 이름이 조회한 도메인과 같으면 캐시에 따로 저장하지 않고, 응답을 만들 때 캐시 키에서 가져옵니다. CNAME 뒤에 이어지는 A 레코드처럼 레코드의 도메인 이름이 조회 이름과 다르면 전체 이름을 저장합니다.

레코드 종류별 자료를 담는 Rust 열거형은 가장 큰 자료형에 맞춰 공간을 잡습니다. NAPTR 자료 자체는 136바이트지만, 구분 정보와 정렬 여유를 포함하면 이를 담는 열거형은 144바이트입니다. 반면 A 레코드 자료는 4바이트, AAAA는 16바이트면 충분합니다. Cloudflare가 설명한 트래픽에서는 A와 AAAA가 80% 넘게 차지해, 흔한 레코드가 큰 자료형에 맞춘 공간을 낭비했습니다. 회사는 큰 자료형만 별도 메모리에 두고 A·AAAA 자료는 열거형 안에 남겼습니다. 다만 이 방식은 자료마다 별도 메모리 할당이 생기고 포인터를 따라가야 해 메모리 접근이 흩어지는 문제가 있었습니다.

Cloudflare가 택한 절충안은 DNS 응답 전체를 완성된 패킷 형태로 저장하는 대신 레코드 자료만 원시 바이트로 묶는 방식입니다. DNSSEC 자료는 클라이언트가 DO 플래그로 요청한 경우에만 응답에 포함됩니다. 완성된 응답을 저장하면 DNSSEC 자료가 있는 응답과 없는 응답을 각각 보관하거나, 조회 때 이미 만든 응답에서 자료를 걸러내야 합니다. 이에 회사는 각 레코드 앞에 2바이트 길이 정보를 붙여 하나의 연속된 바이트 영역에 저장하고, TTL 같은 나머지 항목 정보는 구조화된 필드로 유지했습니다. 이 형식은 레코드를 임의 순서로 바로 찾지 못하고 차례로 읽어야 합니다. A·AAAA 레코드 순서를 바꾸는 기능은 복잡해지지만, 항목마다 레코드 수가 적어 그 비용은 작다고 회사는 설명했습니다.

응답을 만들 때는 A·AAAA·TXT와 DNSSEC 레코드의 저장된 바이트를 새 응답에 바로 복사합니다. CNAME·NS·MX·SOA처럼 도메인 이름을 담은 레코드는 DNS 이름 압축을 적용해야 해 다시 읽습니다. 이름 압축은 메시지 안에 이미 나온 도메인 이름을 다시 길게 쓰는 대신, 그 이름이 있는 위치를 가리키는 방식입니다. 이전에는 저장된 레코드를 필드별로 다시 DNS 응답 형식으로 바꿔야 했지만, 새 방식에서는 해당 작업을 건너뛸 수 있습니다.

Cloudflare는 실제 트래픽 분포를 근사한 무작위 생성 항목으로 벤치마크했습니다. 항목마다 레코드 1~4개를 넣고 A 56%, AAAA 25%, TXT 19%로 구성했습니다. TXT는 다른 가변 길이 레코드 유형을 대신하도록 크기를 무작위로 정했습니다. 이 시험에서 항목당 메모리 사용량은 953바이트에서 420바이트로 56% 줄었습니다. 캐시 항목 삽입 처리량은 초당 62만5000건에서 89만3000건으로 43% 늘었고, 조회 지연은 828ns에서 670ns로 19% 감소했습니다. 이 수치는 생성한 캐시 항목을 대상으로 한 벤치마크 결과입니다.

운영 환경에서는 2026년 5월 18일부터 7월 6일까지 서비스를 순차적으로 갱신했습니다. 인스턴스가 재시작되면 캐시가 비었다가 다시 차므로 Cloudflare는 메모리 사용량이 안정된 구간을 기준으로 배포 전후를 비교했습니다. 인스턴스별 상주 메모리 분포의 p99는 9.3GB에서 5.3GB로 43% 줄었고, p90은 6.5GB에서 3.8GB로 42% 감소했습니다. 이 수치에는 캐시 외 프로세스 메모리도 포함되므로 캐시 항목만 측정한 벤치마크의 56% 감소와 기준이 다릅니다. 배포가 끝난 뒤 Big Pineapple 전체의 워킹셋 메모리 합계는 약 100TB 줄었다고 Cloudflare는 밝혔습니다. 회사는 절감한 메모리를 캐시 용량 확대에 활용해, 메모리 사용량을 늘리지 않고 적중률을 높여 상위 DNS 서버로 보내는 질의를 줄일 계획입니다.

참고 자료

오류 제보