안녕하세요. 강의를 들으며 issuance 테이블에 status, coupon_id로 각각 인덱스를 생성하시면서 조회성능을 향상시키기 위함이라 설명하셨는데요. 특히 status를 이용한 인덱스가 꼭 필요한지 궁금합니다. 현재 status는 3가지 타입으로 (추후에도 늘어날 value가 제한적) 선택도가 약 33% 정도로 보입니다. 이렇게 가짓수가 적은 경우에는 인덱스의 효율을 잘 활용하기 어려워 인덱스를 생성하는 것이 비효율적이라고 학습한적이 있는데 지금과는 다른 상황인가요??
선생님, 안녕하세요. 강의 즐겁게 듣고 있습니다. 6장 28의 수강 중 Producer의 Simple Producer 이해하기 동기/비동기 전송 관련해서 궁금한 점이 있어 질문드립니다. 타임라인은 9:00 입니다. 강의에서는 producer.produce(topic, key="key", value="value")처럼 on_delivery 파라미터를 지정하지 않은 경우를 동기 전송으로 설명해주셨고, on_delivery 콜백을 지정한 경우를 비동기 전송으로 설명해주신 것으로 이해했습니다. 그런데 Confluent Kafka Python 공식 문서를 보면 produce() 자체가 asynchronous operation으로 설명되어 있고, on_delivery는 전송 완료 결과를 전달받기 위한 callback으로 보입니다. 제가 이해한 바로는 on_delivery의 유무와 관계없이 produce() 자체는 비동기이고, on_delivery는 성공/실패 결과를 전달받기 위한 용도인 것 같은데요. 강의에서 on_delivery가 없는 경우를 동기 전송이라고 표현하신 기준이나 맥락이 따로 있는지 궁금합니다. 소중한 시간 내주셔서 감사합니다.
강의에서는 부하 테스트 시 시나리오 작성을 아래와 같이 5000 rps 정도로 부하를 가했을 때와, 1000 rps 수정해서 부하를 가했을 때의 latency(p50, 90, 99) 차이가 있는데, 실무에서는 보통 어떤 기준을 가지고 rps 를 정하는지 궁금합니다! scenarios: { burst: { ... rate: 5000, timeUnit: '1s', duration: '30s', // 1000 req/s × 30s = 총 30,000 요청 }, },
안녕하세요, 현재 Kafka & Spark강의를 수강하고 있고, Section 12에 Hive metastore를 보고 있습니다. 설치과정중에 오류가 있어서 여쭙고자 Q&A드립니다. 8분부터 링크를 넣고 ( https://repo1.maven.org/maven2/org/apache/hive/hive-standalone-metastore/3.1.2/hivestandalone-metastore-3.1.2-bin.tar.gz) 다운로드를 진행하는데, 현재 다운로드 받는 파일 네이밍이 hivestandalone-metastore-3.1.2-bin.tar.gz되어 있어서 ansible-playbook으로 실행하였을때 naming이 맞지 않아서 오류가 발생합니다 ( hive-standalone-metastore-3.1.2-bin.tar.gz) download 된 파일의 이름을 변경해서 진행해봤는데, 다음과 같은 오류가 뜨면서 파일이 제대로 실행되지 않습니다. 확인 부탁드리겠습니다. fatal: [spark03]: FAILED! => {"changed": false, "msg": "Failed to find handler for \"/home/ubuntu/.ansible/tmp/ansible-tmp-1787779731.3065977-4001-20263566616026/source\". Make sure the required command to extract the file is installed.\nCommand \"/usr/bin/tar\" could not handle archive: Unable to list files in the archive: zstd: /*stdin*\\: unsupported format \n/usr/bin/tar: Child returned status 1\n/usr/bin/tar: Error is not recoverable: exiting now\n\nCommand \"/usr/bin/tar\" could not handle archive: Unable to list files in the archive: bzip2: (stdin) is not a bzip2 file.\n/usr/bin/tar: Child returned status 2\n/usr/bin/tar: Error is not recoverable: exiting now\n\nCommand \"/usr/bin/tar\" could not handle archive: Unable to list files in the archive: xz: (stdin): File format not recognized\n/usr/bin/tar: Child returned status 1\n/usr/bin/tar: Error is not recoverable: exiting now\n\nCommand \"/usr/bin/tar\" could not handle archive: Unable to list files in the archive: \ngzip: stdin: not in gzip format\n/usr/bin/tar: Child returned status 1\n/usr/bin/tar: Error is not recoverable: exiting now\n\nCommand \"/usr/bin/tar\" could not handle archive: Unable to list files in the archive: /usr/bin/tar: This does not look like a tar archive\n/usr/bin/tar: Skipping to next header\n/usr/bin/tar: Exiting with failure status due to previous errors\n\nCommand \"/usr/bin/unzip\" could not handle archive: End-of-central-directory signature not found. Either this file is not\n a zipfile, or it constitutes one disk of a multi-part archive. In the\n latter case the central directory and zipfile comment will be found on\n the last disk(s) of this archive.\nnote: /home/ubuntu/.ansible/tmp/ansible-tmp-1787779731.3065977-4001-20263566616026/source may be a plain executable, not an archive\nunzip: cannot find zipfile directory in one of /home/ubuntu/.ansible/tmp/ansible-tmp-1787779731.3065977-4001-20263566616026/source or\n /home/ubuntu/.ansible/tmp/ansible-tmp-1787779731.3065977-4001-20263566616026/source.zip, and cannot find /home/ubuntu/.ansible/tmp/ansible-tmp-1787779731.3065977-4001-20263566616026/source.ZIP, period.\n"}
학습 관련 질문을 최대한 상세히 남겨주세요! 고민 과정도 같이 나열해주셔도 좋습니다. 먼저 유사한 질문이 있었는지 검색해보세요. 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요. 64강 17분쯤 ArticleReadService의 count 메서드 구현하신 코드를 보면 아래 코드블럭과 같이 작성하셨습니다. private long count(Long boardId) { Long result = boardArticleCountRepository.read(boardId); if (result != null) { return result; } long count = articleClient.count(boardId); boardArticleCountRepository.createOrUpdate(boardId, count); return count; } 그런데 BoardArticleCountRepository의 count 메서드는 아래와 같이 작성하셨는데 이 경우 boardArticleCountRepository.count(boardId);는 Redis에서 데이터가 조회되지 않은 경우 0L를 반환하여 ArticleReadService의 count 메서드에서는 항상 client에서 조회하는 케이스가 발생하지 않을거 같습니다. public Long read(Long boardId) { String result = redisTemplate.opsForValue().get(generateKey(boardId)); return result == null ? 0L : Long.valueOf(result); }
안녕하세요! 강의 잘 듣고 있습니다. 아래 issue 메서드 관련해서 질문드립니다. @Transactional fun issue(couponId: Long, userId: Long): Issuance { val policy = couponIssuePolicyReader.get(couponId) val now = LocalDateTime.now() if (!policy.isBookingOpen(now)) { throw NotStartedException() } val expiresAt = now.plusDays(policy.validityDays.toLong()) couponIssuer.tryIssue(couponId, userId) issuanceRequestProducer.publish( IssuanceRequested( couponId = couponId, userId = userId, issuedAt = now, expiresAt = expiresAt, ) ) return Issuance( userId = userId, couponId = couponId, issuedAt = now, expiresAt = expiresAt, ) } 해당 코드에서 couponIssuer.tryIssue() (Redis)는 성공했는데 바로 다음 issuanceRequestProducer.publish() (Kafka)가 실패하는 경우 재고는 차감됐는데 이벤트는 유실된 불일치 상태가 될 수 있을 것 같습니다. 만약 재고를 DB로 관리한다면 아웃박스 패턴으로 같은 트랜잭션 안에서 이벤트를 아웃박스 테이블에 적재하고 별도 워커가 Kafka에 발행하는 방식으로 원자성을 보장할 수 있을 것 같습니다. 그런데 지금처럼 재고 자체를 Redis로 관리하는 구조에서는 Redis와 Kafka 각각에 대한 이중 쓰기 문제가 생기고 아웃박스 패턴을 그대로 적용하기는 어려워 보입니다. 만약 해당 구조에서 at-least-once를 보장하려면 어떤 전략을 택해야 하는지 궁금합니다!
Domain 패키지에 Coupon 같은 @Entity 와 CouponRepository 를 함께 두셨더라고요! 영속성을 storage(또는 Infrastructure) 로 따로 분리하는 구성도 있는데, 여기서는 엔티티와 레파지토리 모두 domain 에 두신게 궁금했습니다. 혹시 이 서비스 규모에서는 db가 바뀔 가능성이 낮고, 엔티티를 밖으로 빼면 도메인 <-> 엔티티 매핑 비용만 늘어난다고 보셔서 의도적으로 domain 안에 함께 두신걸까요? 아니면 다른 기준이 있으셨는지 궁금합니다.
섹션1-11에서 MTputty를 다운로드하는 시간이였습니다. 사이트를 들어갔는데 현재 강의에서 사용되는 다운로드 URL은 사라져서 해당 홈페이지에서 다운로드 중이였는데, 다운로드 파일이 달라지고 링크 클릭 시 다른 페이지로 계속 이동되는 현상 때문에 의심스러워 AI에게 물어봐서 다운로드를 받았습니다. 결론적으로 공식 배포처는 ttyplus.com 이며 mtputty.com은 공식 사이트가 아닌 광고 수익형 사이트라 페이지 메타에 AdMaven광고 placement 삽입이 되어 있습니다. 처음에 다운로드 클릭 했을 때 VPN Download길레 뭐지 했습니다 AI 왈, 다운로드 링크는 제 3자의 GitHub 계정의 mtputty_auto_screen 저장 소스코드 ZIP으로 연결되어 있고 MTPutty는 프리웨어지만 오픈소스가 아니어서 소스 코드를 공개하지 않는 점으로 Git Hub에 공식 저장소가 존재할 수 없다 합니다. 그래서 공식 URL을 제공받아 다운로드를 진행 했는데 이점도 유의해서 사용하시면 될 것 같아요 https://ttyplus.com/download/mtputty_setup.exe
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 현재 Window 환경에 Ubuntu 20.04.6 이미지를 사용하고 Virtual Box 7버전을 사용하는데 터미널이 실행되지 않는 문제점이 발생합니다. 이에 따라 웹 서핑을 통해 Lang에 en 값을 uft8 값으로 변경해도 문제가 반복되어 서버를 삭제하고 다시 실행했는데 같은 문제가 반복되어 해당 강의에서 가상 머신 Virtual Box가 아닌 VMware로 사용해도 문제가 없나 질문드립니다.
MacOs 사용자 분들이시고 cat ~/.docker/config.json 의 결과에 credsStore 필드가 osxkeychain이고 auth 필드의 값이 비어있으신 경우 인증정보가 keychain으로 관리되고 있고 이걸 jib이 가져오지 못하고 있는 겁니다. 방법 1 (가장 추천합니다) jib 내부의 from과 to 블록의 image 선언 다음 credHelper { helper = "osxkeychain" } 해당 코드를 추가해 keychain에 접근할 수 있도록 해주면 좋습니다. + auth {}로 인증정보를 주입하는 방법으로도 대체 가능합니다. 방법 2 (문제 회피) java 25 이미지를 docker pull 받아 로컬에 두고 ./gradlew jibDockerBuild 하시면 됩니다. 나중에 redis를 받던데 그때로 같은 방법으로 해결하면 될 것같습니다. 방법 3 (keychain 필드깨서 강제로 base64쓰게 하기) credsStore 필드를 훼손시켜 강제로 auth에 암호화된 내용을 저장하도록 하는 것같습니다. 정말 추천하지 않으며, 위 방법이 모두 실패하면 시도해보세요.
학습 관련 질문을 최대한 상세히 남겨주세요! 고민 과정도 같이 나열해주셔도 좋습니다. 먼저 유사한 질문이 있었는지 검색해보세요. 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요 쿠케님 강의 너무 잘 보고 있습니다. 해당 내용 수강중에 궁금한 점이 생겨 질문 드립니다. 혹시 제목이나 내용을 검색한다고 했을때는 redis에서 조건을 통해 조회를 하는것인지 다른 전략이 있는지 궁금합니다!
안녕하세요 강사님. 강의 잘 듣고 있습니다. 이번 시간에 강사님께서 Spring WebFlux와 Spring Web MVC를 혼용해서 사용하는 경우, 결국에는 Web MVC의 기본 스레드인 톰캣 스레드를 사용해서 스레드 고갈이 될 수 있다고 하셨습니다. 따라서 내부적으로는 WebFlux의 이벤트 루프 스레드가 아닌 톰캣 스레드를 사용해서 블로킹되는 현상이 발생한다로 해석하면 될까요? 저는 혼용할 경우, Mono/Flux 타입 응답에 한해서는 동시 요청 발생 시 이벤트 루프 스레드를 사용하여 IO 작업을 대기하지 않고 해당 스레드가 다른 일을 처리하러 가는 것으로 알고 있었습니다. 혹시 이러한 상황에서 어떤 스레드를 사용하는지 테스트 해볼만한 좋은 방식이 있을까요? 감사합니다.
안녕하세요 쿠케님! 현재 구현되어 있는 댓글 삭제 로직을 보면 1. 댓글 조회 2-1. 자식 댓글이 존재하면 deleted=true 로 변경 2-2. 자식 댓글이 존재하지 않으면 댓글을 물리 삭제하고, 부모 댓글을 재귀적으로 삭제 이렇게 구현되어 있는데요. 동시성 문제가 발생할 수 있겠다는 생각이 들었습니다! T1 삭제 트랜잭션 T2 답글 트랜잭션 ──────────────────────────────────────────── SELECT 부모 SELECT 자식 → 없음 SELECT 부모 → ACTIVE INSERT 답글 COMMIT DELETE 부모 COMMIT (제가 잘 분석한게 맞나 모르겠네요 ㅎㅎ) 물론 이렇게 꼬일 확률은 낮지만, 이런 케이스에 대해서는 select for update를 거는 것이 좋을지, 아니면 fk를 추가하여 정합성을 보장해줘야 할지, 쿠케님 의견을 묻고 싶습니다.
강사님 안녕하세요, 좋은 강의 여러번 반복해서 잘 듣고 있습니다. 재고 감소와 비교했을때 차이점이 궁금하여 문의드립니다. 안녕하세요 강사님 이전 재고 관리 강의와 차이에 대해 궁금합니다. 이전 질문을 참고하였으나 추가로 더 궁금한게 있어서 문의드립니다. 재고 감소와 쿠폰 발급의 차이점이 너무 헷갈려서 정리하고 있습니다. 두 경우 모두 한정된 수량을 여러 요청이 동시에 차지한다는 점에서는 비슷해 보입니다. 그렇다면 쿠폰도 이벤트 테이블에 잔여 수량을 100개나 300개로 설정하고, 재고처럼 수량을 차감한 뒤 사용자 쿠폰을 생성하는 방식으로 구현할 수 있지 않을까요? 강의에서는 쿠폰 발급의 정합성을 위해서 전체 로직에 락을 걸 필요가 없다고 하셨는데, 그러면 반대로 재고 감소 같은 경우도 마찬가지로 재고 감소의 정합성을 위해 전체로직에 락을 걸 필요 없이 다른 방법으로 하는게 더 나은 방법 아닌가요?? 비슷해 보이는 한정 수량 문제를 서로 다르게 푼 이유를 잘 모르겠습니다 ㅠㅠ