분류 전체보기185 알림 구현(1) Kafka + Redis Pub/Sub + WebSocket MVP 개요이번 프로젝트에서 나는 "알림 기능" 파트를 맡게 되었다. 프로젝트 주제는 실시간 게임 매칭 + 게임 공략글 공유 웹서비스이며, 알림은 전반적인 UX의 핵심 기능 중 하나였다. 알림은 두 가지 방향으로 나눠서 설계하기로 했다.RDB 기반 알림: 로그인 시 확인할 수 있는 알림 목록, 읽음 처리 등 상태 저장용, 푸시 알림이 유실되면(상대 사용자가 WebSocket Session이 없으면) 이곳에 모은다.푸시 기반 알림: 실시간 반응성과 UX 중심의 알림(브라우저 푸시)우선 RDB 연동 없이 "글에 달린 댓글"의 실시간 알림 스트리밍 기능 MVP부터 구현하였다. 이 글은 그 과정을 정리한 것이다. 구성1. 모든 유저는 웹 로그인 시 WebSocketSession을 부여받는다.클라이언트에서 /ws?to.. 2025. 4. 7. Transactional인데, 왜 Redis 로직에서 Connection을? 개요2025.04.04 - [팀 프로젝트/플러스 프로젝트] - Transactional-Readonly가 어플리케이션에 미치는 영향 Transactional-Readonly가 어플리케이션에 미치는 영향개요Hot Key를 관찰하려고 부하테스트를 하던 도중, 세션 자동 생성에 이어 이상한 점을 하나 더 발견했다.우선, 짧게 실험 결과를 요약하고 가면..1. 실험 목적:Hot Key가 Redis 또는 시스템에 어떤 영roqkfchqh.tistory.com지난번에 이어서... Transactional Readonly에 관한 글이다.Transactional readonly를 불필요한 상황에서 사용했을 때 쓸모없는 DB 커넥션이 생겨버려서 부하가 몰릴 경우 어플리케이션 전반의 latency가 증가하는 현상을 관측할.. 2025. 4. 6. Transactional-Readonly가 어플리케이션에 미치는 영향 개요Hot Key를 관찰하려고 부하테스트를 하던 도중, 세션 자동 생성에 이어 이상한 점을 하나 더 발견했다.우선, 짧게 실험 결과를 요약하고 가면..1. 실험 목적:Hot Key가 Redis 또는 시스템에 어떤 영향을 미치는지 확인2. 실험 조건:key: "popular:market:items"TTL: 무제한 - '인기 검색' 은 redis만 사용하도록 할 것이기 때문. 물론 fallback도 존재함.JMeter: 3000유저 / 1초 ramp / 1000 loopRedis: 단일 인스턴스, 로컬실험 도중 1-2번의 Key Update 진행하여, 시스템에 미치는 영향 확인사용한 툴: Prometheus, Grafana, Jmeter3. 결과 요약:Redis key rate(GET)초당 5000~6000.. 2025. 4. 4. JWT Token BlackList TTL을 효율적으로 설정하기 개요기존에는 BlackList의 TTL을 대강 AccessToken의 Exp기간과 똑같이 잡았었는데,유저가 만료시간 직전에 로그아웃을 하는 경우 Redis에 불필요하게 오랫동안 BlackList를 저장하게 된다. 30분짜리 AccessToken의 만료시간이 1분 남았을 때,블랙리스트로 30분간 저장해놓게 된다면 29분간 쓸모없는 데이터가 생기는 것이다. 솔직히 블랙리스트 하나 당 216B밖에 되지 않아서 무시해도 될 수준 아닌가? 싶지만, 100만건이 한번에 몰리면 216MB가 된다.거기다 우리는 RefreshToken도 Redis로 관리하므로 함께 생각하는 편이 좋다. 해결public void addToBlackList(String token) { String blackPrefix = jwtSe.. 2025. 4. 3. Actuator가 자동으로 Session을 생성한다 개요Redis Hot Key Issue를 겪어보려고 Jmeter로 부하테스트를 돌리는 도중에 이슈가 발생했다.정확히는 Hot Key 부하테스트와 관련은 없지만, Redis Insight를 뒤적거리다 발견했다.어플리케이션을 켜놓고 가만히 놔뒀는데, 세션이 스스로 생성되었다..하나에 632B라 무시할만한 수준이라고 생각할 수도 있지만, 15초에 한번 Metrics를 수집하며 이것의 TTL이 30분이니까 서버가 지속될 때 최대 약 74KB * 인스턴스 개수 만큼 Redis에 쌓인다.그리고 어쨋든 버그기도 하고.. 거슬린다. 대체 왜 생긴걸까? 파악너무 예전에 만들었던 Session + Security 구조라 기억이 잘 안 나니까 우선 세션이 어디에서 생성되는지 로그를 찍어보자.@Slf4j@Componentp.. 2025. 4. 2. 조회 성능 향상시키기(6) Redis Hot Key Issue Redis Hot Key?Hot Key는 말 그대로 "너무 자주 접근되는 단일 키" 이다. 이때 요청이 모두 읽기일 경우와, 일부라도 쓰기가 섞인 경우는 시스템 관점에서 부하의 성격이 완전히 달라진다. MESI 프로토콜MESI 프로토콜은 멀티코어 CPU 환경에서 캐시 일관성(Coherency)을 유지하기 위한 프로토콜이다.MESI는 각각의 캐시 라인이 4가지 상태 중 하나를 가지도록 해서, 각 CPU 코어가 동일한 메모리에 주소에 접근하더라도 데이터 불일치를 막아주는 방식이다. MESI의 4가지 상태는 다음과 같다:Modified (수정)이 캐시 라인만 최신 데이터를 가지고 있고, 메모리에는 반영 안 됨다른 캐시에 없음 + dirty 상태Exclusive (배타적)이 캐시 라인만 데이터 가지고 있고, .. 2025. 4. 1. 9. 운영체제 9장 메모리 (4) 페이징 페이징페이징은 연속된 물리 메모리 공간 없이도 프로세스가 실행될 수 있도록 하는 메모리 관리 기법이다.물리 메모리는 프레임이라는 고정 크기 블록으로, 논리 메모리는 페이지라는 동일 크기 블록으로 나눠지고, 이 둘은 일대일로 매핑된다.프로그램이 메모리에 올라갈 때 페이지 테이블을 통해 논리 주소의 페이지 번호를 물리 주소의 프레임 번호로 바꾸고, 거기에 페이지 오프셋을 더해 실제 주소를 계산한다. 이 작업을 MMU가 자동으로 해주고, 덕분에 물리 주소가 연속되지 않아도 된다. 그래서 외부 단편화가 원천적으로 사라진다.하지만 페이지 단위로만 할당하기 때문에 프로세스 크기와 페이지 크기가 안 맞으면 마지막 페이지에서 내부 단편화가 생긴다.예를 들어 2048B짜리 페이지를 썼는데, 마지막 페이지에 1000B만 .. 2025. 3. 31. 8. 운영체제 9장 메모리 (3) 연속 메모리 할당 가변 파티션 방식연속 메모리 할당은 메모리를 나눠주는 방식 중 하나이다.그 중에서도 가변 파티션 방식은 프로세스 크기에 맞춰 딱 맞게 메모리 덩어리를 나눠주는 것이다.처음엔 메모리 전체가 하나의 큰 hole로 비어있고, 요청이 들어온다면 그 크기만큼 잘라서 주고, 남은 공간은 hole로 남긴다.시간이 지나면서 프로세스가 종료되면 메모리 여기저기 작은 hole들이 생기고, 이 hole들을 다시 잘 활용하지 못하면 조각처럼 되어서 공간 낭비가 생긴다.이 모든 문제를 통틀어서 동적 메모리 할당 문제라고 하고, 그래서 운영체제는 어떤 hole에 새로운 프로세스를 배치해야 할지 결정해야 한다.이걸 메모리 할당 전략이라고 한다. 대표적인 전략은 3가지가 있다.1. 최초 적합: 앞에서부터 순차적으로 찾다가 딱 들어맞.. 2025. 3. 30. 7. 운영체제 9장 메모리 (2) with java spring.. 논리 주소 vs 물리 주소CPU가 주소를 생성하면 그건 진짜 주소가 아니라 "논리 주소" 이다. 반면 진짜 RAM에서의 위치를 "물리 주소" 라고 한다.프로그램이 메모리를 사용하려 할 때, CPU는 논리 주소를 생성하고 이걸 실제 물리 주소로 바꾸는 작업이 필요한데, 이 작업을 해주는 게 MMU(Memory Management Unit)이라는 하드웨어다. 논리 주소와 물리 주소는 보통 다르고 매핑을 통해 연결된다. 예를 들어, CPU가 346번지를 접근하려 할 때 운영체제가 "너는 14000부터 써" 라고 했다면 실제 접근 위치는 14346이 된다. 이 때 14000이라는 값을 재배치 레지스터라고 한다. 동적 적재지금까지의 설명은 모두 프로세스가 실행되려면 메모리에 전부 올라와 있어야 한다는 전제였다... 2025. 3. 29. 6. 운영체제 9장 메모리 (1) with redis.. 기본 하드웨어CPU는 계산을 담당하는 놈이고, 계산하려면 데이터가 필요하다.근데 이 데이터는 항상 CPU 내부에 있지는 않고, 보통 RAM에 있다. CPU는 자기 내부에 Register라는 아주 빠른 공간에서만 직접 데이터를 꺼내 쓸 수 있다.그래서 뭔가를 계산하려면 일단 메모리에 있는 데이터를 레지스터로 가져와야 하는데, 메모리에서 레지스터까지 데이터를 가져오는 건 시간이 꽤 걸린다. CPU는 명령 하나를 1-3 Clock cycle에 처리 가능하다. 나노초 단위로 움직이며 굉장히 빠르다.하지만 CPU가 연산하려면 데이터가 필요하고, 그 데이터는 RAM에 있고, CPU가 메모리에게 값을 요청한 사이 지연시간이 생긴다.이 시간 동안 CPU는 계산을 못 하고 가만히 기다려야 하고, 이걸 Stall(지연) .. 2025. 3. 28. 이전 1 2 3 4 ··· 19 다음