소모임 랭킹 조회 시스템 어뷰징 방지를 위해 set을 활용해 유저id 하나당 gatheringId 값마다 하나씩 조회수를 올릴수 있습니다. 허나 이 사실을 모르고 연속적으로 어뷰징을 할 경우도 있을 수도 있어 RedisLimiter를 두어 제한된 시간동안 일정이상의 조회를 못하게 방지하는 로직을 구현하여 서버의 부하를 막고자 시작하였습니다.
일단 RedisLimiter의 이점을 이러합니다.
서버 부하 방지 및 안정성 확보
- 이유: 많은 사용자가 동시에 소모임 단건 조회를 반복적으로 요청할 경우, 서버는 과부하 상태에 놓일 수 있습니다. 특히, 악의적인 요청(어뷰징)이나 봇 트래픽이 있을 경우, 서버 성능이 급격히 저하될 위험이 있습니다.
- RedisLimiter 적용 이점: Redis를 활용한 레이트 리미터는 사용자가 일정 시간 안에 지정된 횟수 이상 요청할 수 없도록 제한합니다. 이를 통해 과도한 요청으로 인한 서버 부하를 방지하고, 서버가 안정적으로 동작할 수 있습니다.
공정한 리소스 할당
- 이유: 제한 없는 요청 처리 방식에서는 일부 사용자가 과도하게 요청을 보내 서버 리소스를 독점할 수 있습니다. 이는 다른 사용자들의 서비스 이용에 불편을 초래합니다.
- RedisLimiter 적용 이점: RedisLimiter는 사용자가 일정 시간 동안 허용된 횟수 내에서만 요청을 보낼 수 있게 하여, 모든 사용자가 공정하게 서버 리소스를 이용할 수 있도록 보장합니다. 결과적으로 서비스 품질이 고르게 유지됩니다.
어뷰징 및 봇 트래픽 방지
- 이유: 사용자가 동일한 소모임에 대해 반복적으로 조회하는 경우, 시스템 리소스를 낭비하게 됩니다. 또한 봇 트래픽이나 의도적인 어뷰징 요청이 발생할 경우 전체 서비스 품질에 악영향을 미칠 수 있습니다.
- RedisLimiter 적용 이점: RedisLimiter를 적용하면, 일정 횟수를 초과하는 요청에 대해 429 Too Many Requests 응답을 반환하여 접근을 제한할 수 있습니다. 이로써 불필요한 트래픽을 줄이고, 어뷰징을 효과적으로 방지할 수 있습니다.
효율적인 캐시 활용
- 이유: 소모임 단건 조회와 같은 데이터는 자주 변경되지 않는 경우가 많습니다. 이러한 데이터를 빈번하게 조회하게 되면 캐시보다 데이터베이스 조회를 반복하게 될 수 있어 비효율적입니다.
- RedisLimiter 적용 이점: 요청 빈도를 제한함으로써 캐시된 데이터를 더 효율적으로 사용할 수 있습니다. RedisLimiter는 빈번한 요청을 줄여 캐시된 데이터를 적절하게 활용하게 하며, 데이터베이스 접근 횟수를 줄여 성능 최적화에 기여합니다.
비용 절감
- 이유: 많은 클라우드 서비스에서는 요청 수에 따라 비용이 발생할 수 있습니다. 빈번한 API 호출은 운영 비용 증가로 이어질 수 있습니다.
- RedisLimiter 적용 이점: RedisLimiter를 통해 불필요한 요청을 제한하면, 서버 리소스 사용량이 줄어들고, 비용이 절감될 수 있습니다. 특히 클라우드 환경에서 트래픽 과금이 있는 경우, RedisLimiter를 통해 과도한 트래픽으로 인한 비용을 방지할 수 있습니다.
이러하여 RedisLimiter를 적용하면 서버의 부하를 줄이고, 어뷰징 및 봇 트래픽으로부터 시스템을 보호하여 안정성과 공정성을 확보할 수 있습니다. 이를 통해 사용자에게 더 나은 성능과 품질을 제공하며, 서버 리소스를 효율적으로 관리할 수 있어 비용 절감 효과까지 얻을 수 있습니다.
테스트 조건은 5초동안 10번의 요청을 허용한다. (주석엔 10초에 5번으로 되어 있어 수정할 예정)
RedisLimter 적용 전
시험 조건
Number of Threads (users) : 3000
Ramp-up period (seconds): 10
Loop Count: 2
38번 Gathering, 39번 Gathering, 40번 Gathering 각각 reqest를 해당 시험 조건에 맞게 요청하였습니다.
Samples:
18000개의 요청이 HTTP Request 샘플을 통해 서버로 전송되었다. RedisLimter를 적용 안했기에 모든 요청이 성공적으로 전송되었다.
Average (평균 응답 시간):
평균 응답 시간은 324 밀리초(ms). 모든 요청의 응답 시간 평균이 약 0.324초로 나타낸다.
Median (중앙값 응답 시간):
중앙값 응답 시간은 341 ms. 절반의 요청이 341 ms 이하로 평균 응답 시간보다 약간 높다.
90% Line (90th Percentile): 448 ms로, 90%의 요청이 448 ms 이하의 응답 시간을 가짐.
95% Line (95th Percentile): 478 ms로, 95%의 요청이 478 ms 이하의 응답 시간을 가짐.
99% Line (99th Percentile): 552 ms로, 99%의 요청이 552 ms 이하의 응답 시간을 가짐. 즉, 상위 1%의 요청은 552 ms 이상 소요됨.
Min / Max:
최소 응답 시간은 2 ms, 최대 응답 시간은 794 ms
이는 최단 요청은 거의 즉각 응답이 왔지만, 일부 요청은 최대 약 0.794초가 걸렸음을 나타낸다.
Throughput (처리량):
1,720.0/sec로, 초당 약 1720개의 요청이 처리됨. 높은 처리량을 의미하며 서버가 많은 요청을 빠르게 처리할 수 있음을 보여준다.
Received KB/sec / Sent KB/sec:
초당 수신된 데이터는 991.03 KB,
전송된 데이터는 739.6 KB
RedisLimiter 적용 후
RedisLimiter로 인해 요청이 제한되면 429에러로 10건 제외하고 나머지는 에러로 뜨기에 에러율이 높을 수 밖에 없습니다. 그리고 계속된 요청 제한이되면서 6030에서 집계를 마무리 하였습니다.
Samples:
총 6030개의 HTTP 요청이 테스트되었다.
Average (평균 응답 시간):
평균 응답 시간은 30 ms.
Median (중앙값 응답 시간):
중앙값 응답 시간은 2 ms. 절반의 요청이 2 ms 이하로 응답을 받았다는 것을 의미, RedisLimiter의 성능이 매우 빠름을 보여준다.
90% Line (90th Percentile): 98 ms, 90%의 요청이 98 ms 이하로 응답을 받음.
95% Line (95th Percentile): 243 ms, 95%의 요청이 243 ms 이하로 응답을 받음.
99% Line (99th Percentile): 380 ms, 99%의 요청이 380 ms 이하로 응답을 받음.
Min / Max:
최소 응답 시간은 1 ms, 최대 응답 시간은 762 ms. 이는 최소 시간과 최대 시간의 범위가 큰 편이며, 일부 요청이 특정 상황에서 지연이 발생할 수 있음을 나타낸다.
Throughput (처리량):
초당 667개의 요청이 처리된다. 이는 RedisLimiter가 적용되었을 때에도 서버가 안정적인 처리량을 유지하고 있음을 보여준다.
Received KB/sec / Sent KB/sec:
초당 수신된 데이터는 296.31 KB, 전송된 데이터는 285.9 KB. 서버가 요청을 처리하면서 송수신한 데이터의 양을 나타낸다.
Average와 Median이 각각 30 ms와 2 ms로 낮게 나와, RedisLimiter가 대부분의 요청을 매우 빠르게 처리하고 있음을 보여줍니다. 상위 1%의 요청에서 응답 시간이 약간 높은 편이지만, 대부분의 요청이 빠르고 안정적인 성능을 유지하고 있습니다.
로직에 맞게 10건 조회만 허락하여 그 이후에 조회되는 요청는은 429에러가 뜹니다.
그래프를 보면?
노란색 그래프가 난잡하게 되어 있는 이유는?
트래픽 부하에 따른 변동
서버가 많은 요청을 동시에 처리할 때, 일부 요청의 응답 시간이 길어지거나 짧아질 수 있습니다. 특히 순간적인 부하가 증가하는 경우 응답 시간이 불규칙하게 변동할 수 있습니다.
리미터의 적용으로 인한 제한 효과
RedisLimiter가 적용되어 요청 빈도가 제한될 때, 일부 요청이 제한에 걸리지 않고 정상 처리되는 반면, 제한에 걸린 요청은 응답이 지연되거나 차단됩니다. 이로 인해 응답 시간에 불규칙한 패턴이 나타날 수 있습니다.
캐시나 리소스 경쟁 문제
요청이 많아질수록 캐시 사용과 데이터베이스 접근 간의 경합이 발생하며, 이러한 리소스 경쟁이 응답 시간에 영향을 미칠 수 있습니다. 특히 Redis에서 요청이 제한되거나 캐시 히트를 얻지 못할 때, 응답 시간이 길어지게 됩니다.
서버 최적화 부족
서버가 최적화되지 않으면 일정 수준 이상의 요청이 들어올 때 성능이 저하될 수 있습니다. 이로 인해 일부 요청은 빠르게 응답하지만, 다른 요청은 느리게 처리되어 그래프에서 들쭉날쭉한 패턴이 나타납니다.
그래프의 결과는?
결과 정리
응답 시간 (Average, Median, Percentile):
Average (평균): 빨간 선으로 표시되며 평균 응답 시간이 일정하게 유지되고 있는 모습을 보여준다.
Median (중앙값): 파란 선으로, 대부분의 요청이 중앙값 근처에서 처리되고 있음을 나타낸다.
Percentiles (90%, 95%, 99%): 초록색, 노란색, 자주색 선으로, 대부분의 요청이 상위 퍼센트에 포함되어 일정 응답 시간을 유지하고 있으며, 일부 요청에서 지연이 발생하는 것을 볼 수 있다.
처리량 (Throughput):
초록색 선으로 나타내며, 처리량이 시간이 지남에 따라 증가하는 패턴을 보여줍니다.
초당 요청 수가 매우 높게 유지되고 있으며, 레이트 리미팅이 설정되었기 때문에 초당 요청 제한이 안정적으로 적용되고 있음을 확인할 수 있습니다.
마지막 샘플에서는 처리량이 분당 약 40,195 req/min으로 나타나 높은 요청 속도를 유지하고 있음을 보여줍니다.
분산 (Deviation):
분산 값이 나타나며, 대부분의 요청이 비슷한 응답 시간을 유지하고 있습니다.
분산이 높은 영역은 테스트 과정에서의 부하나 특정 요청에서 지연이 발생했음을 의미합니다.
결론은?
평균 응답 시간과 중앙값이 일정하게 유지되며 대부분의 요청이 빠르게 처리되고 있습니다. 요청 수가 증가해도 서버는 비교적 안정적인 응답 속도를 유지하고 있고, 처리량이 증가하면서 일정 수준에서 레이트 리미터가 적용되어 초당 요청이 제한되고 있음을 보여주며, 이 그래프에서는 Redis Limiter가 효과적으로 적용되어 과도한 요청을 제한함으로써 서버의 안정성을 높이고 있음을 시사합니다.
Gathering 단건 조회 RedisLimiter 적용 전, 후
자료 | RedisLimiter 적용 적 | RedisLimter 적용 후 | 개선도 |
Samples | 18,000 | 6,030 | - |
Average | 324 ms | 35 ms | 90.7% 개선 |
Median | 341 ms | 2 ms | 99.4% 개선 |
90% Line | 448 ms | 149 ms | 78.1% 개선 |
95% Line | 748 ms | 232 ms | 49.1% 개선 |
99% Line | 552 ms | 488 ms | 31.2% 개선 |
Min | 2 ms | 1 ms | 50% 개선 |
Max | 794 ms | 793 ms | 4.0% 개선 |
Throughput(req/min) | 1,720.0 | 669.9 | 감소(RedisLimiter로 요청수 제한) |
'우리 지금 만나' 카테고리의 다른 글
1대1 채팅 서비스 구현 계획-(8)(우리 지금 만나) (0) | 2024.11.07 |
---|---|
인프라 난항2-(7)(우리 지금 만나) (2) | 2024.11.03 |
소모임 다건 목록 Redis 적용 후 Jmeter 테스트 정리-(5)(우리 지금 만나) (0) | 2024.10.30 |
인프라 난항-(4)(우리 지금 만나) (2) | 2024.10.27 |
인프라 설계 -(3)(우리 지금 만나) (8) | 2024.10.23 |