게시글
질문&답변
실무에서의 락
재근님, 안녕하세요! 말씀하신대로 실무에서는 논리적 외래키로 가져가는 경우가 많습니다.대규모 시스템에서는 잠깐의 병목도 장애가 날 수 있기 때문에 비관적 락은 가능하다면 피하려곤 합니다.하지만 장애 위험도와 개발 비용을 적절히 고려하여 사용할 수도 있습니다.(강의에서는 단일 레코드에 비교적 적은 쓰기 트래픽으로 인한 락을 일시적으로 점유하므로, 비관적 락도 적절하다고 판단할 수 있는 배경)낙관적 락도 자주 사용하는데, 사용자 유즈케이스에 따라 필요하다면 실패 시에 재처리 동작을 수행하기도 합니다.그리고 정합성 문제는 꼭 락을 안 잡고 해결 할 수도 있습니다.(이 부분은 인기글 강의에서 배우는 분산 트랜잭션이란 개념을 활용할 수도 있습니다!)꼭 DB 락을 이용하지 않고, 다른 시스템의 락을 이용할 수도 있고요.(조회수 강의에서 배우게 될 레디스를 이용한 락 개념처럼) 개인적으로는 select for update는 언급된 위험성(락 점유가 길어질 수 있는) 때문에 굳이 잘 사용하진 않는 편이고,다른 부분(DB 락 외의 다른 방법으로도)은 상황에 따라 적절히 사용하고 있습니다! 혹시 더 궁금한 점 있으시면 편히 문의 주세요!
- 0
- 2
- 54
질문&답변
안녕하세요! 테스트 질문입니다
qheogus55님, 안녕하세요!제가 작업했던 부분에서는 v2 api에서만 이벤트 전송하도록 처리했었는데, 혹시 v2로 바꿔서 해보시겠어요?아니면, 개인적으로 v1 api에서도 이벤트 전송 코드를 넣으셨던걸까요?!comment api에서 댓글 생성과 전송에 대해서 잘 처리되고 있는지도 확인 한번 해보시면 좋을 것 같네요!
- 0
- 2
- 37
질문&답변
안녕하세요! 강의 잘 듣고 있습니다!!
보키님, 안녕하세요!강의 수강하시느라 고생 많으시고, 좋은 말씀 주셔서 감사합니다! 테스트코드@Test를 만드시고, 따로 밑에 메서드를 추가하시는건 반복호출을 위해서인게 맞을까요!? 그렇다면 JUnit의 @ParameterizedTest, @CsvSource 이거를 활용하면 좋을것같은데 사용 안하신 이유나 실무에서 요거를 잘 안쓰시는지 궁금합니다!단순히 제 주변(저 포함)에서 잘 쓰지 않아서 낯설었을 뿐이고, 익숙한 방식의 제 경험에 기인했다고 봐주시면 될 것 같습니다.저도 방금 해당 기능들 다시 찾아봤는데 실무에서도 활용해보면 좋을 것 같네요!이 부분은 오히려 제가 배워갑니다. 좋은 내용 공유 감사합니다! 저도 WebClient나 RestClient로 api테스트를 하긴 하는데요! 그 API Docs 만들어주는 RestDocs는 테스트객체: RestTemplate, WebTestClient, RestClient 와 테스트방법(WebMvcTest, SpringBootTest)과 상관없이 플러그인만 추가하면 api docs가 만들어지는걸까요? 지식공유자님은 현업에서 Swagger, RestDocs중에 어떤걸 쓰시는지 궁금합니다현재 전 주로 Swagger를 활용하고 있으나 RestDocs도 현업에서 많이 사용됩니다.api docs에 대해서는 제가 직접 만들어본건 아닌데,테스트에 사용한 RestClient의 경우, 실행된 서버 애플리케이션 호출을 위해 임의로 선언해본거라, 일반적인 테스트 또는 문서 도구와 자동으로 통합되진 않을 것으로 예상되네요. (저도 직접 테스트해본건 아니고 찾아보니 테스트코드에서 문서 생성을 위해 RestDocs 연동에 대해 코드 작성 과정이 필요한 것 같네요) TestContainer 등의 방법은 사용하지 않으시는지!?이것도 필요에 따라 적절히 사용할 수 있습니다!강의에서는 테스트를 엄청 꼼꼼하게 다 만든 것도 아니라, 굳이 필요성을 못느껴서 활용하지 않았네요.현재 강의에서도, 로직 점검하는 단위테스트야 문제 없다지만, API로 직접 호출 테스트(RestClient로 요청)해보는 것은 실제 DB(로컬 개발환경이긴 하지만)에 데이터가 다 들어가고 있는 상황이라 미비한 부분이긴 합니다.강의에서는 테스트 데이터 준비 과정이 장시간 소요되어 사용하지 않았는데(그냥 로컬 MySQL(Redis/Kafka) 컨테이너를 테스트 전용으로 사용), 이런 곳에 활용해보면 적절할 수 있습니다! JPA & SpringController에서 @PageableDefault()로 받는 방법은 주로 사용되지 않는 것일까요..?이러한 부분은,개인적인 취향 차이일수도 있고, 모르고 있었을 수도 있고, 어떤걸 쓰든 유의미하게 큰 차이가 없다면 익숙한 방식을 택할 수도 있는데요!저는 해당 애노테이션 모르고 있기도 했고 그냥 파라미터 받는게 익숙하고 편해서 사용했습니다!뭐가 더 낫다라는 정답은 없어서 필요에 따라 충분히 사용하셔도 됩니다! DTO로 반환해서 Response를 내려주시긴 하시지만 ResponseBody나 ResponseEntity 등으로 감싸서 내려주시지는 않으시는데, 이유가 있으신지요!?이 부분도 선호도 차이일 수도 있고, 굳이 사용할 이유가 없어서 그럴 수도 있는데요.필요한 상황(응답 헤더나 상태 코드를 커스텀 한다든지 등)이면 적용해도 문제 없습니다!강의에서는 마땅히 그러한 동작이 없어서 굳이 적용 안한 것이라 봐주시면 됩니다! 강의에서처럼 커버링인덱스와 무한스크롤을 구현하려면 nativeQuery를 사용하지 않고 JPA와Hibernate로 해결하는 방법(JQPL/QueryDsl/Creteria)이나 Raw Library(Spring Data JDBC/JdbcTemplate)으로 해결하는 방법은 없는걸까요?강의에서 JPA를 사용하긴 했지만, 최대한 JPA에 의존하지 않고 개발을 진행하고자 했습니다.(개인적인 취향이라 조심스럽지만 JPA를 딱히 선호하진 않는 이유도 있습니다)그래서 데이터베이스에서 동일하게 쿼리를 직접 실행해볼 수도 있고, 실제 쿼리를 바로 확인할 수 있는 nativeQuery로 작성했습니다.다른 방법에 대해서는,무한스크롤 같은 경우 단순히 정렬 + 필터링 조건만 추가하면 되는거라 다른 방법으로도 모두 해결 가능할 것 같고,커버링 인덱스 경우에도 서브쿼리를 지원하지 않으면 articleId만 먼저 뽑아낸 뒤에, 이후에 articleId로 쿼리를 한번 더 보내서 데이터를 가져오면 되므로(즉, articleId와 데이터 가져오는 쿼리 각각 나눠서, 애플리케이션에서 쿼리를 2번 요청하는 형태), 모두 해결 가능할 것 같습니다!이건 직접 코드를 만들어본건 아니지만, 필요하다면 만들어보셔도 좋을 것 같네요! 답변에 뭐든 정답이 없다는 뉘앙스가 많아서 당혹스러우실 수 있을 것 같은데요,사실 어떠한 기술(또는 방법론)이든 검토해보고 문제가 없다면, 상황에 적절하다면, 그리고 팀에 납득만 된다면, 뭐든 적용해볼 수 있습니다!언급주신 내용들은, "실무에서는 사용하지 않는다"라기보단, 필요하다면 사용해도 된다?정도로 인지해도 충분할 것 같네요!뭐든 딱히 문제될 내용들은 아닌 것 같습니다.그냥 제가 강의에서 마땅히 적용할 필요가 없어서/익숙치 않아서/몰라서 사용 안했을 뿐이라고 봐주시면 됩니다! Next제가 아직 모든 강의를 다 본것은 아니지만.. 챕터를 보면 각각 다른 모듈끼리 Join을 하는 경우는 없는 것 같아보입니다..! 혹시 나중에 또 강의를 내신다면 샤드키와 DB 이중화의 fail over에 대한 실전강의, 다른 DB 스키마, 모듈을 사용하는 상황에 하나의 View에 다건의 Join이 들어갈 경우 설계 방법..이나 DDD, 클린 아키텍처에 대해서도 다룰 에정이 있으신지 궁금합니다!"하나의 View에 다건의 Join이 들어갈 경우 설계 방법"에 대해서는 게시글 조회 최적화 강의에서 살펴봅니다!다음 강의로는 여러 주제들 사이에서 계속 고민 중인데, 입문 강의는 잘 만들어진게 너무 많아서 어려운 강의로 변별력을 가지고자 하니 난이도가 만만치 않아서 계속 고민중이긴 하네요..!일단 구상중인건 아마 대규모 시스템 시리즈로 SNS 피드(인스타그램/트위터같은) 만들기를 해볼 것 같습니다. (이것도 확정은 아니고, 미정입니다. 제대로 만들고자 하면 너무 어렵고 복잡해지네요 😅 )외에는 캐시전략, 스케줄러, 대기열 등.. 고민 중이네요.물론 DDD, 클린 아키텍처도 만들고자 하는 강의 주제 후보군에 있습니다.애초에 본 강의에서도 해당 방법론 적용하여 개발해볼까 싶기도 했는데,"대규모"라는 초점을 벗어나는 주제에 대해서 설명할 내용이 많아질 것 같더라고요.수강생 분들도 "대규모"를 배우러왔는데 다른 방법론에 초점이 맞춰져있는게 당황스러우실 수 있을 것 같았고, 괜히 익숙치 않은 개념에 고생할 것 같더라고요.사실 이러한 방법론들은 저도 복잡한 시스템을 지속적으로 개발 및 개선하면서 뒤늦게 와닿던 부분이 있어서..한시적으로 진행하며 간단할 수 밖에 없는 강의 수준의 요구사항에 적용하면서 납득 가능한 수준으로 설명하는게 정말 어려울 것 같더라고요..!그래서 본 강의에서 "도메인"이란 용어 조차도 일부러 사용하질 않았던 것이네요.이 부분은 과연 제가 잘 만들어낼 수 있을지 계속 고민해보겠습니다!근데 요즘 본업도 바쁘고 강의 준비도 쉽지 않아서, 다음 강의가 언제 오픈될 수 있을지는 모르겠네요.. 😅 미취업자(취준생)에 비해서 중-고급 경력직은 그렇게 많지 않아서 강의 수요가 적기도 하고 각자 나름의 위치에서 배운 self best practice가 있어서 그들만의 생각이나 태클이 들어올 수 있을 것 같은데..이런저런 이유에도 불구하고 이런 귀한 중고급 강의를 내주셔서 정말 감사합니다!저야말로 귀한 시간과 비용 내주시며 강의 수강해주셔서 감사합니다!! 😄취준생 시절 항상 초급 강의만 있고 중고급 강의가 없던게 아쉬웠던 것 같아요.초급 강의나 책에서는 매번 똑같은 게시판 CRUD만 개발하고,중급 강의도 실무 개발보단 대부분 프레임워크 이론에만 치우쳐져있고,그렇다고 마땅히 실무 관점에서의 고난이도의 강의는 잘 없고(개인적으로 쿼리를 꼭 먼저 살펴보는데, 대부분 인덱스 조차 제대로 다루지 않는..)막상 어려운 책은 특정 주제에 대해서만 깊게 들어가기 때문에 갑자기 뜬금없이 어려워지고,대기업에서 대규모는 요구한다지만 그래서 그게 뭐고 어떻게 다루는지?CS랑 어떻게 접목시켜내는 건지?이런 것들이 정말 가려운 부분이었고,이러한 강의가 있었으면 좋았을 것 같아서 만들어보았습니다.물론 제 강의도 만능은 아니고 부족한 부분도 많지만요..! (요즘에는 좋은 강의가 정말 많아졌더라고요)"그들만의 생각이나 태클이 들어올 수 있을 것 같은데"이 부분은 사실 저 보단 비교도 안될 정도로 잘하시는 분들이 하도 많아서 지금도 무섭긴 합니다.혹여나 잘못된게 있다면 괜한 비판이 들어오진 않을지 걱정되는 부분도 있습니다.근데 어차피 정답은 없는 것이고, 건전하게 피드백 받으면 오히려 저도 배울 수 있는 것이라고 좋게 생각하려고 합니다..! ㅋㅋㅋ 질문 남겨주신 것 보니 공부도 많이 하시고, 직접 고민도 많이 하시는 분이라는게 느껴지네요.혹시 궁금한 점 더 있으시면 편히 문의주시고, 앞으로도 편하게 질문 주세요!남은 강의도 화이팅입니다!
- 2
- 1
- 62
질문&답변
실무에서 Primary Key 생성 전략 질문 있습니다.
리나님, 안녕하세요! 일단, AUTO_INCREMENT PK와 Snowflake 크기 차이에 대한 오해가 있는듯 하여, 이 부분 먼저 언급 드려보겠습니다.Snowflake는 64비트를 사용합니다.AUTO_INCREMENT PK는 INT 타입으로 정의하면 32비트로 사용할 수도 있지만,대규모 시스템에서는 데이터가 많다면 INT 타입의 식별자는 금세 고갈될 수 있기 때문에 처음부터 64비트를 고려하는 경우가 많습니다.따라서, 둘다 64비트로 PK를 정의한다면, 언급해주신 문제에 대해서는 읽기 성능 문제만 남으므로 1번으로 처리하는게 유리합니다. 아무튼 질문 자체는, 2번 상황에서의 PK를 INT 타입(32비트)로 정의하는 등 PK의 크기 차이가 나는 상황이라고 가정해보겠습니다.읽기/쓰기 트래픽 차이로 인한 트레이드오프가 생길 것 같은데요.읽기 트래픽이 많다면 당연히 데이터(클러스터드 인덱스)에 즉시 접근하는게 더 빠르기 때문에 1번이 더 나을 수 있습니다.그런데 또, 데이터베이스 앞단에 캐시를 붙이는 시스템 구성이라면, 최종 클라이언트 입장에서 사실 세컨더리 인덱스 한번 더 타는 것 정도는 2번과 성능 면에서 크게 유의미하지 않을 수 있습니다.특히 클라이언트가 사람이라면 이 차이가 느껴지지도 않을 것이고요. 그런데 반대로 2번이 쓰기 트래픽이 빠른 것도 아닙니다.인덱스로 인해 쓰기 시점에 부가적인 비용도 생기기도 하고,AUTO_INCREMENT를 사용하면 순차적인 채번을 위해 동시 쓰기 요청이 들어왔을때 락 경합이 생길 수 있습니다.이러한 락을 방지하기 위한 데이터베이스 내부 설정들이 있긴 하지만(반드시 1씩 순차 증가하진 않도록 하는 등.. 저도 사용해보진 않았습니다),이를 위해 데이터베이스 설정을 변경 및 관리해줘야하는 번거로움은 생기고요.(강의에서는 분산 환경에서의 PK 전략을 설명하는 것에 조금 더 초점을 두었기 때문에 AUTO_INCREMENT 성능에 대해서는 따로 다루진 않았는데, 궁금하시면 한번 찾아보셔도 좋을 것 같습니다!)하지만 이런걸 문제로 볼 정도로 쓰기 트래픽이 많지 않다면, 마음 편하게 AUTO_INCREMENT PK 생성하는게 간단하긴 합니다.저장 용량에 대해서는, 인덱스가 많이 생성될 수 있으면 당연히 PK가 작은게 유리하겠지만,테이블이 작게 유지되거나 강의 뒷편에서 배울 캐시 또는 CQRS를 적용한다면, 어차피 테이블 하나에 인덱스가 많이 생성될 일은 없을 수 있습니다.저장소 자체 비용은 크게 비싸지 않기 때문에, 인덱스가 조금 더 크다고 해서 문제될 요소는 딱히 없을 수 있고요. 결론은, 뭐가 더 낫다라는 정답은 없고,실제 들어오는 데이터와 트래픽, 서비스 특성, 시스템 구성을 모두 종합적으로 고려해서 테스트를 진행해야 구체적인 차이를 얻을 수 있을 것 같고, 아무튼 이러한 부분에 대해 인지하고 필요할 때 적용할 수 있으면 충분하다고 봅니다. 그런데 대부분의 경우에서는 정말로 반드시 이걸로 해야된다라는 유의미한 차이는 없을 것 같고요.그래서 실무 관점에서 조금 더 현실적으로 말씀드리면,시스템 구성에서 크게 유의미한 차이나 문제가 없을 것 같다면, 기존 팀에서 이미 선택했던 전략 또는 팀원들이 선호하는 방향을 따라가는 경우가 많네요.또, 강의에서는 MySQL 단일 컨테이너로 진행하긴 했지만, 실제로 사용하는 데이터베이스의 정책에 따라서 내부적으로 PK를 특정 전략으로 강제해버리는 경우도 있고요. 이 경우에는 선택권이 없을 수도 있습니다. 저는 직접 강의로 만들면서 시스템 구성하는 입장이어서 이론 상 또는 유지보수 측면에서 유리한 점이 많은 1번 전략을 취했다고 보시면 되고, 실무에서도 특별한 이유가 없고 결정권이 온전히 저에게 있다면, AUTO_INCREMENT 사용하는 것보단 1번 전략을 취할 것 같네요.그런데 또 뭘 쓰든 아무 상관 없는 트래픽 작고 가벼운 테이블이라면 AUTO_INCREMENT를 쓰기도 할 것 같습니다. 실무에 들어가면, 정형화된 정답이 있는 경우는 많이 없네요.그래서 강의에서도 범용적인 내용으로 설명하려다보니 구체적인 수치에 대해서는 언급하지 않게 된 것도 있고요.(상황이 조금만 달라져도 어차피 무의미한 내용이 될 수 있으므로)각각 장단점 인지해서 상황에 맞게 적절한 해답을 찾아가게 되는 것 같습니다! 혹시 더 궁금한 점 있으시면 편히 문의 주세요! 약간 다른 이야기인데 리나님의 이전 질문에서도 느꼈지만,강의 내용을 기계적으로 그대로 따라오는게 아닌, 스스로 계속 고민하면서 더 나은 방안을 찾아보려고 하시는 것 아주 좋습니다!! 👍
- 0
- 2
- 73
질문&답변
멀티 모듈 방식 질문입니다.
qheogus55님, 안녕하세요!아래 AI가 잘 답해주었는데 추가 답변 드립니다!말씀하신대로 프론트에서 두 개의 api를 각각 호출할 수도 있고,서버에서 두 개의 api를 조합하는 엔드포인트를 만들어서 프론트는 해당 api만 호출할 수도 있습니다.또는, 게시글 서비스의 게시글 조회 api 내에서 조회수를 처리하도록 구성하면, 게시글 조회 api만 호출할 수도 있습니다. 현재 구성처럼 게시글 서비스와 게시글 조회수 서비스가 분리되어 있는 상황이 의아하실 수 있는데요, 실무에서 반드시 분리하는 것은 아니고 상황에 따라 달라질 수 있습니다. 예시로, 게시글 조회수 처리가 게시판 서비스 팀과 별도 팀으로 구성된 통계 팀의 책임이라고 볼 수도 있는데요.이 경우 각 팀이 분리하여 관리하는게 유리할 수도 있습니다.같은 팀 내의 책임이더라도, 개별 서비스가 처리해야하는 사항이 복잡하다면 유지보수 또는 개발 편의를 위해 분리할 수도 있습니다. 그래서,- 게시글 서비스 내에서 조회수 처리- 게시글 서비스와 조회수 서비스를 분리하여 처리(현재 구성)- 게시글 서비스에서 조회 이벤트를 발행 후, 조회수 서비스에서 처리등 다양한 구성이 가능하다고 봐주시면 되고, 강의에 나온 구성은 하나의 예시일 수 있습니다. 혹시 더 궁금한 점 있으시면 편히 문의 주세요!
- 0
- 2
- 53
질문&답변
강의자료 파워포인트 기준 361~362 페이지를 보면
아이고, 맞습니다. 해당 부분 강의 자료에는 부등호가 반대로 되어 있었군요..이 부분 빠른 시일 내로 수정해두도록 하겠습니다.강의 수강에 불편을 드려 죄송합니다.일단 ">" 방향으로 인지하고 진행해주시면 될 것 같습니다.날카로운 제보 감사합니다! 👍 👍
- 1
- 1
- 37
질문&답변
Selet All 쿼리에서 반복적으로 Clustered Index 탐색 하는지 궁금 합니다.
리나님, 안녕하세요! MySQL의 스토리지 엔진(InnoDB)의 설계 방향에 대해서는 저도 깊게 들여다본 적이 없다보니, 공식적으로 답변드리기엔 어려운 부분이네요..! 세컨더리 인덱스만으로 충분히 조회 후, 마지막 필요한 상황에만 클러스터드 인덱스를 조회하면 되지 않을지 의문을 가지신 것 같은데요,그렇게 했을 때의 제한 사항을 짐작가는 부분으로 말씀드려보겠습니다. 현재 쿼리는 WHERE 조건과 정렬에 인덱스 지정한 컬럼만 포함되어 있어서 의문이 생길 수 있지만,예시로 WHERE절에 boardId 외에도 다른 조건(인덱스와 무관한)이 들어가있는 경우를 상상해 볼 수 있을 것 같습니다.이 경우에는 반드시 데이터(클러스터드 인덱스)에 접근하여 원본 데이터를 확인해야 필터링을 수행할 수 있습니다.클러스터드 인덱스를 통해 데이터의 실제 검증이 필요한 것입니다.boardId만을 검사한다고 하더라도, 동시 요청 시에 데이터(클러스터드 인덱스)가 업데이트 되었지만, 세컨더리 인덱스에는 데이터가 아직 업데이트 되어있지 않은 상황이 만들어질 수도 있을 것 같고요. (이 경우에도 실제 데이터에 접근하여 검증은 필요하겠고요.) 쿼리 옵티마이저가 이러한 특수 상황을 모두 구분하여 최적화해주진 못하는 상황인가 봅니다.설계의 일관성을 맞추기 위한 부분도 있었을 것이고, 예상치 못한 에러까지 모두 잡아내기엔 풀어내기 어려운 문제였을지도 모르겠습니다.아마 이러한 최적화를 고려한다면 내부적으로 더욱 풀어내기 어려운 문제와 충돌날 수도 있었을지 싶네요. 저도 데이터베이스에 대해 엄청난 전문가는 아니다보니, 내부 설계 철학까지는 명쾌하게 만족스러운 답변을 드리기가 쉽지 않네요..!추후 스토리지 엔진이 더욱 발전하면 이러한 문제도 알아서 해결해주지 않을까 싶긴 합니다.당장은 성능 최적화보단 안전성에 초점을 맞춘 설계라고 생각되네요.혹시 더 궁금한 점 있으시면 아는 선에서는 답변 드려보겠습니다!
- 0
- 2
- 91
질문&답변
ArticleRepository의 네이티브 쿼리부분 질문드립니다...
janggoni님, 안녕하세요!테이블 생성 여부, DB 연결 여부, 테이블 컬럼명 또는 쿼리 오타 등이 있을지 점검해보시면 좋을 것 같습니다!코드를 봤을 때에는 문제될 만한 지점은 안보이는데, 어떠한 에러 로그가 남았는지 구체적으로 알려주실 수 있을까요?!
- 0
- 3
- 83
질문&답변
게시글 CRUD API 구현 10:39에서 에러 발생
재근님, 안녕하세요!(사진) ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root'; FLUSH PRIVILEGES;mysql 컨테이너 접속하여 위처럼 명령어도 실행해보시겠어요? 오 AI 인턴 이런 것도 있군요..!위 명령어 수행하기 전에 일단 application.yml locahost 오타가 있어보여서, localhost로 먼저 수정 및 확인해보시면 좋을 것 같습니다!
- 0
- 3
- 110
질문&답변
강의 자료 질문입니다.
성관님, 안녕하세요!학습에 불편을 드려 죄송합니다.윈도우 환경 압축 파일을 고려하지 못했었네요..지금 강의자료 다시 업로드 해두었는데 확인 해보시겠어요?혹 안되시면 다시 말씀 부탁드립니다!소스코드는 강의자료 압축 파일에 포함되어 있습니다.감사합니다.
- 0
- 1
- 187