네이버 클라우드
[#11] 재고 관리는 어떻게 해야될까? - 3. Eventually Consistency
[#11] 재고 관리는 어떻게 해야될까? - 3. Eventually Consistency
2022.11.07개요 이전 포스팅에서 진행했듯이 Lua Script를 적용함으로써 Redis의 Atomic한 재고 관리를 수행할 수 있었습니다. 곧바로 nGrinder를 통해 트래픽을 발생시켜 이전보다 개선되었는지 확인하고 싶은 마음이 굴뚝같았으나 다시 한번 고민에 빠졌습니다. 왜 항상 Database는 구매 시마다 차감되는 재고를 기록해야될까? A. [#10] 재고 관리 Integrity 문제 포스팅을 해결하는 시점에서는 재고를 실시간으로 차감하여 실물상 재고와 서비스 상의 재고를 일치시켜 고객 경험을 높이기 위해서 구매 시마다 Database에서의 실시간 재고 차감이 필요합니다. B. [#11] 재고 관리는 어떻게 해야 될까? - 1. Redis Transaction 포스팅부터 [#11] 재고 관리는 어떻게 해야될까..
[#10] 재고 관리 Integrity 문제 - 2
[#10] 재고 관리 Integrity 문제 - 2
2022.10.15개요 이번 포스팅에서는 재고 관리 Integrity 문제 1편의 마지막에 '왜 Database Lock이 Distributed-Lock보다 TPS 성능이 좋겠나왔는가?'를 다뤄보려고 합니다. 주의🚫 : 해당 테스트에서 Distributed-Lock이 DB Lock보다 성능이 안 좋게 나왔지만 Database Lock은 항상 Distributed-Lock보다 좋다라는 관점은 적절하지 않습니다. Distributed-Lock은 왜 사용할까? 처음 예상하기로는 In-memory DB를 통해서 Lock을 수행하므로 막연히 더 빠르겠지(?)라는 생각을 갖고 있었습니다. 더불어 분산 락으로 인해 Database에서 해당 Row에 대한 Update 동작을 경합할 Transaction의 수가 적어지니 Database에..
[#10] 재고 관리 Integrity 문제 - 1
[#10] 재고 관리 Integrity 문제 - 1
2022.10.13개요 구매 부분은 대부분 서비스들의 핵심이고 커머스 도메인에서 재고 관리의 경우 비즈니스와 밀접한 연관이 있다고 생각합니다. 관리측면에서 보면 100개 밖에 없는 상품을 120개 판매했다고 기록한다면 추후 실제 재고를 관리하는 팀에서는 추가 발주를 진행해야 될 수도 있고 만약 추가 발주를 통해 재고가 확보가 안된다면 구매했던 고객들의 상품을 취소해야 합니다. 결국 이런 일들이 반복되면 비즈니스적으로 악영향을 끼칠 것이 분명합니다. 도메인마다, 서비스마다 다를 수도 있습니다! 결국 Trade-Off가 핵심 10개의 제품을 10명이 1개씩 구매했지만 2개가 남아있는 상황같이 반대의 경우는 어떨지 생각해보았습니다. 현재 구매를 진행한 고객들은 상품을 잘 받았지만 재고가 있어 추가적으로 구매하려 했지만 실패하는..
[#9] Scale-Out 테스트 결과 분석하기
[#9] Scale-Out 테스트 결과 분석하기
2022.10.11개요 Scale-Out에 필요한 사전 준비 사항들은 모두 Infra에 반영하여 구성을 완료했습니다. Pinpoint를 Scale-Out 시킨 Server에 모두 설치하여 Application Server를 모니터링할 수 있도록 구성하였고 Database Server의 경우 이전과 마찬가지로 Prometheus, Grafana를 통하여 테스트 결과를 확인했습니다. TPS 비교 이번 테스트의 목표는 Scale-Out을 도입하였을 때 어느정도의 성능 향상이 이루어지는지와 또 다른 병목지점을 찾기 위한 목적입니다. Scale-Out을 위한 사전 작업을 적용하기 전과 Scale-Out 적용된 Infra를 비교했습니다. 그래프를 확인해보면 전반적으로 Scale-Out시 성능이 향상 된 것을 볼 수 있습니다. 비교를..
[#8] Scale-Out을 위한 사전 준비 작업
[#8] Scale-Out을 위한 사전 준비 작업
2022.10.05개요 이전에 진행했던 Scale-Up을 통해서 Application Server의 Resource 부족의 재검증과 성능이 개선되는 것을 포스팅했었습니다. 마지막으로 결론은 '이제는 Scale-Out을 해야 할 때'라고 적었었습니다. 그래서 이번 포스팅을 통해 Scale-Out을 어떻게 진행했는지 보겠습니다. 수평적 확장(?) #1에서 개선하여 지속적으로 사용해온 Infra 구조도입니다. 바로 수평적 확장을 적용해보겠습니다. 현재 Client라고 볼 수 있는 nGrinder Agent가 요청을 분산해서 보낸다면 바로 수평적 확장이 가능하겠지만 추가적인 Component나 로직이 없으므로 기본적으로 기존에 요청을 보내던 Server로 보낼 것입니다. 비슷한 개념으로 MSA(Micro-Service Archi..
[#6] Connection 점유 시간 단축시키기 - HikariCP와 LazyConnectionDataSourceProxy 적용하기
[#6] Connection 점유 시간 단축시키기 - HikariCP와 LazyConnectionDataSourceProxy 적용하기
2022.10.01개요 이전 포스팅에서 auto commit 설정을 통해 Connection의 획득을 지연시키는 설정을 추가하여 성능을 개선하려고 했습니다. 하지만 이 부분에 있어서 간과한 것이 있었습니다. Auto Commit 전에 이미 Connection이 필요하다면 어떻게 될까요? 당연히 지연된 획득이 아니라 기존과 동일하게 작동할 것입니다. 이전 포스팅에서는 Auto Commit을 기준으로 Bean들을 살펴보았다면 이번 포스팅에서는 Transaction부터 HikariCP까지의 동작을 살펴보면서 Auto Commit을 적용했을 때 달라지는 부분과 LazyConnectionDataSourceProxy의 동작도 살펴보겠습니다. Transaction부터 HikariCP까지 이전 포스팅에서도 Connection을 언제 가..
[#6] Connection 점유 시간 단축시키기 - AutoCommit 설정
[#6] Connection 점유 시간 단축시키기 - AutoCommit 설정
2022.09.27개요 Scale-Out을 진행하기 전 추가적으로 진행하는 성능 개선 포인트로 Connection의 점유 시간을 단축하는 방향을 적용해 보았습니다. Connection을 갖고 오거나 반환하는 부분을 Code를 통해서 제어하는 방향보다는 Spring, Hibernate, HikariCP의 설정을 조정하여 비효율적으로 동작하는 부분을 개선하는 방향으로 진행했습니다. 비즈니스 로직에 집중하여 개발할 수 있도록 Spring 프레임워크의 많은 부분이 추상화되어 있습니다. 이런 Spring 프레임워크의 철학을 적용하여 사용되는 라이브러리도 추상화가 잘 되어 있습니다. 이번 개선 과정에서는 무엇보다 Spring의 추상화된 부분부터 구체화된 부분으로 동작을 따라가는 과정이 필요했습니다. 특히 Spring과 Databas..
[#5] Scale-Up으로 검증
[#5] Scale-Up으로 검증
2022.09.27개요 #4를 통해서 Application Server의 Resource 부족으로 병목이 발생한다는 것을 알게 되었습니다. 만약 해당 가정이 참이라면 Application Server의 Resource를 Scale-Up 한다면 성능이 오르는 것은 자명합니다. Scale-Up을 진행한 이후에도 Pool Size에 대한 변화를 관찰하여 예상했던 가정을 재검증하는 작업을 거쳤습니다. 그동안 진행된 실험에서 JVM Heap Size로 인해 문제가 발생되지는 않았으므로 vCPU만 Scale-Up 하여 실험을 진행했습니다. Scale-Up 예상 결과 먼저 사용 가능한 Resource들에 대해서 다시 한번 점검하고 실험 결과를 보여드리겠습니다. Heap Memory - 2GB CPU - 4vCPU 예상하는 실험 결과는..
[#3 ~ #4] Database Connection PoolSize 최적화
[#3 ~ #4] Database Connection PoolSize 최적화
2022.09.26개요 Index를 적용하여 쿼리 최적화를 진행한 뒤에 N + 1 문제도 해결했습니다. 하지만 N + 1 문제를 개선한 뒤에 분리하여 테스트를 기록하지는 않았습니다. 왜냐하면 가장 오래 걸렸던 테스트 TOP 3안에 뽑히는 Database Connection PoolSize를 조정해보며 실험을 하게 되면 자연스럽게 기본 Pool 사이즈에서 N + 1 문제의 개선 결과도 볼 수 있을 것이기 때문입니다. 이 부분에서 가장 고생했던 부분은 Pool Size를 최적화 실험에서 더 효율적으로 테스트 하는 방법이었습니다. 예를 들면 '어느 정도의 테스트 시간을 설정하면 Connection Pool Size에 대한 변화를 잘 볼 수 있을까?', 'Connection Pool Size의 간격을 어느 정도로 진행해야 최적의..
[#2] 쿼리 문제 최적화
[#2] 쿼리 문제 최적화
2022.09.22개요 [#1](인프라 개선하기 작업)을 통해 이제 정상적으로 테스트는 가능했지만 전반적으로 개선의 필요성이 있다는 것을 절실히 느꼈습니다. 'Postman으로 응답 오면 잘 만들어졌군!' 하던 스스로가 너무 부끄러웠지만 이제 시작이니 차근차근 해결해 나가 보자는 생각을 갖고 가장 쉽게 고칠 수 있는 부분부터 접근해 나가려는 계획을 세우고 시작했습니다. 가장 먼저 눈에 띄는 것은 바로 '쿼리의 수행 시간'이었습니다. Database라는 것을 학습하면서 인덱스를 통해 빠른 속도를 통해 데이터를 갖고 올 수 있고 왜 빠른지에 대해서 알고 있었지만 '정말 빨라?'라는 의문과 '나는 실행 계획(EXPLAIN)을 통해 쿼리를 개선할 수 있을까?'라는 의구심으로써 Primary Key와 Foreign Key를 제외하..
[#1] 서버 인프라 개선하기 - 구매주문 API 테스트
[#1] 서버 인프라 개선하기 - 구매주문 API 테스트
2022.09.08개요 E-Commerce의 핵심이라고 할 수 있는 구매 주문 API 테스트 결과입니다. 인프라 개선 전에는 구매 주문 테스트를 시작하는 순간 서버가 다운돼서 테스트 결과를 얻지 못해 어느 정도로 개선되었는지 비교할 수는 없지만 로그인 API와 물품 목록 조회 API를 보았을 때 개선점이 많을 것이라 예상했습니다. 초기 테스트 계획은 랜덤한 물품 옵션을 랜덤한 수량으로 구매하는 시나리오만 테스트하려고 했으나 고민해보니 진정한 문제는 하나의 물품을 많은 유저가 구매하는 경우라고 생각이 스쳐 지나갔습니다. 랜덤한 상품을 구매하는 것을 다품목 구매 주문 테스트, 하나의 상품만 구매하는 것을 단품목 구매 주문 테스트라고 명명하고 테스트를 진행했습니다. 다품목 구매 주문 테스트 기대도 없어서 일까요 아니면 물품 조..
[#1] 서버 인프라 개선하기 - 물품 목록 조회 API 테스트
[#1] 서버 인프라 개선하기 - 물품 목록 조회 API 테스트
2022.09.08개요 하나의 개선점과 여러 테스트들을 모두 하나의 포스트에 담고 싶었지만 가독성이 떨어질 것이라 예상해서 분리하려고 합니다. 이번에는 물품 목록을 조회하는 API에 대해 테스트를 진행했습니다. 이해를 돕기 위해 ERD도 첨부했습니다. 물품 목록 조회 API는 Product의 Category를 쿼리 파라미터로 받아 Product Option과 함께 반환해주는 기능입니다. Spring Rest Doc을 통해 생성된 문서를 보면 다음과 같이 요청을 보냅니다. 이렇게 요청을 보내면 다음과 같이 응답이 반환됩니다. 상품과 함께 사이즈에 따른 수량도 함께 나오는 것이 기획이었기 때문에 Index, N + 1 문제 등 테스트 하기도 전에 걱정되는 API 입니다. 그럼 테스트 결과를 한번 보겠습니다! 물품 조회 API..