Foundry
처리율 제한 장치 설계
심화
핵심

요청 시각을 다 들고 세기

정확한 대신 들고 있는 양이 비용이다

앞 단계에서 고정 윈도우가 경계에서 두 배를 통과시키는 것을 봤습니다. 원인은 자르는 기준이 고정된 시각이라는 것이었습니다. 기준을 요청 시점으로 바꾸면 경계가 사라집니다.

통과한 요청의 시각을 모아 둔다

요청 시각을 모두 저장하고 최근 60초 밖의 것을 버리면 경계가 없는 정확한 판정이 된다 요청 시각을 모두 저장한다 최근 60초. 이 안의 개수를 센다 창을 벗어났다. 버린다 기준이 요청 시점이라 경계가 없다. 언제 봐도 뒤로 60초다 대신 통과한 요청마다 항목 하나가 남는다 키 10만 개에 한도 1,000이면 최대 1억 항목

판정은 두 단계입니다. 60초보다 오래된 항목을 버리고, 남은 개수를 한도와 비교합니다. 언제 보든 뒤로 60초를 보므로 경계 버스트가 원리적으로 없습니다.

비용은 들고 있는 양이다

한 키가 들고 있는 항목은 최대 한도만큼입니다. 한도가 분당 1,000회 이면 키마다 최대 1,000개입니다.

활성 키최대 항목 수
1,000개100만
10만 개1억

항목 하나가 수십 바이트라도 1억 개면 수 기가바이트입니다. 그리고 이 메모리는 한도를 다 쓰는 키가 많을수록 늘어납니다.

거절한 요청은 저장하지 않는다

한도를 넘어 거절한 요청까지 저장하면 이상한 일이 생깁니다. 한도를 넘긴 뒤에도 계속 요청을 보내는 쪽이 저장소를 계속 키웁니다. 막으려던 상대가 비용을 늘리는 구조가 됩니다.

통과시킨 요청만 기록한다
거절은 세지 않고 응답만 돌려준다

이 규칙은 남용을 막는 장치에서 일반적으로 성립합니다. 거절 자체가 비싸면 거절이 공격 수단이 됩니다.

판정 비용도 요청마다 든다

버리기와 세기가 매 요청에 붙습니다. 피크 초당 5만 요청이면 그만큼 반복됩니다. 저장소가 정렬된 집합을 다뤄 준다면 한 번에 처리할 수 있지만, 버릴 항목이 많이 쌓인 키에서는 그 한 번이 길어집니다.

1ms 예산에서 이 방식은 여유가 없습니다. 그래서 선택은 둘 중 하나입니다.

선택언제
이 방식을 쓴다키 수가 적고 정확도가 돈과 직결될 때. 유료 호출 과금 경계 등
더 값싼 근사로 간다키가 많고 오차가 허용될 때. 이 요구사항이 그렇다

정확한 방법이 늘 정답은 아니다

이 방식은 오차가 0입니다. 그런데 요구사항은 오차 5퍼센트 를 허용한다고 적었습니다. 허용된 오차를 쓰지 않으면 그만큼을 비용으로 내는 것입니다.

요구사항에 적힌 여유는 쓰라고 있는 것입니다. 정확도를 공짜로 얻을 수 있을 때만 정확한 쪽을 고릅니다.

면접에서 이렇게 나옵니다

Q.요청 시각을 저장하는 방식은 어떻게 판정하나요

60초보다 오래된 항목을 버리고 남은 개수를 한도와 비교합니다.

통과한 요청의 시각을 키마다 모아 둔다
판정할 때 60초 밖의 항목을 버린다
남은 개수가 한도보다 작으면 통과시키고 시각을 추가한다

기준이 고정된 시각이 아니라 요청 시점이므로 언제 보든 뒤로 60초를 봅니다. 그래서 경계 버스트가 원리적으로 없습니다.

정렬된 집합을 다루는 저장소라면 버리기와 세기를 한 번의 왕복으로 처리할 수 있습니다.

흔한 실수: 거절한 요청까지 저장하는 것. 한도를 넘긴 뒤에도 계속 보내는 쪽이 저장소를 계속 키우게 되어 막으려던 상대가 비용을 늘립니다. 통과시킨 것만 기록합니다.

Q.이 방식의 메모리 비용은 얼마나 되나요

키마다 최대 한도만큼입니다. 한도가 분당 1,000회 이면 키당 1,000개 항목입니다.

활성 키최대 항목 수
1,000개100만
10만 개1억

항목 하나가 수십 바이트라도 1억 개면 수 기가바이트가 됩니다. 그리고 이 비용은 한도를 다 쓰는 키가 많을수록 커집니다. 평소에는 여유롭다가 트래픽이 몰릴 때 함께 커지는 성질이라 더 위험합니다.

판정 비용도 요청마다 듭니다. 버릴 항목이 많이 쌓인 키에서는 그 한 번의 정리가 길어집니다.

흔한 실수: 활성 키를 전체 발급 키 수로 계산하는 것. 대부분의 키는 조용하므로 실제 메모리는 동시에 활동하는 키 수로 잡습니다. 반대로 최악을 볼 때는 전체 키가 한도를 다 쓰는 경우를 잡아야 합니다.

Q.오차 5퍼센트 가 허용되는데 정확한 방식을 쓰면 안 되나요

허용된 오차를 쓰지 않으면 그만큼을 비용으로 내는 것입니다.

이 방식은 오차가 0이지만 대가가 있습니다. 항목이 쌓이고, 판정이 무거워지고, 1ms 예산에 여유가 없어집니다.

선택언제 맞나
정확한 방식키 수가 적고 정확도가 돈과 직결될 때
값싼 근사키가 많고 오차가 허용될 때

요구사항에 적힌 여유는 쓰라고 있는 것입니다. 정확도를 공짜로 얻을 수 있을 때만 정확한 쪽을 고릅니다.

흔한 실수: 정확한 방식을 골라 두고 "필요하면 나중에 바꾼다" 고 답하는 것. 처리율 제한은 트래픽이 몰릴 때 부하를 받는 장치라, 그 순간에 메모리와 지연이 함께 나빠집니다. 바꿔야 하는 시점이 곧 가장 바쁜 시점입니다.

Q.거절한 요청을 세면 어떤 문제가 생기나요

거절 자체가 비싸지면 거절이 공격 수단이 됩니다.

한도를 넘긴 뒤에도 계속 요청을 보내는 쪽이 있습니다. 그 요청까지 저장하면 저장소가 계속 자라고, 판정할 때 버려야 할 항목도 계속 늘어납니다.

막으려던 상대가 우리 비용을 늘리는 구조가 된다

그래서 통과시킨 요청만 기록하고, 거절은 응답만 돌려줍니다. 거절 횟수를 알고 싶다면 별도의 집계 카운터에 값 하나만 올립니다.

흔한 실수: 거절 기록을 남기려고 판정 경로에 로그 쓰기를 넣는 것. 남용이 심할 때 가장 많이 실행되는 경로에 가장 무거운 작업이 붙습니다. 관찰이 필요하면 표본만 남기거나 개수만 세는 쪽으로 갑니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

읽었으면 문제로 확인해보세요

처리율 제한 장치 설계 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.