Tiny Star

프로젝트 22

[대용량 이관] bookRatingStep 개선

[bookRatingStep]을 만들었다. 300만 데이터 넣는데에 211초가 걸렸고, 문득 성능 테스트하는데 노트북 사양을 full 로 쓰면 조금 아이러니한 느낌이 들어서 메모리를 제한해보고 테스트해보기로 했다. 수정사항1. 메모리 설정-Xms512m -Xmx1g -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log옵션설명-Xms512mJVM의 초기 힙 메모리 크기를 512MB로 설정-Xmx1gJVM의 최대 힙 메모리 크기를 1GB로 제한-XX:+PrintGCDetailsGC가 발생할 때 어떤 세대에서 얼마나 수집되었는지 상세하게 로그 출력-XX:+PrintGCDateStampsGC 로그에 날짜와 시간 정보 포함-Xloggc:gc.logGC 로그를 ..

[대용량 이관] Book Job/Step 구성

20만건 정도의 book 데이터를 이관하는 것부터 시작했다. 구성보다는 에러를 해결한 내용이 위주이다...ㅎ Book Job, Step 구성@RequiredArgsConstructor@Configurationpublic class BatchConfiguration { private final Step stepBook; @Bean public Job bookJob(JobRepository jobRepository) { return new JobBuilder("bookJob", jobRepository) .start(stepBook) .build(); }}@Configurationpublic class BookStep ..

[대용량 이관] ItemWriter 선택 (JPA vs JDBC vs MyBatis)

파일 형식에 따라 Reader가 달라지기 때문에 이건 차치하고, 어떤 Writer를 써야할지 고민했다.MyBatisBatchItemWriter만 사용해봤는데, 실무에서 이걸 사용했던 이유는 테이블명이 기간에 따라 변경되기도 하고, if 문을 활용한 분기처리를 위한 동적매핑이 필요했기 때문이다.현재는 동적 매핑이 필요하지 않고 단순 Insert 처리만 하면 되기 때문에 굳이 이걸로 구현해야할까?란 생각이 들었기에 JdbcBatchItemWriter를 고려하게 됐다. JpaItemWriter는 [Spring Batch ItemWriter 성능 비교]를 보고 속도상 제외했다. 하지만!실제로 속도차이가 많이 나는지 궁금해서 테스트해보기로 했다. 구성공통 설정 (Entity)// BookRating.java@N..

[대용량 이관] 데이터 찾기 (Kaggle)

대용량 데이터 이관을 진행하기에 앞서, 어떤 데이터를 이관하면 좋을지 찾아봤다.이관량 자체가 목적이라면 랜덤 데이터 생성해서 넣을 수도 있으나, 추후 파일(CSV, JSON 등)을 활용한 배치작업이 필요할 수도 있기 때문에 구조까지 고려해서 작업해보려고 한다. (이미지 클릭 시 Kaggle 페이지로 연결됩니다.) Yelp Dataset이 데이터 세트는 Yelp의 사업체, 리뷰 및 사용자 데이터의 일부입니다. 원래는 학생들이 Yelp 데이터를 조사하거나 분석하고 그 결과를 공유할 수 있는 기회인 Yelp 데이터 세트 챌린지를 위해 마련되었습니다. 최신 데이터 세트에는 미국과 캐나다 8개 대도시 지역의 사업체 정보가 포함되어 있습니다. 용량 기준으로 데이터를 찾고 있었는데 대부분 용량이 큰 데이터는 '리..

[쿠폰] 성능 테스트 및 개선 (JDBC Bulk Insert)

k6 - DB Worker delay1. 100count / 5s k6는 테스트를 진행해서 끝났는데, insert는 계속되는 문제가 발생했다.현재 로직은 5초마다 최대 100개의 메세지를 처리하도록 되어있는데 이 수치를 조정해서 보완해보려고 한다. 2. 10,000count / 5s '20분 -> 1분'으로 많이 줄었지만, 그래도 1분 이상 차이가 난다.아무래도 한번 메세지를 받을 때마다 5초의 딜레이가 있다보니 거기서 나오는 문제로 예상된다.1초로 바꿔보자. 3. 10,000count / 1s이제 1분 안으로 들어왔다.다만 1초로 줄였음에도 30초가 넘는 차이가 나는게 이상한데, 아무래도 saveAll()이 하나씩 insert 하다보니까 생기는 문제가 아닐까 생각해봤다. Bulk insert가 가..

프로젝트/쿠폰 2025.04.30

[쿠폰] 테스트를 위한 k6 + InfluxDB + Grafana 구성

k6 → InfluxDB → Grafanak6: 테스트 트래픽 생성InfluxDB: 시계열 DB, 테스트 메트릭 저장Grafana: 실시간 시각화 1. k6 Dockerdocker pull grafana/k6// coupon_test.jsimport http from 'k6/http';import { check } from 'k6';export const options = { vus: 100, // 가상 사용자 수 duration: '10s', // 테스트 시간};export default function () { // 1 ~ 10 사이의 랜덤 couponId const couponId = Math.floor(Math.random() * 10) + 1; const url = `http:..

프로젝트/쿠폰 2025.04.30

[쿠폰] 쿠폰 발급 수정 (saveAll, @Transactional)

for (MapRecord message : messages) { // 중략 CouponIssues issued = CouponIssues.builder() .coupons(Coupons.builder().id(Long.parseLong(couponIdStr)).build()) .userId(userId) .build(); couponIssuesRepository.save(issued); // 중략}기존 코드는 이렇게 CouponIssues 객체 하나씩 인서트하고 있었는데,이렇게하면 Redis 등록하면서 인서트하는거나 마찬가지였다. 그래서 CouponId 기준으로 그룹지어 saveAll 처리하고 그에 따라 Redis Stre..

프로젝트/쿠폰 2025.04.29

[쿠폰] 쿠폰 발급 (Redis Stream, CustomDbWorker)

쿠폰 발급에 관한 상세사항은 [Git Issues] 참고 흐름[1] 발급 요청 수신 ↓[2] Redis 재고 조회 ↓[3] 재고 DECR - 재고 부족이면 → 발급 실패 ↓[4] 발급 성공 - 재고 DECR 상태 유지큰 흐름은 위와 같다.다만 여기에서는 Redis에 해당 Key가 만료되어 사라지거나 다른 문제로 없어졌다면 어떻게 해야할지와DECR만 할 뿐 발급 내역을 따로 저장하는 로직이 포함되어 있지 않아서 추가했다. [1] 발급 요청 수신 ↓[2] Redis 재고 조회 - 없으면 → DB 조회 → Redis 복구 ↓[3] 재고 DECR - 재고 부족이면 → 발급 실패 ↓[4] 발급 성공 - 발급 성공 이력을 Kafka/Redis Stream 등에 publish ..

프로젝트/쿠폰 2025.04.29

[쿠폰] 쿠폰 조회 (Redis 예외처리)

couponId에 따른 재고 조회하는 API (자세한 내용 Git Issue 참고) 1. 요구사항1. 목적Redis에 coupon:{couponId}:stock 형식으로 재고를 등록한다. 2. 작업 내용POST /api/admin/coupons요청 파라미터:couponId (Long, 필수) : 쿠폰 IDquantity (int, 필수) : 초기 재고 수량ttlSeconds (int, 선택) : 재고 만료시간(초 단위), 미지정시 무제한 유지 3. 요청/응답 예시요청POST /api/admin/coupon{ "couponId": 123, "quantity": 100, "ttlSeconds": 86400} 응답{ "couponId":13, "stock":100} 2. 작업 내용//..

프로젝트/쿠폰 2025.04.28

[쿠폰] 쿠폰 생성 (@Transactional, CustomException)

쿠폰 정보를 받아서 DB에 저장하고 Redis에도 올리는 작업을 했다. (자세한 내용은 Git Issue 참고) 1. 요구사항1. 목적쿠폰 등록 시 DB와 Redis를 일관성 있게 관리하기 위해 등록 흐름을 명확히 분리한다.쿠폰 정보를 먼저 DB에 저장하고, 생성된 coupon_id를 기반으로 Redis에 재고를 등록하는 프로세스를 구현한다. 2. 작업 내용쿠폰 종류 등록 API 구현POST /api/admin/coupons API 생성쿠폰 이름(name), 총 수량(total_quantity) 등을 받아 DB에 저장저장 후 생성된 coupon_id를 반환쿠폰 재고 Redis 등록반환된 coupon_id를 사용하여 Redis에 coupon:{coupon_id}:stock으로 재고 등록필요 시 TTL(만..

프로젝트/쿠폰 2025.04.28
top