일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 디버깅
- 구현
- 셀러리
- 완전탐색
- 알람 시스템
- JPA
- 쿠키
- spring event
- 결제서비스
- 검색어 추천
- 객체지향패러다임
- 누적합
- docker
- prg 패턴
- 백준
- 깊게 생각해보기
- 카카오
- BFS
- 주식
- 레디스 동시성
- jwt 표준
- gRPC
- AWS
- 이분탐색
- piplining
- 트랜잭샨
- 숫자 블록
- 프로그래머스
- 좋은 코드 나쁜 코드
- branch 전략
- Today
- Total
목록분류 전체보기 (168)
코딩관계론
규모 추정하루에 100만 건의 트랜잭션을 처리해야 하는 상황입니다. 이를 초 단위로 나누면, 1초에 약 12건(TPS, Transactions Per Second)을 처리해야 하는 수준입니다. 이러한 요구사항을 고려할 때, 시스템 설계 시 성능보다는 안정성에 중점을 두는 것이 중요합니다.시스템 선택 고려 사항이 결제 시스템의 경우 성능적 요구사항이 상대적으로 낮기 때문에, 안정성을 최우선으로 고려해야 합니다. 이를 위해 동기식 통신보다는 비동기식 통신을 사용하는 것이 더 적합합니다. 그 이유는 다음과 같습니다:장애 격리: 동기식 통신을 사용할 경우, 결제 서비스 제공사(PSP)에서 장애가 발생하면, 우리의 서버까지도 장애 영향을 받을 수 있어, 장애 격리가 어렵습니다.확장성: 트래픽이 급격히 증가할 때,..
최근 프로젝트에서 Redis를 사용하는 분산 시스템에서 동시성 이슈가 발생하는 것을 확인했습니다. 단일 worker 환경에서는 동시성 문제를 크게 신경 쓰지 않아도 되었지만, 시스템을 scale-out 하면서 여러 가지 동시성 문제가 발생하게 되었습니다. 예를 들어, 아래와 같은 코드가 있을 때 단일 Thread로 동작한다면 동시성 이슈가 발생할 수 있을까요?RScoredSortedSetAsync scoredSortedSet = client.getScoredSortedSet(key);RFuture scoreFuture = scoredSortedSet.firstScoreAsync();RFuture nameFuture = scoredSortedSet.pollFirstAsync(); 정답은 "발생할 수 없다..
문제 이해하기간단하게 생각하면 두 저울의 합을 같게 맞추는 문제로 한 저울에서 다른 저울로 값을 옮겨가다 보면 같게 맞춰진다. 문제 해결 방법 설명하기1. 큐1에 있는 원소들의 합과 큐2에 있는 원소들의 합을 비교2. 더 큰 값의 큐에서 더 작은 큐쪽으로 원소를 이동하면 됨3. 문제 예시의 3번 조건을 보면 항상 같을 똑같이 만들 수 있는 것이 보장되지 않기 때문에 최대 경우의 수가 넘어가면 -1을 반환해야 함코드from collections import dequedef solution(q1, q2): t1_sum = sum(q1) t2_sum = sum(q2) q1 = deque(q1) q2 = deque(q2) answer = 0 max_try = len(q1)..
먼저 성능 개선을 하기 전에 목표를 정해야 합니다. 이 이벤트가 열리게 되면 1,00,000명의 사용자가 초당 5번의 질의를 이어가게 된다. 똑똑한 사용자들이 시스템의 허점을 노리고 쿠폰을 받거나 말거나 쿼리를 넣는 것이다. 또한 이 서비스는 10분간만 유요한 서비스다. 따라서 초당 QPS는 8,400을 감당할 수 있어야 합니다. (QPS와 TPS가 동일하다고 가정함) 최근에 DDD를 공부하면서 타임딜을 리펙토링 하고 성능 테스트를 진행해 보았습니다. 하지만 웬걸 성능이 아래와 같이 TPS가 2? 가 나오는 상황이 발생했습니다. 2000도 아니고 2가 나오는 숫자가 너무 기괴했습니다. 바로 프로메테우스를 보니 DB의 커넥션 풀이 10개인데 사용자의 요청이 몰리면서 10개가 전부 활성화되고, 71개가 커낵..
서론서비스에 많은 트래픽이 발생하지 않는 경우, 사용자의 요청에 따라 DB에 데이터를 저장하고 불러오는 방식은 큰 문제가 되지 않습니다. 그러나 트래픽이 증가하면 DB에서 데이터를 읽고 수정한 후 다시 저장하는 과정에서 성능 저하가 발생할 수 있습니다. 따라서, 많은 트래픽을 처리해야 하는 시스템에서는 데이터를 중간 서버에 임시로 저장한 후, 일정 주기로 DB에 영속화하는 방식으로 성능을 최적화하는 것이 일반적입니다. 저는 Redis의 Keyspace Notifications 기능을 활용하여 이 방법을 구현했습니다. 이제 이 기능의 동작 원리와 사용법을 설명하고, 이를 사용해 구현하는 과정에서 발생한 문제와 그 해결 과정을 공유하겠습니다. 동작 방식Redis의 Keyspace Notifications 구..
이전의 V3는 정말 모든 것을 만족했지만, 데이터가 지속적으로 확장된다면 결국 디비와 레디스의 용량은 한계에 도달하게 된다. 따라서 우리는 scalue-out 방법인 샤딩을 도입해서 이러한 문제를 방지해야 합니다. 검색어 추천 서비스의 경우에는 두 개의 저장소를 사용하고 있기 때문에 두 개의 저장소(Redis, Mongo)에 샤딩을 진행해야 합니다. 먼저 샤딩을 어떤 방식의 샤딩이 있는지 알아보고, 그에 맞는 적적한 샤딩 키 설계를 진행해야 합니다. 샤딩 키 설계가 잘못되면 한 서버로 데이터가 몰리게 되면서 샤딩 효과를 볼 수 없게 됩니다. 샤딩 방식에는 크게 모듈러 샤딩과 레인지 샤딩이 있습니다. 이제부터 각각의 장단점을 한번 살펴보겠습니다. 먼저 모듈러 방식은 아래 그림과 같습니다. 모듈러 방식으로 ..
CAP 이론은 분산 시스템 환경에서는 세 가지의 요구사항을 동시에 만족하는 분산 시스템을 설계하는 것은 불가능하다라는 정리입니다. CAP의 의미에 대해서 자세히 설명하자면 아래와 같습니다.일관성이란 분산시스템에서 접속하는 모든 클라이언트는 어떤 노드에 접속했는냐와는 상관 없이 같은 데이터를 보아야 한다.가용성은 시스템이 항상 응답할 수 있는 상태를 유지하는 것을 의미합니다. 일부 노드가 장애를 겪거나 다운되더라도, 다른 노드가 정상적으로 작동하여 사용자 요청에 응답해야 합니다.파티션감내란 네트워크 분할이 발생했을 때, 즉 두 노드 간의 통신이 단절되었을 때에도 시스템이 여전히 작동할 수 있는 능력을 의미합니다. 이 경우에도 시스템은 일정 수준의 기능을 유지하며 계속해서 서비스를 제공할 수 있어야 합니다...
이전 버전은 기능적, 성능적 만족을 이뤄냈지만 53일 간만 서비스가 유효하다는 치명적인 단점이 있었습니다. 이를 해결하기 위해서 저장공간이 많은 하드디스크를 이용하기로 했습니다. 따라서 버전 1,2에서 구성된 서비스 플로우는 아래와 같이 수정되어야만 했습니다. 사용자의 검색어에 따라서 트라이를 실시간 갱신하지 않고, 왜 Cron을 통해서 배치작업을 진행할까라는 의문점이 있을 수 있습니다.저도 이런 의문점이 있었는데 생성된 트라이가 사용자의 몇 번의 요청으로 인기 검색어가 변경될 일은 잘 없을 것이고 사용자의 요청을 실시간으로 반영해서 트라이를 계속 생성하게 되면 성능적으로 매우 느려지게 될 것입니다. 또한 이 서비스가 실시간 급상승 검색어 순위와 같은 민감한 데이터가 아니고, 대용량의 데이터 처리이기 때..
이전 버전은 기능적으론 만족스러웠지만, 성능 측면에서 아쉬움이 있었습니다. 따라서 버전 2는 성능 개선을 중점으로 진행했으며, 대규모 시스템 설계의 기초 서적에서 많은 도움을 받았습니다. 앞서 우리는 문자열 검색에 데이터베이스 쿼리를 활용했는데, LIKE 연산자의 동작 방식으로 인해 데이터베이스는 테이블의 모든 행을 검사해야 했습니다. 이 과정에서 시간 복잡도는 O(테이블의 행 수)이며, 각 행의 해당 컬럼에서 질의 문장을 매칭하는 과정이 추가되기 때문에 실제로는 O(테이블의 행 수 * 문장 길이)의 시간 복잡도가 발생하게 됩니다. 모든 행을 검사하는 것은 비효율적입니다. 예를 들어, 사용자가 입력한 검색어가 "A"일 경우, "A"로 시작하는 칼럼만 비교하면 되지, "C"나 "D"로 시작하는 컬럼과 매칭..
검색어 추천 기능은 대부분의 현대적인 웹사이트에서 사용자 경험을 개선하기 위해 중요한 역할을 합니다. 이 기능은 사용자가 검색창에 특정 단어나 구문을 입력하면, 이를 기반으로 관련성이 높은 추천 검색어를 실시간으로 제공하여 사용자가 원하는 정보를 보다 빠르고 효율적으로 찾을 수 있도록 돕습니다. 예를 들어, 사용자가 "강아"라고 입력했을 때, 서버에서는 이 입력된 부분을 기반으로 "강아지", "강아지 복숭아", "강아지 종류"와 같이 자주 검색되는 키워드를 실시간으로 검색하고, 그중에서 상위 키워드를 추천해 줍니다. 검색어 추천 기능의 기술적 특징은 크게 네 가지가 있다고 생각합니다.(구글 페이지를 분석한 결과에 대한 글쓴이의 생각임으로 부정확성이 있을 수 있습니다!)검색어 추천과 검색 결과를 위한 별도..
버전 1의 서비스 구성은 다음과 같이 설계했습니다. 사용자의 요청이 오면 캐시 서버나 특별한 자료구조 처리를 사용하지 않고, 데이터베이스의 쿼리문을 통해 응답하도록 구성했습니다.데이터베이스는 단일 테이블로 설계했습니다. 이는 추천 키워드 기능에 필요한 데이터가 '키워드'와 해당 키워드가 검색된 횟수에 대한 정보만으로 충분했기 때문입니다. 개발 과정은 2024.08.09 - [개발] - 검색어 추천 서비스 개발기에서 분석한 내용을 토대로 진행했습니다. 사용자가 입력을 할 때(1바이트가 추가되면 검색으로 간주), 해당 단어로 검색된 키워드 중 상위 10개를 반환하는 방식으로 구현했습니다. 스프링(Spring)과 JPA를 사용하여 개발했으며, JPA 구현체로는 Hibernate를 선택했습니다. 아래는 JPQL..
서론앞서 API Gateway를 공부하면서, 특정 API Gateway Framework(AGF)를 사용하는 것의 한계에 대해 알아보았습니다. 그중 하나는 내부 통신 프로토콜로 REST를 강제하는 단점이 있었습니다. 이는 내부 서버 간의 통신에서 굳이 REST를 사용할 필요가 없다는 뜻이기도 합니다. 따라서 저는 내부 서버의 통신은 gRPC프로토콜을 선택하여 사용했고, 이제부터는 gRPC 통신의 장점에 대해서 설명해보겠습니다REST API의 성능 문제REST API를 강제했을 때 발생할 수 있는 문제점은 무엇일까요? 이전 글에서 성능 이슈에 대해 언급했는데, 이를 구체적인 예시를 통해 설명해보겠습니다. 사용자가 "모든 정보 조회"라는 API를 요청한다고 가정해봅시다. 내부 서비스에서 사용자 정보를 조회하..