알고리즘을 골랐으니 이제 게이트웨이 20대 가 그것을 함께 수행해야 합니다. 여기서 새 문제가 셋 생깁니다. 동시성, 왕복 비용, 저장소 장애입니다.
읽고 계산하고 쓰면 서로를 덮는다
값을 읽어 판정하고 다시 쓰는 방식은 동시 요청에서 무너집니다. 두 게이트웨이가 같은 값을 읽으면 한 번의 증가가 사라집니다. 피크 초당 5만 요청이면 이 겹침이 상시로 발생합니다.
올리면서 올린 값을 돌려받는 연산을 쓰면 해결됩니다. 각 요청이 서로 다른 번호를 받고, 그 번호가 한도를 넘는 쪽만 거절됩니다. 왕복 한 번으로 올리기와 비교가 함께 끝납니다.
여러 값을 함께 고쳐야 하는 방식(토큰 버킷의 시각과 개수, 버킷 60개)은 저장소에서 여러 명령을 한 덩어리로 실행하게 합니다. 판정 논리를 저장소 쪽에서 돌리면 왕복이 한 번으로 유지됩니다.
왕복이 지연 예산의 대부분을 쓴다
같은 구역 안이라도 왕복은 대개 0.2에서 1밀리초입니다. 예산이 1ms 이므로 왕복 한 번이 예산의 전부일 수 있습니다.
| 설계 | 왕복 |
|---|---|
| 판정을 저장소에서 한 덩어리로 | 1회 |
| 읽고 판정하고 쓰기 | 2회 이상. 게다가 겹침 문제 |
| 값을 여러 이름에 나눠 저장 | 이름 수만큼. 묶어 담아 1회로 |
그래서 판정은 한 번의 왕복으로 끝나게 설계합니다. 이것이 알고리즘 선택에도 영향을 줍니다.
저장소가 죽으면 어떻게 하나
이 구조에서 저장소는 모든 요청 경로에 있습니다. 죽으면 판정할 수 없습니다. 선택은 둘입니다.
| 선택 | 결과 |
|---|---|
| 통과시킨다 | 서비스는 살아 있다. 한도가 사라진다 |
| 거절한다 | 한도는 지켜진다. 서비스가 멈춘다 |
대개 통과시키는 쪽을 고릅니다. 처리율 제한은 서비스를 돕는 장치이고, 그 장치의 고장으로 서비스가 멈추면 목적이 뒤바뀝니다.
다만 그동안 무방비가 되므로 게이트웨이 안에 최소한의 방어를 함께 둡니다. 자기 메모리로 세는 느슨한 한도를 예비로 두면, 저장소가 없는 동안에도 극단적인 남용은 막힙니다. 정확하지 않아도 없는 것보다 낫습니다.
지역 캐시로 왕복을 줄일 수 있다
한도를 이미 넘긴 키는 다음 판정 결과가 뻔합니다. 그 사실을 게이트웨이 메모리에 짧게 기억해 두면 거절 경로에서 왕복이 사라집니다.
한도를 넘긴 키를 몇 초 동안 기억한다
그 키의 요청은 저장소를 보지 않고 거절한다
남용이 심할 때 가장 많이 실행되는 경로가 가장 값싸집니다. 대가는 한도가 풀리는 시점이 기억 시간만큼 늦어지는 것인데, 거절 쪽으로 늦어지는 것이라 안전한 방향입니다.
원자적이라는 말의 범위
한 키에 대한 판정은 원자적으로 만들 수 있습니다. 그런데 여러 한도를 동시에 적용하면(키 한도와 조직 한도) 두 판정이 각각 원자적일 뿐입니다. 하나는 통과하고 하나는 거절되는 조합에서 이미 올린 값을 되돌려야 하는지 판단이 필요합니다.
대개 되돌리지 않습니다. 오차 5퍼센트 안이고, 되돌리는 경로가 새로운 겹침 문제를 만들기 때문입니다.