묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
lockType 오류 및 카운트 체크 안 됨
안녕하세요! 강의 잘 듣고 있습니다. 좋은 강의 감사합니다.실습하다가 오류가 생겨 문의 드립니다. void like(Long articleId, Long userId, String lockType) { restClient.post() .uri("/v1/article-likes/articles/{articleId}/users/{userId}/" + lockType, articleId, userId) .retrieve(); } @Test void likePerformanceTest() throws InterruptedException { ExecutorService executorService = Executors.newFixedThreadPool(100); // 100개의 스레드 풀 생성 // 각 lock type별로 테스트 likePerformanceTest(executorService, 1111L, "pessimistic-lock-1"); likePerformanceTest(executorService, 2222L, "pessimistic-lock-2"); likePerformanceTest(executorService, 3333L, "optimistic-lock"); } void likePerformanceTest(ExecutorService executorService, Long articleId, String lockType) throws InterruptedException { CountDownLatch latch = new CountDownLatch(3000); System.out.println(lockType = " start"); like(articleId, 1L, lockType); long start = System.nanoTime(); for (int i = 0; i < 3000; i++) { long userId = i + 2; // String finalLockType = lockType; executorService.submit(() -> { like(articleId, userId, lockType); latch.countDown(); }); } latch.await(); long end = System.nanoTime(); System.out.println("lockType = " + lockType + ", time = " + (end - start) / 1_000_000 + " ms"); System.out.println(lockType + " end"); Long count = restClient.get() .uri("/v1/article-likes/articles/{articleId}/count", articleId) .retrieve() .body(Long.class); System.out.println("count = " + count); }여기서 '람다 식에 사용되는 변수는 final 또는 유사 final이어야 합니다' 라는 오류가 뜨더라고요. // String finalLockType = lockType; 부분 주석 해제하고 람다 내부에 like(articleId, userId, finalLockType); 으로 하면 startlockType = start, time = 914 ms start endcount = 0 startlockType = start, time = 589 ms start endcount = 0 startlockType = start, time = 567 ms start endcount = 0 으로 출력도 잘 안 나옵니다. 애플리케이션 콘솔에는 아래 로고만 찍히고 나머지는 안 나옵니다.Hibernate: select alc1_0.article_id,alc1_0.like_count,alc1_0.version from article_like_count alc1_0 where alc1_0.article_id=?Hibernate: select alc1_0.article_id,alc1_0.like_count,alc1_0.version from article_like_count alc1_0 where alc1_0.article_id=?Hibernate: select alc1_0.article_id,alc1_0.like_count,alc1_0.version from article_like_count alc1_0 where alc1_0.article_id=? 어느 부분이 문제일까요? ArticleLikeController에서 count 경로는 테스트처럼 뒤에 /count 추가했습니다.
-
해결됨6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법
API 별 실행 쿼리 모니터링 구현 질문 있습니다.
1. 현재 학습 진도몇 챕터/몇 강을 수강 중이신가요? 여기까지 이해하신 내용은 무엇인가요? 2. 어려움을 겪는 부분어느 부분에서 막히셨나요?코드의 어떤 로직이 이해가 안 되시나요?어떤 개념이 헷갈리시나요? 3. 시도해보신 내용문제 해결을 위해 어떤 시도를 해보셨나요?에러가 발생했다면 어떤 에러인가요?현재 작성하신 코드를 공유해주세요 안녕하세요 강의 잘 보고 있습니다. 저는 강의를 보고 아래와 같이 이해를 했습니다.1.API 별 실행 쿼리 모니터링 구현2.그러면, 모든 api 엔드포인트에 대한 쿼리 min , max값을 알 수 있음. 질문1근데, 그렇게 되면 실제로 서비스에 필요한 코드와 모니터링 코드가 불필요하게 섞이는 거 아닌가요? 왜냐하면, 실제 모니터링이라고 하면 서버를 유지보수할 때, 필요한 데이터를 실시간으로 받아와서 시각화한다는 것으로 이해를 했습니다. 그런데 "API 별 실행 쿼리 모니터링 구현"은 서버의 유지보수에 필요한 모니터링 기능이 아니라, 1번만 딱 실행되면 되는데 이 부분이 왜 모니터링 구현으로 분류가 되는지 잘 모르겠습니다! 질문2API 별 실행 쿼리 모니터링 구현 부분에서, 실무에서도 "API 별 실행 쿼리 모니터링을 구현"해서 사용하는게 맞나요? 잘은 모르겠지만, 쿼리 분석이나 다른 방법이 있을 것 같은데 왜 이 부분이 서비스 코드 내에 포함을 시키면서까지 모니터링의 영역으로 분류가 되는지 잘 모르겠습니다 ! 질문3 만약에 실무에서는 해당 방법을 잘 사용하지 않는다면 API 별 실행 쿼리 횟수를 보통 어떤 식으로 측정을 하는건가요??? 감사합니다 ! 이렇게 구체적으로 알려주시면, 더 정확하고 도움이 되는 답변을 드릴 수 있습니다!
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
강의자료중 github 자료
학습 관련 질문을 최대한 상세히 남겨주세요!고민 과정도 같이 나열해주셔도 좋습니다.먼저 유사한 질문이 있었는지 검색해보세요.인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 혹시 github 자료도 받아볼 수 있나요?
-
미해결실습으로 배우는 선착순 이벤트 시스템
consumer가 topic을 전부 사용하기 전에 사용자에게는 쿠폰이 발급된것으로 확인하는 과정에서 발생가능한 문제.
운영중인 서비스에서 선착순 100명 이벤트를 적용한다고 가정하겠습니다. redis를 통해 100명을 제한했고, kafka를 적용하여 부하를 줄여주는 것은 까지는 이해했습니다. 부하를 줄이는 방법이 kafka를 적용할때 때 provider가 topic을 생성하고 consumer가 topic을 가져와서 DB에 입력하는 작업을 하는 것으로 이해했는데요. 만약 이게 실제 운영 환경이라고 가정했을때 궁금한것은 다음과 같습니다.사용자가 이벤트 신청redis에서 쿠폰 생성 수량 확인 결과 생성 가능한 조건 임으로 새로운 쿠폰 발급provider가 새로운 토픽을 생성 토픽을 생성한 그 순간 바로 직후, 사용자는 새로운 쿠폰이 발급된 것으로 확인 해야함.그치만 consumer에서 topic을 가져오기 전으로 DB에는 새로운 쿠폰이 생성되지 않음.쿠폰을 사용(또는 확인) 하려고 DB에서 select해보니 쿠폰이 없음consumer가 이제서야 쿠폰 생성이 경우에서 보는 것과 같이.provider가 topic을 생성하고 consumer가 topic을 가져와서 DB에 넣는 과정 사이에 사용자가 select를 진행하는 케이스가 있을것같습니다.이 부분은 어떻게 해결할 수 있을까요?혹시 다음과 같이 해결 할 수 있을까요?provider가 topic을 생성하는 과정에서 발급 내역을 redis에 입력consumer가 모든 토픽을 전부 사용하여 DB에 입력하기 전까지 redis에 입력되어 있는 쿠폰 정보로 사용자에게 보여줌consumer가 모든 토픽을 사용했을때(= 생성된 모든 쿠폰정보를 DB에 입력했을때) redis에 있는 쿠폰정보는 삭제하고 DB에서 select해서 보여줌.궁금합니다.
-
해결됨15일간의 빅데이터 파일럿 프로젝트
gcc 설치 에러
안녕하세요 빅디님 ! gcc 설치 중에 오류가 나서 yum repository 삭제 후 다시 시도해 보았는데, 계속 오류가 나서 질문 드립니다. ㅠㅠ 어떤게 문제일까요..? yum repo 삭제는 다음과 같이 진행 하였습니다. [root@server02 ~]# cd /etc/yum.repos.d/ [root@server02 yum.repos.d]# rm -rf remi.* remi-* [root@server02 yum.repos.d]# [root@server02 yum.repos.d]# cd /var/cache/yum/ [root@server02 yum]# rm -rf x86_64 [root@server02 yum]# [root@server02 yum]# yum clean headers Loaded plugins: fastestmirror, refresh-packagekit, security Cleaning repos: base cloudera-manager extras updates 0 header files removed [root@server02 yum]# yum clean packages Loaded plugins: fastestmirror, refresh-packagekit, security Cleaning repos: base cloudera-manager extras updates 0 package files removed [root@server02 yum]# yum clean metadata Loaded plugins: fastestmirror, refresh-packagekit, security Cleaning repos: base cloudera-manager extras updates 0 metadata files removed 0 sqlite files removed 0 metadata files removed yum install -y gcc* 명령어 입력시 발생하는 오류 입니다.[root@server02 ~]# yum install -y gcc* Loaded plugins: fastestmirror, refresh-packagekit, security Setting up Install Process Loading mirror speeds from cached hostfile Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=6&arch=x86_64&repo=os&infra=stock error was 14: PYCURL ERROR 6 - "Couldn't resolve host 'mirrorlist.centos.org'" Error: Cannot find a valid baseurl for repo: base 추가로, CentOS-Base.repo 파일 내용 첨부드립니다. [root@server02 yum.repos.d]# cat CentOS-Base.repo # CentOS-Base.repo # # The mirror system uses the connecting IP address of the client and the # update status of each mirror to pick mirrors that are updated to and # geographically close to the client. You should use this for CentOS updates # unless you are manually picking other mirrors. # # If the mirrorlist= does not work for you, as a fall back you can try the # remarked out baseurl= line instead. # # [base] name=CentOS-$releasever - Base mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra #baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6 #released updates [updates] name=CentOS-$releasever - Updates mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates&infra=$infra #baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6 #additional packages that may be useful [extras] name=CentOS-$releasever - Extras mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra #baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6 #additional packages that extend functionality of existing packages [centosplus] name=CentOS-$releasever - Plus mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus&infra=$infra #baseurl=http://mirror.centos.org/centos/$releasever/centosplus/$basearch/ gpgcheck=1 enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6 #contrib - packages by Centos Users [contrib] name=CentOS-$releasever - Contrib mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=contrib&infra=$infra #baseurl=http://mirror.centos.org/centos/$releasever/contrib/$basearch/ gpgcheck=1 enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6 감사합니다.
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
COUNT 쿼리에 LIMIT
안녕하세요COUNT 쿼리에 LIMIT 를 지정하는 이유가 있을까요? 설명해주셨는데 놓친건지 모르겠네요ㅜ
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
게시글 조회 최적화 전략 도입 관련, 조회수 원본 데이터와 비교하였을때 원본과 캐싱 데이터 모두 Redis에서 추출하는 데이터임에도 (별도의 key 운용 등) Redis 캐싱 과정을 원본추출 과정과 따로 간주하는 이유(데이터를 가져오는 과정만 보았을때)
학습 관련 질문을 최대한 상세히 남겨주세요!고민 과정도 같이 나열해주셔도 좋습니다.먼저 유사한 질문이 있었는지 검색해보세요.인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.안녕하세요 선생님!지난번에 남겨주신 답변내용을 보면서 전략도입의 배경부터 처리과정까지 복기해보았습니다.그러다가 의문이 생긴 점이 있습니다.1) 의문점Request Collapsing, 캐싱중복적재를 제외하고 캐싱하여 데이터를 추출하는 과정만을 보았을때, 원본과 캐싱 데이터 모두 Redis에서 추출해오는 것인데, 원본추출과 비교하였을때 과정적으로 어떠한 차이점이 추가적으로 있있기에 별도의 과정으로 간주하는 것일까? 즉, "캐싱하여 가지고 오는 과정"과 "원본 데이터 추출"을 따로 보고 계셨기에, 어떠한 차이점이 있는지 의문점이 들었습니다. 2) 의문점이 생긴 이유단순하게 간략히 말씀드리자면,조회수 원본데이터는 Redis에서 가져오는 조회수이고, 캐싱해서 가져오는 것 역시 Redis에서 가져오는 조회수로 보여집니다. 원본데이터가 MySQL과 같은 디스크 조회 비용이 큰 저장소에 들어있는 것이 아니라, 동일한 In Memory database인 Redis에서 가져오는 것이기에 성능/비용적으로 캐싱 데이터를 가지고 오는 것에 큰 이점을 느끼지 못하였습니다. 세부적으로 살펴보았을때,ViewClient에서 원본 데이터를 가지고 오는 경우 아래 로직을 통해 Redis에서 추출합니다.articleViewCountRepository.read(articleId);이떄 key는 view::article::#articleId::view_count 입니다.ViewClient에서 Aspect를 처리하여 캐싱 데이터를 가지고 오는 경우 Redis에서 추출합니다.이때 key는 articleViewCount::#articleId입니다.이 과정에 대해 캐싱을 하는 목적을 생각해보았을때(=원본데이터 추출에 시간이 오래 걸릴 경우 성능이 빠른 다른 데이터저장소를 운용하여 이곳에서 데이터를 추출해오기 위함), 동일하게 Redis에서 추출하는 데이터임에에도 key를 별도로 운용하고, 데이터를 추출하는 과정도 다르게 가져가는(간주하는) 이유가 무엇인지 궁금하여 문의코자 합니다(물론 전체 로직을 살펴보았을때는 기존 대비 중복적재/Request Collapsing 과정을 추가하였기에 당연히 성능적인 이점이 존재하겠지만, 데이터를 가져오는 과정 그 자체만을 보았을때는 의문점이 들었습니다). 이게 데이터를 추출하는 과정이 다르기에, 동일한 key로 운용하면 실무적으로 로직이나 key관리방안이 복잡해져서 관리의 효율화를 위해 나누는 것일까요(즉, 기존과 달리 분산락도 사용하고 중복적재를 방지하기 위해 이용하므로 목적 자체가 다르기에 key 포맷 및 캐싱을 별도로 운용하는 것으로 이해하는 것이 적절한지)? 제가 캐싱의 목적 부터 잘못 이해하고 있는 것일 수 있고, 실무적으로 비용/성능적 유리하다는 의미가 무엇인지 잘못 이해하고 있는 것일 수 있다고 생각하고 있습니다. 그렇기에 챗지피티에게 물어보기보다는 실무적으로 경험이 풍부하시고 그만큼 검증된 선생님의 판단이 더 정확하고 궁금하여 질문드리게 되었습니다. 바쁘신데도 항상 성심성의껏 답변해주시는 선생님께 감사의 말씀 드립니다. 이효균 드림.
-
미해결비전공자도 이해할 수 있는 Redis 입문/실전 (조회 성능 최적화편)
redis 적용을 위한 service 반환값
안녕하세요. redis 강의를 통해 간단한 프로젝트로 적용을 하려고 합니다. @Cacheable( value = "reviewList", key = "'review:store:' + #storeId + ':page:' + #pageable.pageNumber", cacheManager = "reviewCacheManager", condition = "#pageable.pageNumber == 0") @Transactional(readOnly = true) public Page<ResViewReviewDto> getReviews(UUID storeId, ReviewRepositorySearchConditionDto condition, Pageable pageable) { Page<ResViewReviewDto> reviews = reviewRepository.findReviews(storeId, condition, pageable); return new PageImpl<>(reviews.getContent(), pageable, reviews.getTotalElements()); }원래는 return reviews를 했더니 계속 조회를 누르면 ClassCastException: LinkedHashMap cannot be cast to Page 이 오류가 나오게 됩니다. 강의에서는 그냥 getContent를 List로 반환값을 보냈는데 혹시 위 코드처럼 new PageImpl 형식으로 return 해도 괜찮을까요?
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
게시글 조회 최적화 전략과 게시글 목록 최적화 전략 구분에 따른 정책수립/관리의 비용 관련 문의
학습 관련 질문을 최대한 상세히 남겨주세요!고민 과정도 같이 나열해주셔도 좋습니다.먼저 유사한 질문이 있었는지 검색해보세요.인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요, 선생님! 강의 알차게 잘 수강하고 있습니다.현재 90% 수강 완료하였는데, 어렵고 힘들게 여기까지 온 만큼 저의 역량도 비교할 수 없을 정도로 많이 성장한 것 같습니다.먼저 감사의 말씀을 드립니다.일단 현재 게시글 목록 최적화 전략 구현(64강) 강의를 수강 중인데, 이전의 강의 내용(게시글 조회 최적화 전략)과 비교하였을때 최적화 전략을 수립하는 과정과 관련하여 몇가지 의문점이 들어 질문드리게 되었습니다.의문점) - 게시글/카테고리에 대한 게시글 목록 모두 전략을 나누어야 하는가?의문점이 들었던 과정) - 일단 크게 보았을때, 게시글 내용에 대한 캐싱(articleId)과 게시글 목록(*특정 카테고리, board로 지칭)에 대한 캐싱(boardId)으로 내용을 나눌 수 있을 것 같습니다.- 여기서 드는 제 개인적인 생각은, (일단 전략의 당위성이나 세부적인 내용 상관없이) 캐싱전략을 너무 세세하게, 오히려 성능적 이점보다는 관리적 비용이 더 크게 소모되지 않을까 하는 염려가 들 정도로 배꼽이 더 큰 전략/관리방안을 각각 구분해놓는 것이 아닌가하는 생각이 들었습니다.- 예를 들어, 게시글 목록 최적화 전략의 경우 말씀하신대로 최초 목록 조회 진입 시 보여지는 내용이기도 하고 이는 모든 사용자에게 공통적으로 적용할 수 있는 정책이므로 관리의 당위성이나 책임이 명확하다고 생각하였습니다.- 하지만 게시글 조회 최적화 전략의 경우, 목록 최적화 전략을 수강한 이후에는 "게시글 조회"역시 어떻게 보면 그 게시글을 보고싶은 사용자 일부에 대해서만 보여지는 글이므로..지금처럼 모든 생성 글/댓글/좋아요에 대해 ArticleQueryModel 데이터를 생성하는 것이 비용효율이나 관리효율면에서 과연 올바른 방향인지 다소 의문이 들게 되었습니다. 또한, 이러한 전략수립의 당위성을 떠나서 각 조회기능별로 전략을 구상하는게(단건/목록 등) 수립은 가능하더라도 관리가 힘들 것 같은데, 실무적으로 관리가 가능할지 의문이 들기도 하였습니다.최종 질문)- 제가 올바르게 강의내용을 이해하지 못하여 질문드리는 것 일 수 있기에, 일단 제가 들었던 의문이 선생님께서 생각하셨을때, 타당한 의문일지 궁금합니다.- 타당하다면 아래와 같은 "게시글 단건" 조회 전략을 생각할 수 있을 것 같은데, 혹시 바람직한 전략이 될 수 있을지 고견을 요청드려보고자 합니다.- 또한 실무적으로 이러한 다양한 관리전략을 수립하게된 계기가 "성능문제" "사용자 패턴에 따른 문제점 예상" 등, 여러 문제 중 어떠한 부분이 가장 중요하게 작용하는지 궁금하여 질문드립니다.[단건 조회전략 구상 방안] 게시글 조회 전략을 만약 구상한다면(세부적인 전략구현은 생략)- 지금처럼 단건 데이터 생성마다 articleQueryModel을 구성하는 것이 아니라, 각 카테고리별 보여지는 1000개의 데이터에 대해 articleQueryModel 데이터를 구성한다. (*게시글을 보는 것도 결국 최신 1000개의 데이터에 대해서만 볼 것이기 때문이다.)- 인기글 데이터 생성 후 해당 인기글에 대한 articleQueryModel 데이터를 구성한다.(*인기글 데이터에 대해서만 단건 조회 트래픽이 몰릴 것으로 예상할 수 있기 때문이다.)읽어주셔서 감사드립니다.
-
해결됨은행 서버 프로젝트 실습을 통해 배우는 코틀린 마스터 클래스
강의 19] 질문입니다.
안녕하세요! 강의 너무 잘 보고 있습니다!강의를 보는 중 궁금한 부분이 생겨 질문드려봅니다!@GetMapping("/callback") fun callback( ... return ResponseEntity.status(HttpStatus.FOUND) .location(URI.create("https://localhost:3000")).build()콜백 함수에 return을 이렇게 작성하셨는데요!만약에 서블릿객체를 이용해서 쿠키를 담지 않고 아래와 같이 하는 방법은 어떻게 보시는지요...?? 같은 동작을 할 것으로 예상은되는데 보편적인 스타일이 궁금합니다 ㅋ.ㅋ;```return ResponseEntity .status(HttpStatus.FOUND) .header("Set-Cookie", "authToken=$token; HttpOnly; Path=/; Max-Age=${60 60 24 * 7}") .location(URI.create("http://localhost:3000")) .build()```
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
물리샤드, 논리샤드 번호 질문입니다!
안녕하세요!다른 분 질문에 대한 답변을 보고 기본적인 의구심은 해소되었는데요. 혹시 몰라 확인차 여쭙습니다.09:38 피피티에서요.나머지 연산을 이용해서 물리샤드, 논리샤드를 구분하셨잖아요.제가 이해하기로 나머지가 0이면 1번 샤드, 1이면 2번 샤드...이렇게 의도하시려고 했던 것 같아요.https://inf.run/7i72V여기에서 답변해주신 것과 피피티의 샤드 번호 현황?이 달라서 조금 혼란스러웠습니다. 링크 답변을 보면 아주 간단한 샤딩 예시였지만, 물리 샤드가 두 개일 때 % 2를 적용하면 1번 샤드(나머지 연산결과 +1)에는 article_Id가 [2, 4, 6, 8]이 들어가고 2번 샤드에는 [1, 3, 5, 7]이 들어갈 테죠.논리 샤드 기준으로는1번 논리샤드 = [4, 8]2번 논리샤드 = [1, 5]3번 논리샤드 = [2, 6]4번 논리샤드= [3, 7] 1번 물리 샤드에는 1, 3번 논리 샤드2번 물리 샤드에는 2, 4번 논리 샤드(링크 답변과 동일한 분포)이게 제가 위의 답변을 강의 자료에 적용해서 이해한 샤딩 현황입니다! 실제 프로덕션에서도 이렇게 샤딩하는지는 모르겠지만 교육 목적 상 간단한 해싱이었어도 제대로 이해하고 넘어가고 싶었습니다.PPT만 보고는 나머지 연산이 어떻게 사용된 건지 이해가 안 됐는데 답변 보고 이해가 돼서 확인 차 질문드렸습니다.추가적으로 클라이언트는 논리 샤드만 알고 있다고 하셨는데 그럼 물리 샤드 번호는 물리적으로 나뉜 샤드를 구분하는 데만 사용하고 비즈니스 로직에서는 사용되는 일이 없을까요?감사합니다.
-
미해결실습으로 배우는 선착순 이벤트 시스템
쿠폰에 관련되어서 좀 더 참고할만한 자료가 있을까요?
쿠폰에 관련되어서 좀 더 참고할만한 자료가 있을까요?
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
댓글 내용 조회 시 어떤 방식을 선택하실까요?
게시글 조회 기능을 확장하려고 할 때 댓글을 조회하는 방향에 대해 고민이 있어서 질문 남깁니다.게시글 하나를 보는 페이지로 사용자가 이동해서, 게시글의 내용과 댓글들까지 이동한 페이지에서 그려야 할 때 게시글 정보와 해당 게시글의 모든 댓글을 가져오는 기능을 신규로 추가하려고 합니다. 해당 기능의 구현에 대해 2 가지 방향을 고민해봤습니다.게시글처럼 댓글까지 캐싱하는 방법Hot data 로 캐싱된 게시글들의 댓글들을 캐싱하는 것을 고민했을 때, 댓글은 게시글보다 훨씬 많은 양이기 때문에 캐싱에 대한 비용이 너무 커지는 것에 부담이 생기는 문제가 있다고 생각합니다.댓글에 대한 조회는 매번 댓글 서비스에서 조회하는 방법실시간으로 게시물의 댓글을 계속 조회한다면, 조회 서비스에 읽기 부하가 크게 걸릴 것으로 생각합니다. 두 방식 다 장단점이 있다고 생각하는데, 강사님께선 어떤 방식으로 게시글 + 댓글 조회 기능을 구현하실지 의견이 궁금합니다!
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
강의 전에 학습할 내용
해당 강의를 수강하기 전에 사전 학습으로 준비하면 좋은 내용들(MySQL, Redis, Kafka, 시스템 설계 등)에 대해 추천해주실 만한 책이나 강의가 있을까요?저에게는 이 강의가 다소 어렵게 느껴져서, 관련 내용을 따로 공부한 후 다시 수강하고 싶습니다.혹시 강의 내용과 연관되어 쿠케님께서 좋다고 느끼셨던 자료나 도움이 되었던 책, 강의 등이 있다면 공유 부탁드립니다!
-
미해결개발자라면 알아야 할 redis 기본
실무에서의 복잡한 쿼리 결과 캐싱 전략(크기, TTL 등) 관련 질문
강사님, 캐싱 관련해서 실무적인 관점의 질문이 있습니다.강의에서 String 타입의 value에 JSON 형식으로 데이터를 저장해서 캐싱 처리를 한다고 배웠는데, 실무에서 어느 범위까지 캐싱하는 게 적절한지 감을 잡고 싶습니다. 과거에 MyBatis의 동적 쿼리처럼 조건부 로직이 포함된 200줄짜리 복잡한 쿼리가 DB에서 파싱되는 시간 자체만으로도 성능 부하를 유발했던 경험이 있습니다.쿼리 자체를 수정하는 것이 베스트겠지만, 현실적으로 어려울 때가 있었습니다. 이런 '고치기 힘든 악성 쿼리'의 실행 자체를 회피하는 목적으로 Redis 캐싱을 적극적으로 사용하는 전략에 대해 궁금합니다. 실무에서는 이런 경우:1. 쿼리 결과 데이터가 어느 정도 크기(예: 수십 MB)까지 Redis에 캐싱을 허용하시나요?데이터가 너무 크면 오히려 Redis에 부담이 될 것 같아서요. 2. 만약 결과가 너무 크다면, 페이징 처리된 일부만 캐싱하시나요?아니면 보고서처럼 핵심 요약 데이터만 따로 캐싱하는 전략을 사용하시나요? 3. 특히 이런 복잡한 집계/통계 쿼리는 데이터 변경이 잦지 않은데,이런 경우 TTL은 보통 어느 정도로 설정하시는지 강사님의 경험이 궁금합니다.
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
Transactional Outbox 테이블 관련하여 질문드립니다
안녕하세요, 강의를 통해 대규모 시스템 설계에 대한 다양하고 실무적인 방법을 배우게 되어 감사히 수강하고 있습니다!수강중 Transactional Outbox 테이블 관련하여 궁금한 부분이 있어 질문드립니다.실무에서는 보통 "Outbox 테이블에 Insert -> kafka send 후 Outbox 상태 Update" 하는 방식으로 쓰일까요? 강의에서는 간단히 Delete로 구현한다고 말씀주셔서 질문드려봅니다!Update 하는 방식도 자주 쓰인다면 Outbox 테이블은 파티셔닝(p20251001 와 같이)하여 관리하고 주기적으로 삭제하는 방식일지도 궁금하여 질문드립니다!
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
카프카 메시지 순서 관련 문의
안녕하세요 강사님!카프카를 사용하면서 궁금한 점이 있어서요~ 예를 들어 주문 시스템을 구현한다고 하면요.주문에 대해 상태가 계속 바뀌어 해당 이벤트를 받을 수 있도록 카프카를 붙이려고해요.consumer가 동일한 주문 id에 대해 상태 업데이트를 해야 하니, producer가 순서 보장되도록 카프카 key도 동일하게 셋팅하면 consumer는 순서대로 status를 제대로 update 하는데요. 만약 producer가 메시지 발행을 비동기적으로 진행하도록 구현했다고 하면,무언가 이슈로 주문 생성 -> 주문 취소 순이 아닌 주문 취소 -> 주문 생성 순으로 발행되었다면consumer 입장에서 메시지 순서가 제대로 들어왔음을 어떻게 인지할 수 있을까요..? 이런 상황은 발생하지 않을까요..? ㅎㅎ
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
만약 조회수가 중요한 데이터라면 어떻게 해야 되나요?
안녕하세요 강사님!아직 완강은 아니지만 너무 재밌게 잘 보면서 많이 배우고 있습니다! 이번 강의를 보다가 궁금한 점이 생겨 질문을 남깁니다!강의에서 제시해주신 조회수라는 정보가 게시판이라는 도메인으로 보았을 때 비교적 중요하지 않다고 하신거에 충분히 동의합니다!근데, 문득 조회수를 통해 수익이 발생하는 서비스(ex. 유튜브)에서는 중요한 정보 아닌가? 라는 고민이 생겼습니다. 중요한 정보인데 쓰기가 자주 발생하는 상황에서 In-Memory 저장소를 메인으로 사용하고 RDB를 백업용으로 사용하면 위험하지 않나? 라는 생각이 들었습니다!이럴 때에는 보통 어떻게 처리하시나요? (이럴 때 NoSQL을 사용하나요?)
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
완강 후 학습 방향에 대한 질문
쿠케님 안녕하세요!우선 좋은 강의 제작해주셔서 정말 감사합니다. 강의 들으면서 대규모 시스템을 설계할 때는 어느 것을 신경써야 하고, 또 주의해야 하는지 많은 인사이트를 얻고 있어요. 추석 연휴 동안 제 나름대로 열심히 들어서 이제 한 개 섹션만 남았는데, 완강을 한 뒤에 강의에서 얻은 것들을 토대로 대규모 트래픽을 가정한 서비스를 설계하고, 개발해보려고 합니다. 강의로만 듣고 넘기기에는 아까운 내용들이 많아서 확실하게 제 것으로 만들어야겠다 싶더라고요. 일하면서 써먹으면 더없이 좋겠지만 아쉽게도 그럴 환경은 안 되어서요.. ㅎㅎ 그래서 나름대로 구상을 해보면서 강의를 듣고 있는데, 문득 강의에서 다룬 아키텍처와 기술을 한 번에 다 도입하는 건 오히려 학습 효율을 떨어뜨리는 선택이 아닐까 싶은 생각이 들어서요. 실무에서 Redis 정도는 사용해봤지만, 분산 데이터베이스나 MSA도, Kafka나 CQRS도 이 강의에서 처음 사용해봤습니다. 개념은 대충 주워 듣긴 했지만, 제대로 공부해본 적도 없고요. 결론적으로 하나씩 해보는 게 낫겠다 싶은데, 강의에서 다룬 내용 중 어느 것을 먼저 학습하는 게 좋을지 쿠케님께 조언을 구하고 싶어요. 물론 정답이 없는 문제지만, 지금 당장 제가 일하는 환경에서는 써먹을 일이 별로 없는 내용들이다 보니 무엇을 먼저 하는 게 좋을지 선택하기가 어렵네요. 감사합니다.
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
Kafka 대신 Redis Pub/Sub을 사용할 수도 있을까요?
안녕하세요, 강사님!Kafka 관련 강의를 듣다가 기술 선택의 기준에 대해 궁금한 점이 생겨 질문드립니다. 현재 강의에서 Kafka를 이벤트 브로커(Event Broker)로 사용하고 계신데,Redis의 Pub/Sub 또는 Redis Streams 기능을 이용하면비슷한 형태로 서비스 간 메시지 전달을 구현할 수도 있을 것 같다는 생각이 들었습니다. 그래서 아래 두 가지 부분이 궁금합니다 Kafka를 선택하신 이유 또는 기준이 무엇인지 예: 처리량, 확장성, 영속성, 장애 복구 등 기술적 관점에서 어떤 요소가 결정적이었는지혹은 실제 서비스 환경에서 Redis 기반 메시징을 사용했을 때의 한계가 있었는지도 궁금합니다. 이벤트 브로커(Event Broker)와 메시지 브로커(Message Broker)의 개념적 차이 두 용어가 거의 비슷하게 사용되는 경우도 많은데,Kafka가 ‘이벤트 브로커’로 분류되는 이유가 무엇인지 알고 싶습니다.실제로 시스템 설계 시, 어떤 기준으로 두 개념을 구분하고 선택하시는지도 궁금합니다. 제가 이해하기로는 Redis는 단순한 메시지 전달 중심,Kafka는 이벤트 스트리밍 및 데이터 파이프라인 중심으로 알고 있는데,이 부분이 맞는 방향인지도 확인해보고 싶습니다.