Cloudflare, Pingora 캐시에 zstd를 넣어 적격 텍스트 저장 공간을 평균 3분의 1로 축소
- Cloudflare의 Cache Transcoding 시제품은 Pingora 캐시에 들어온 적격 응답을 zstd 레벨 3으로 압축해 디스크와 Tiered Cache 전송에는 압축본을 유지하고, 클라이언트 전송 전 해제함
- 통제된 코퍼스에서 적격 자산은 평균 2.834배 압축됐으며, 디스크 크기는 원본의 약 3분의 1로 줄어 페타바이트 규모의 실효 캐시 용량과 데이터센터 간 대역폭 절감을 예상함
- 압축 대상은 HTML·JSON·CSS·JavaScript 같은 텍스트 중 원본이 비압축으로 보낸 응답이며, 이 텍스트는 요청의 67.3%, 바이트의 22.3%를 차지하고 약 71%가 Content-Encoding 없이 도착함
- 이미 압축된 이미지·동영상·폰트는 요청의 21.4%지만 바이트의 63.3%를 차지해 재압축하면 CPU만 소모하므로 대상에서 제외함
- zstd 레벨 3의 인코딩 비용은 바이트당 4.31ns(약 232MB/s)로 캐시 채움 때 한 번 내고, 해제는 바이트당 1.56ns(약 641MB/s)로 매 응답마다 수행함
Hacker News opinions
CPU를 아끼려는 목적이면 인기 콘텐츠보다 차가운 콘텐츠를 압축했을 것 같음. 글의 인기 콘텐츠만 제한하려 했다는 대목이 이상함.
나는 전부 압축한 뒤 링크, 읽기 빈도, 클라이언트 특성에 따라 더 높은 압축률로 다시 압축하겠음. zstd 35는 거의 공짜고 1219도 디스크 읽기에서는 빨라질 수 있으며, 이미 압축된 스트림은 빨리 중단함.
캐시 계층에서는 차가운 콘텐츠를 더 싸고 느린 저장소에 두는 게 맞다고 봄. 여기서 압축 저장은 그 역할을 하는 셈임.
아마 압축하는 장비의 저장소보다 에지로 인기 콘텐츠를 빨리 밀어 넣는 일을 최적화하는 듯함. 소스에서 압축하면 에지 전송 대역폭과 캐시 축출 후 재채움 비용이 줄고, 같은 디스크에 더 많이 보관해서 축출도 줄어듦.
대형 CDN에서 일할 때 상위 1% 콘텐츠가 처리량의 2040%, 상위 10%가 8090%를 차지했음. 나머지는 캐시 수명 안에 다시 읽힐 가능성이 낮아서 절반에 처리 시간을 쓰는 건 낭비일 수 있음.
범위 요청이 어떻게 처리되는지 모르겠음. 압축하지 않으면 캐시된 전체 파일의 필요한 부분만 읽으면 되는데, 압축본만 저장하면 글의 '범위 요청은 바뀌지 않는다'는 말이 성립하기 어려워 보임.
내 추측으로는 전체 리소스를 풀거나, 적어도 요청 범위의 끝까지는 풀어서 잘라 내보내야 함.
zstd에는 pigz의 독립 블록처럼 프레임을 찾을 수 있는 seekable 포맷이 있음. 그걸 쓰면 범위 요청을 처리할 여지가 있음.
btrfs나 ZFS도 비슷한 일을 해냄. Seekable OCI처럼 인덱스로 원래 바이트 범위 a-b를 압축 범위 x-y에 매핑하는 방식도 가능하지만, 헤더와 추가 조각은 읽어야 할 듯함.
글에서 범위 요청 동작을 바꾸지 않았다고 했으니, 서버 쪽에서 압축을 풀어 처리하는 기본 방식일 것 같음.
원본이 비압축 파일을 보내도 클라이언트가 지원하면 그대로 압축해 내려주면 되지 않나 싶음.
브라우저의 zstd 지원이 지금도 80%를 넘고 계속 늘 텐데 나도 그 생각을 했음.
Cloudflare는 적어도 유료 계정에는 이미 그렇게 제공함. 어떤 압축 방식을 대신 제공할지도 고를 수 있음.
파일시스템과 전송 계층의 압축으로 처리하면 상위 소프트웨어가 압축을 알 필요가 없지 않을까 싶음. btrfs처럼 커널 공간에서 처리하면 압축과 해제가 더 자주 일어나겠지만, 대역 외 중복 제거와 스냅샷 배포도 붙일 수 있음.
예전에 npm 레지스트리를 디스크에서 90% 넘게 줄인 적이 있음. 패키지 버전끼리 비슷하니 먼저 델타 인코딩하고 압축했고, 롤링 해시로 파일을 나눠 CID 파일시스템에 저장하면 유사 파일이 압축 청크를 공유함.
큰 컨테이너 이미지에 비슷한 방식을 썼음. FastCDC로 파일을 청크로 나눌 수 있지만, 공유 청크 수와 HTTP 요청 수 사이에 손해가 있어서 기본값으로는 꺼 둠.
PyPI도 월간 대역폭을 페타바이트 단위로 줄일 수 있겠음. 다만 로컬 캐시를 제대로 쓰지 못하는 CI가 원인의 일부로 보임.
내 경험상 gzip을 zstd로, 때로는 lz4·bz2·brotli로 바꾸는 것만으로도 큰 절감이 났음. 큰 자산은 디스크를 덜 쓰고 다운로드와 해제도 빨라져서 인프라 비용과 개발 생산성이 모두 좋아졌음.
여기서 '트랜스코딩'이라는 말은 맞지 않는 듯함. 기술적으로는 인코딩·디코딩이 맞지만, 의도는 압축·해제라고 썼어야 더 분명했음.