깨진 상품 이미지를 찾아야 해서 복구 도구를 만들었는데 시험할 대상이 필요했다. 도구의 점검 모드를 돌려 보니 예상 소요 시간이 몇 시간으로 나왔다.
Table of contents
Open Table of contents
세 시간짜리 전수 점검
그 점검은 저장소를 전수로 훑으면서 사만 건이 넘는 대상을 하나씩 확인한다. 지금 내가 필요한 것은 깨진 사례 몇 개이지 전체 목록이 아니었다.
목적에 비해 수단이 훨씬 크면 기다리는 시간이 그대로 낭비가 된다. 그래서 실행을 중단하고 더 값싼 판별 수단이 있는지부터 찾아봤다.
식별자에서 계산되는 주소
마켓의 썸네일 주소 규칙을 보니 상품 식별자의 뒷자리를 쪼개 디렉터리를 만드는 방식이었다. 즉 데이터베이스 조회 없이 식별자만으로 주소를 계산할 수 있었다.
그러면 저장소를 거치지 않고 그 주소를 바깥에서 직접 물어볼 수 있다. 확인해야 할 대상이 저장소가 아니라 공개된 주소로 바뀐 셈이다.
헤더에 남은 지문
정상 이미지가 없으면 대체 이미지가 응답으로 오는데 그 응답의 콘텐츠 타입과 길이가 항상 같았다. 확장자와 실제 콘텐츠 타입이 어긋나는 것도 그 지문 가운데 하나였다.
본문을 받지 않고 헤더만 봐도 판별되므로 요청 하나의 비용이 크게 내려간다. 식별자 수백 개를 병렬로 물으니 몇 시간짜리 확인이 수십 초로 끝났다.
첫 표본에서 나온 0건
처음에는 최근 등록된 상품에서 표본을 뽑았고 깨진 것이 하나도 안 나왔다. 그 결과만 보고 깨진 것이 없다고 결론 낼 뻔한 자리였다.
식별자가 순번이라 구간을 나눠 다시 뽑아 보니 오래된 구간에만 몇 퍼센트가 몰려 있었다. 시간이 지나며 쌓인 문제이므로 오래된 쪽에 군집하는 것이 당연한 분포였다.
구간을 나눠 뽑는 이유
최근 구간에서만 뽑았으면 깨진 상품이 없다고 보고했을 것이고 그 보고를 받으면 복구 도구를 안 만든다. 실제로는 상당한 비율이 깨져 있는데도 그렇게 된다.
무작위 표본도 등록량이 늘고 있으면 최근 쪽으로 치우치므로 안전하지 않다. 구간을 명시적으로 나눠 각각 뽑는 것이 이런 분포에서 유일하게 안전한 방법이었다.
정리
- 목적에 비해 수단이 크면 기다리는 시간이 낭비가 된다
- 식별자에서 주소가 계산되면 조회 없이 직접 물어볼 수 있다
- 대체 이미지는 콘텐츠 타입과 길이 지문으로 판별된다
- 본문을 안 받고 헤더만 보면 요청 비용이 크게 내려간다
- 깨진 것은 균등 분포가 아니라 오래된 구간에 군집한다
- 최근 구간에서만 뽑으면 없다고 오판한다
- 무작위 표본도 등록 분포가 치우치면 안전하지 않다
- 만들어 둔 도구가 아니라 목적에 맞는 방법을 고른다