본문 바로가기

Redis4

[#9] 같은 주문에 2명의 라이더가 동시에 배달하는 문제 해결 - Redis Transaction을 이용하여 데이터 atomic 보장 제가 진행하는 make-delivery 배달 앱 서버 프로젝트는 라이더들이 배차가 되지 않은 주문 목록 중에서 배차 요청을 하여 배달할 주문을 선택하는 로직이 있습니다. 하지만 만약 동시에 라이더들이 같은 주문에 배차 요청을 한다면 동시에 두 라이더가 배달을 하게 되는 것으로 나오며 주문 테이블에 라이더 정보는 더 늦게 배차 요청을 한 라이더가 입력되는 문제가 발생할 것이라 판단했습니다. 이는 데이터의 atomic이 보장되지 않는 문제이며 Race Condition과 비슷한 문제라고 판단했습니다. 기본적으로 이 문제가 발생한 원인을 설명하기 위해 간단한 예제를 설명하겠습니다. public int getNext() { return value++; } 얼핏 보기에 value++; 의 연산은 단 한번으로 이루.. 2020. 12. 27.
[#5] 성능을 위해 Redis keys 대신 scan 이용하기 Redis scan을 사용하는 이유 레디스의 명령어중 keys를 이용하면 모든 키값들을 가져올 수 있지만 이키값들을 가져오는동안 다른 명령어를 수행하지 못합니다. 따라서 성능에 영향을 줄 수 있어 레디스에서는 scan,hscan을 권장합니다. redis의 keys 명령어는 시간 복잡도가 O(N)입니다. 레디스는 싱글스레드로 동작하기 때문에 이처럼 어떤 명령어를 O(n)시간 동안 수행하면서 lock이 걸린다면 그시간동안 keys 명령어를 수행하기 위해 멈춰버리기 때문입니다. Redis에서 제공하는 Scan명령어는 Keys처럼 한번에 모든 레디스 키를 읽어오는 것이아니라 count 값을 정하여 그 count값만큼 여러번 레디스의 모든 키를 읽어오는 것입니다. (기본 count값은 10입니다) 예를들어 레디스.. 2020. 10. 25.
[#2] Redis에 한번에 많은 데이터 추가 시 네트워크 병목 개선하기 - Redis Pipeline 이용하기 문제 상황 예를들어 레디스에 리스트를 저장하였고 그 리스트에 한번에 여러개의 원소를 추가하는 상황이라고 가정해보겠습니다. 레디스에 기본적으로 한번의 추가 연산을 하면 O(1)시간이 들며 요청을 보내고 다음과 같이 응답 값을 받습니다. 레디스는 싱글스레드와 이벤트루프 기반으로 비동기방식으로 요청을 처리하기 때문에 고성능입니다. 하지만 기본적으로 TCP 기반의 네트워크 모델을 따르기 때문에 네트워크 I/O 에서 병목이 생길 수 있는 가능성이 있습니다. 하지만 매번 요청을 할 때마다 응답값을 받기 때문에(요청을 보내고 응답을 받을때까지는 blocking이 됩니다) 한번에 수십만개의 요청을 보낸다면 이 응답값을 매번 받는 것도 부하가 생길 수 있습니다. 즉, 레디스 서버에 반복문을 돌며 여러번 리스트의 원소를 .. 2020. 10. 8.
[#1] 서버가 여러대면 로그인 정보는 어디에 저장할까? - Sticky Session, Session Clustering, Redis Session Storage 크게 많이 사용하는 로그인 방식으로는 세션방식과 토큰방식이 있습니다. 이 글은 세션 방식에 대해 다룹니다. 세션 방식은 보통 서버에 로그인 정보를 저장합니다. Scale-out을 하기 전에는 한대의 WAS 서버로 세션을 처리했습니다. 하지만 서버의 대수를 늘린 후에는 세션을 어디에 저장할 것인지라는 이슈가 발생합니다. 만약 1번 서버에 어떤 사용자의 세션을 저장하고 배달 주문을 하는 Request가 2번 서버로 전달된다면 B서버에는 이 사용자의 세션이 없기 때문에 로그인이 유지되지 않는 문제가 발생합니다. 따라서 이러한 Session 정합성 문제를 해결해야했고 여러 가지 방법을 고민해보았습니다. 첫째로 고려한 방법은 Sticky Session입니다. Sticky Session은 어떠한 사용자의 세션이 1.. 2020. 9. 2.