본문 바로가기

분류 전체보기54

Redis SortedSet 정말 빠른가? 랭킹 측정에서 List의 Collection과Redis의 Sorted 성능 비교를 측정한글 입니다.테스트 상황100만명의 임의로 생성한 유저를 저장한 상태에서 List와 SortedSet으로 각각임의의 랭킹을 가진 유저를 조회해보는 테스트 입니다.  임의 User 데이터 삽입 ( Redis )@Testvoid insertUser() throws Exception { for (int i = 0; i  Redis에 SortedSet으로 User 데이터를 추가합니다.  ZCOUNT 명령어로 100만개의 데이터가 저장되었습니다. SortedSet  vs ArrayList507079번 순위의 유저를 조회하는 상황을 테스트 해보겠습니다. ArrayList 테스트@Testvoid inMemorySort() { .. 2024. 10. 17.
좋아요에서 발생하는 동시성 이슈 좋아요 기능을 구현하면서 생긴 동시성 문제 해결 과정을작성한 글입니다. 문제 상황2명이 동시에 좋아요을 누르게 된 경우, 2명의 좋아요가 전부 반영되지 않는 상황  좋아요 기능을 구현한 코드public Long like(Long postId) { Post post = postRepository.findById(postId).orElseThrow(() -> new PostNotFound()); post.addLikeCnt(); postRepository.save(post); return postId;}게시물 조회 후, 좋아요 갯수 증가 Service 계층 로직입니다. breakPoint를 Thread기반으로 해서, 2개의 요청이 Thread애 동시에 접근할 수 있는 환경을 만들어줍니다.. 2024. 10. 14.
Fan Out TimeLine on Read vs Write 팬 아웃 타임라인의조회를 더 빠르게한 경험을 담은 글 입니다. FanOut이란소셜 미디어나 뉴스 피드와 같은 시스템에서 사용되는 데이터 전송 패턴으로, 사용자의 활동이나 게시물이 다른 사용자들의 타임라인에 어떻게 전달되는지를 설명하는 방식입니다. FanOut Read란사용자가 자신의 타임라인을 조회할 때마다, 그때 실시간으로 팔로우하는 사용자의 최신 게시물을 수집하여 타임라인을 구성하는 방식입니다. FanOutRead 흐름잡기public PostCursorDto execute(Long userId, PostsCursorRequest request) { userReadService.getUser(userId); List followings = followReadService.getFollow.. 2024. 10. 11.
Cursor기반 페이지네이션으로 응답 속도 개선하기 OffSet기반 페이지네이션에서속도 개선 경험을 작성한글 입니다. 테스트 환경 : M1 mac - RAM 8GB 문제점OffSet기반 페이지네이션을 사용할 때, DB에서 넘겨준 offset 위치를 찾기 위해서 맨 처음부터 데이터를 한번 훑게 됩니다.만약, 총 100만개의 데이터가 DB에 존재하고, offset을 100만이라고 주는 경우, 100만개의 데이터를 훑은 다음에 이후의 데이터를 가져와야 하므로, 성능 저하가 발생할 수 있다. 즉, offset이 클수록 성능이 저하된다. 성능저하 확인하기테스트 환경 : POSTMANDB에는 100만개의 더미데이터를 저장해 두었고, 극단적인 성능 저하를 확인하기 위해서, [offset:0, size:1]과 [offset:999999, size:1]인 두 상황의 응답.. 2024. 10. 10.
인덱스로 빠른 조회 만들기 인덱스를 사용해서 쿼리 조회성능을 개선한 경험을 글로 작성하였습니다.준비물Mysql에 100만개의 데이터를 먼저 넣어줍니다.@Test@DisplayName("대용량 데이터 넣기")void bulkInsert() throws Exception{ //given EasyRandom easyRandom = PostFactory.get(3L, LocalDate.of(1999,1,1), LocalDate.of(2024, 2,1)); //when ObjectStopWatch.start(); List posts = IntStream.range(0, 10000 * 100) .parallel() .mapToObj(i -> easyRandom.next.. 2024. 10. 8.
[테스트 환경] 벌크 쿼리(Bulk Query) 사용하기 테스트 환경에서 벌크 쿼리를 사용해성능을 개선한 경험을담았습니다. 🙆🏻‍♂️ 개선할 점테스트 코드에서 데이터베이스(MySQL)에 데이터를 저장할 때, 반복문을 사용하여 데이터 저장을 수행했습니다. 하지만 반복문이 실행되는 횟수만큼 쿼리가 실행되기 때문에, 예를 들어 100만 건의 데이터를 저장할 경우, 100만 번의 쿼리가 실행됩니다. 이는 저장할 데이터와 쿼리 실행 횟수가 1:1 비율로 증가하여 매우 비효율적이라고 생각합니다.  개선한 방법벌크 쿼리(Bulk Query)를 사용하여 만 건의 데이터를 한 번의 쿼리로 처리했습니다. 이를 통해 데이터 저장 시 쿼리 실행 횟수를 줄이고 성능을 크게 향상시킬 수 있었습니다.   벌크 쿼리 사용전 코드@Testvoid not_use_bulkInsert() .. 2024. 10. 7.
자바 메모리 구조 자바 메모리 구조Deep Dive 자바 실제 메모리 구조 메서드 영역, 스택 영역, 힙 영역으로 총 3가지 영역으로 나뉜다. 메서드 영역메서드 영역은 프로그램을 실행하는데 필요한 공통 데이터를 관리한다. 이 영역은 프로그램의 모든 영역에서 공유한다. 어떤 정보가?클래스 정보 : 클래스 실행 코드(바이트 코드), 필드, 메서드 생성자 코드static 영역 : static 변수들을 보관런타임 상수 풀 : 공통 리터럴 상수를 보관 스택 영역스택 영역은 자바 실행 시, 하나의 실행 스택이 생성된다. 각 스택 프레임은 지역 변수, 중간 연산 결과, 메서드 호출 정보 등이 포함된다.스택 프레임 : 스택에 쌓이는 네모 박스 하나가 스택 프레임 (메서드 호출시 하나의 스택 프레임이 쌓이고, 메서드 종료시 해당 스택 프.. 2024. 10. 2.
Redis사용시, 발생하는 데이터 정합성 문제 Redis를 사용하면서 겪은 데이터 정합성 문제 해결 과정을작성한 글입니다.  문제 상황게시물을 새로 등록을 하고, 조회를 한뒤 기존 게시물을 업데이트하고,다시 조회를 해보니 업데이트된 게시물이 조회되는 것이 아닌, 업데이트 이전 게시물이 조회가 되는 상황 문제 원인게시물이 업데이트되었을 때, Redis에 저장된 데이터는 동기화되지 않으므로, 데이터 정합성 문제가 발생할 수 있다. 데이터베이스의 게시물 내용이 변경되었지만, Redis는 여전히 이전 데이터를 반환할 수 있어 최신 상태가 유지되지 않는다. 문제 해결 방법게시물을 업데이트할 때, 해당 게시물과 관련된 Redis에 저장된 캐시 데이터를 삭제하여, 다음 조회 시 최신 데이터가 반영되도록 한다. @CacheEvict(value = "getPosts.. 2024. 10. 1.
Redis, 캐싱하면 정말 응답 속도가 빨라? Redis가 정말 캐싱을 잘 해주는지 아닌지확인하는 글입니다. 성능을 높이고자 하는 부분게시물을 불러올때 카테고리를 기준으로 불러오게 됩니다. 매번 카테고리에 관련된 글을 불러올때, 속도를 개선하고자DB에 직접 쿼리를 날려 조회하는 방식이 아닌, 한번 조회된 데이터는 Redis에 저장해 놓고, 다음번 조회시엔 Redis에서 조회하도록 하는 상황입니다.  Redis관련 설정 코드package com.sangyunpark.smileboard.config;import com.fasterxml.jackson.databind.ObjectMapper;import java.time.Duration;import org.springframework.beans.factory.annotation.Value;import or.. 2024. 10. 1.