Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- Java
- NoSQL
- reactive
- Elk
- nodejs
- AWS
- mybatis
- redis
- socket
- git
- network
- Linux
- github
- Lombok
- reactor
- HTTP
- 데이터통신
- Heap
- html
- mongodb
- Static
- cache
- 네트워크
- ajax
- VCS
- libuv
- effective
- javascript
- r
- spring
Archives
- Today
- Total
빨간색코딩
AWS S3 비용 절감하기 (feat. 크로미움 favicon cache 버그) 본문
1. 들어가며
- 여기서 말하는 s3 비용절감은 대규모 서비스용도가 아니다. 그런 서비스들은 앞단에 AWS CloudFront 같은 CDN으로 서빙해야하는 게 맞고 그렇게들 하고있을테니, s3와 직접적으로 관련이 없다.
- 사이드 프로젝트에서 비용을 소소하게 아껴본 경험을 이야기해보고자 한다.
- 이용자 수가 어느정도 있는 경연, 사이드프로젝트, 데모 등
- 앞단에 뭔가 대는게 오히려 더 비용이 아까운 상황
2. aws s3 요금 계산식
- 서울 리전, 20년 6월기준
- 저장 0.025 USD / GB
- 전송량 0.126 USD / GB
- 1 GB 까진 무료
- 요청량
- READ 10000번 당 0.0035 USD
- WRITE 1000번 당 0.0045 USD
3. 문제발생
- s3 를 이미지 스토리지, 서빙 용도로 사용하고 있다. GET에 대해서만 public으로 정책을 변경했으며, 서비스페이지에서 s3 경로를 직접 참조한다.
- 컨텐츠의 이미지, 유저 이미지, favicon, opengraph 이미지
- 기대상황: s3 에서 etag 를 통한 브라우저 캐시를 걸어주니, 유저가 캐시를 삭제하거나, 배포를 통해 buildtime 이 바뀌지 않는 이상 요청이 크게 안 들어올 것이다.
- 실제 read 요청량 (이용자 수가 늘어나는 상황임)
- 2월 : 6,928
- 3월 : 21,527
- 4월 : 56,654
- 5월 : 176,137
- 요청량 그래프를 보고 그냥 넘어갈 수도 있었지만, google analytics 에서 월간 PV를 보니 뭔가 비례한다는 점에서 이상함을 느꼈다. 브라우저 캐시가 제대로 안되고 있나?
3-1. 크로미움에서 favicon 을 캐시하지 않는다?
- 크롬 개발자도구 네트워크 창에서 대부분 이미지들이 memory, disk cache 되고 있었으나, favicon.ico 파일만은 계속 실제 요청을 날리고 있었다.
- 버그항목을 찾아보니..https://bugs.chromium.org/p/chromium/issues/detail?id=969033
- 이 때문에, favicon.ico 으로 많이 요청이 들어가고 있던 것이다.
- 이 상태로 둔다면, 브라우저 캐시로 줄일 수 있었던 요금을 괜히 더 내야하는 것이다.
4. 어떻게 풀었나요?
- s3 경로를 직접 참조하는 방식에서, 서비스 서버의 nginx proxy cache 를 활용하여, 캐시된 이미지를 서빙하였다.
- 그 결과, 5월보다 이용자 수가 늘었음에도 6월 read 요청량이 약 4만대로 줄었다.
4-1. nginx proxy cache
docs :http://nginx.org/en/docs/http/ngx_http_proxy_module.html
뒷단 서버로 부터 전달받는 데이터를 cache 하여 서빙한다. 뒷단 서버가 받는 요청량을 줄여줄 수 있다. 여기서는 뒷단서버가 AWS S3 이다.
관련 설정
- proxy_cache_path : 캐시된 파일을 저장할 디렉터리와 옵션들을 설정할 수 있다.
- levels : 하위 디렉터리의 수를 나타낸다.
- keys_zone : cache 명과 공유 메모리 영역의 크기를 지정
- 가이드에 따르면 1MB면 약 8,000개의 key를 저장할 수 있다고 한다.
- nginx 는 공유 메모리에서 존재여부를 먼저 확인한 후, 실제 캐시의 위치를 찾는다.
- inactive : 사용되지 않는 캐시파일 만료 기간
- max_size : 전체 캐시파일의 크기
- levels : 하위 디렉터리의 수를 나타낸다.
- proxy_cache_key : 캐시 키 포맷 설정
- proxy_cache_valid : 해당 응답코드에 대해 지정된 시간동안 뒷단으로 요청보내지 않고 캐시하는 설정
- proxy_cache : 사용할 cahce zone을 지정
- proxy_cache_path : 캐시된 파일을 저장할 디렉터리와 옵션들을 설정할 수 있다.
캐시 상태 파악
- ngx_http_upstream 모듈이 제공하는 $upstream_cache_status 를 통해 캐시 상태를 파악할 수 있다.
- HIT : proxy_cache_valid 내에 있으며, 캐시 파일로 서빙했다.
- EXPIRED : proxy_cache_valid 내에 없어서, 뒷단에 다녀와서 캐시파일을 갱신했다
- MISS : 캐시파일이 없어서, 뒷단에서 요청해왔다.
- 이외에도 몇가지 있으나, 잘 안쓰임
- 참고 : 응답헤더도 브라우저 캐시되므로,X-Cache-Status: EXPIRED가 계속 보일 수도 있다.
전체 설정
http {
...
proxy_cache_path /devljh/app/nginx/cache/image levels=1:2 keys_zone=image_cache:10m inactive=1d max_size=128M;
proxy_cache_key "$host$request_uri";
...
server {
...
location ~* \.(gif|png|jpg|jpeg|ico)$ {
proxy_pass https://{bucket}.s3.ap-northeast-2.amazonaws.com;
proxy_ignore_headers "Set-Cookie";
proxy_hide_header "Set-Cookie";
proxy_set_header cookie "";
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_cache_valid 200 1h;
proxy_cache image_cache;
expires 1M;
add_header Pragma public;
add_header Cache-Control "public";
add_header X-Cache-Status $upstream_cache_status;
}
...
}
}
'Web' 카테고리의 다른 글
Web Storage (localStorage, sessionStorage, cookie) (0) | 2018.08.03 |
---|---|
ECMAScript 6 (0) | 2017.11.11 |
XML 기본 구조 (요소, 속성, CDATA, 네임스페이스) (0) | 2017.10.11 |
XML 개요 (개념, 설계목표) (0) | 2017.10.10 |
Chrome Devtool (CPU프로파일링, 힙덤프) (0) | 2017.08.04 |
Comments