일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- BFS
- 관측가능성
- langgraph
- 몽고 인덱스
- ipo 매매자동화
- 추천 검색 기능
- docker
- spring event
- 누적합
- AWS
- next-stock
- 디버깅
- 셀러리
- ai agent
- 크롤링
- JPA
- piplining
- gRPC
- 결제서비스
- 쿠키
- 카카오
- 프로그래머스
- 구현
- 백준
- dau 3만명
- 아키텍쳐 개선
- 완전탐색
- 베타적락
- 이분탐색
- 알람시스템
- Today
- Total
목록전체 글 (190)
코딩관계론
문제 이해하기간단하게 생각하면 두 저울의 합을 같게 맞추는 문제로 한 저울에서 다른 저울로 값을 옮겨가다 보면 같게 맞춰진다. 문제 해결 방법 설명하기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)..

🔥 성능 개선 목표 설정서비스 이벤트가 열리면 100,000명의 사용자가 초당 5회의 요청을 수행하게 됩니다. 이 서비스는 10분간 유지되므로 초당 QPS는 8,400 TPS를 감당해야 합니다. (QPS와 TPS를 동일로 가정)🚩 초기 문제 발견DDD 기반으로 타임딜 서비스를 리팩토링한 뒤 성능 테스트를 진행했으나, TPS가 2라는 극단적으로 낮은 결과가 나왔습니다. 프로메테우스를 통해 분석한 결과, DB 커넥션 풀이 10개뿐이라 요청이 몰릴 경우 모든 커넥션이 활성화되고 대기 요청이 쌓이는 현상이 발생했습니다.하지만 Look Aside 캐싱 패턴을 사용했기 때문에, 최초 요청만 DB에 접근하고 이후 요청은 Redis에서 처리해야 했습니다. 원인을 분석한 결과, 캐시 접근 이전에 트랜잭션이 시작되면서..

서론서비스에 많은 트래픽이 발생하지 않는 경우, 사용자의 요청에 따라 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를 요청한다고 가정해봅시다. 내부 서비스에서 사용자 정보를 조회하..

서론만들고 있는 서비스가 MSA(마이크로서비스 아키텍처)를 사용하다 보니 API Gateway의 구현이 필수적으로 요구되었습니다. API GateWay를 구현하는 방법에는 크게 두 가지 접근 방식이 있습니다. 첫 번째는 직접 구현하는 방식이고, 두 번째는 프레임워크를 사용하는 방식입니다. 저는 직접 API Gateway를 구현하는 방법을 택했는데, 이 글에서 그 이유와 구현 방식에 대해서 설명해보겠습니다.API Gateway란? API Gateway는 클라이언트와 백엔드 서비스 간의 요청을 중계하는 서버입니다. 이 서버는 인증과 인가를 담당하여, 사용자의 권한에 맞는 서비스만 호출할 수 있도록 관리해줍니다. 보통 API Gateway는 아래의 그림처럼 단순히 인증 및 인가를 처리하고, 클라이언트의 요청을..

서론앞서 JWT가 어떤 방식을 통해서 동작하는지 알아봤습니다. 이제는 어떤 방식으로 개발했는지에 대해서 설명하겠습니다.1. 왜 Interceptor를 선택했나?먼저 spring에는 filter를 통해 Interceptor와 똑같은 기능을 구현할 수 있습니다. 이때의 차이점이라고 한다면 Filter는 스프링 앞단에서 동작하고, Intercepto는 스프링 영역에서 동작하게 됩니다. 만약 Filter를 통해 구현하게 되면, 에러 처리가 추가적인 시간을 소모하게 됩니다. 그 이유는 Filter에서 발생한 에러가 WAS까지 전달된 후, WAS에서 다시 패킷을 생성해 /error 리다이렉트 시키는 방식이기 때문입니다. 반면, Interceptor를 사용할 경우, 서블릿 내에서 직접 Exception Handle..