묻고 답해요
167만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
HotArticleApiTest 오류
package kuke.board.hotarticle.api; import kuke.board.hotarticle.service.response.HotArticleResponse; import org.junit.jupiter.api.Test; import org.springframework.core.ParameterizedTypeReference; import org.springframework.web.client.RestClient; import java.util.List; public class HotArticleApiTest { RestClient restClient = RestClient.create("http://localhost:9004"); @Test void readAllTest() { List<HotArticleResponse> responses = restClient.get() .uri("/v1/hot-articles/articles/date/{dateStr}", "20250225") .retrieve() .body(new ParameterizedTypeReference<List<HotArticleResponse>>() { }); for (HotArticleResponse response : responses) { System.out.println("response = " + response); } } }섹션 6 인기글 Producer&Consumer 테스트 테스트 코드 실행 오류가 발생합니다.2025-02-25T14:24:03.178+09:00 INFO 38230 --- [kuke-board-hot-article-service] [nio-9004-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2025-02-25T14:24:03.178+09:00 INFO 38230 --- [kuke-board-hot-article-service] [nio-9004-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms 2025-02-25T14:24:03.191+09:00 WARN 38230 --- [kuke-board-hot-article-service] [nio-9004-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingPathVariableException: Required URI template variable 'dataStr' for method parameter type String is not present]org.springframework.web.client.HttpServerErrorException$InternalServerError: 500 Internal Server Error: "{"timestamp":"2025-02-25T05:24:03.195+00:00","status":500,"error":"Internal Server Error","path":"/v1/hot-articles/articles/date/20250225"}" 다른 질문글에서 언급한 500에러 해결책을 참고해봤지만 소용이 없네요. 코드를 점검해봐도 잘못 작성한게 없어보입니다. 기초 선수지식이 없는 상태에서 클론코딩을 하다보니 어디를 어떻게 더 점검해야할지 모르겠는데 제시 해주신다면 찾아서 해결해보려고 합니다. 어떻게 해야할까요?
-
미해결15일간의 빅데이터 파일럿 프로젝트
HDFS 명령어를 치는데 오류가 납니다
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
테스트 코드 작성 관련해서 질문드립니다!
강사님 안녕하세요.강의의 테스트 코드도 보고 실무서 테스트 코드 작성시 문득 궁금한 사항이 생겼습니다.테스트 코드 작성시 단위, 통합, E2E 등 종류도 많고 일정 등 고려해야 될 사항이 많은데 강사님의 테스트 코드 작성 기준이 궁금합니다. 제가 정한 기준은 아래와 같습니다.단위 테스트(도메인 폴더 하위 순수 객체)는 반드시 작성일정 일정이 급할때 단위 테스트일정이 여유로울때단위 테스트API 테스트 or 통합 테스트서비스의 핵심 로직단위 테스트API 테스트 or 통합 테스트일정이 급해도 최대한 작성 그리고 다음과 같은 고민도 있습니다.Mockito를 이용한 테스트가 충분히 검증이 될까? 근데 될것 같기도..? XxxFacade 혹은 XxxService에 Mockito를 이용한 테스트의 정확도에 의문을 품었습니다. 그래서 @SpringBootTest를 이용한 통합 테스트를 작성하였는데 테스트를 위한 데이터 세팅이 너무 귀찮더라구요.(하하하) 그래서 도메인 모델링을 잘하고 단위 테스트를 꼼꼼하게 작성한다고 쳤을때 Mockiot의 verify를 이용해 의도한 메서드가 호출이 되었는지만 테스트만 해도 괜찮지 않을까? 란 생각이 들었습니다. 회사일도 바쁘실텐데 다음 강의 준비도 하시고 질의응답도 해주셔서 언제나 감사드립니다.
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
이거 맞아요?
이런식으로 서비스 밑의 폴더 이어 붙이기 하고 article 따로 service 따로 서버 실행할수 있게 되면 그게 msa 기본 구조 잡아가는 과정인가요?지금 막 우당탕탕 이렇게 저렇게 막 코드 붙여가면서 되는거 같기는 한데 뭐 하고 있는지 헷갈리고 어지러워요
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
Spring Boot 프로젝트 세팅 2 강의 듣는데 따라 치기 너무 어렵
Spring Boot 프로젝트 세팅 2 강의 듣는데 따라 치기 너무 어렵
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
PK 전략에 관련해서 질문 드립니다!
안녕하세요. 만 1년된 작은 중소기업에서 일하고 있는 개발자입니다. 강의 잘 듣고 있습니다! 현재 회사에서는 오라클 데이터베이스를 사용하고 있고 최근 스프링부트와 JPA를 사용해서 프로젝트를 시작했고, 낡은 레거시 사업을 영위하는 업체라서 이게 회사의 첫 스프링부트 프로젝트입니다! 나름 새로운 기술스택을 제안했기에 가지는 부담감이 심한데요. 최근에 만든 거의 대부분의 프로젝트들은 단일 DB를 사용하고 있기 때문에 별다른 고민 없이 AutoIncrement를 선택했습니다. 오라클에서도 최신 버전에서는 잘 지원해주고 있고 DB 버전은 높았기 때문에 이에 익숙해서 JPA에서 지원하는 IDENTITY 전략을 사용해서 시스템을 만들었는데요. 현재 ID를 노출해야하는 상황이 생길 경우 이를 그대로 노출하고 있습니다. 다른 PK 전략을 사용하지 않고 보완할 수 있는 방법이 있을까요? 현재 떠오르는것은 외부로 노출할 때 컨트롤러에서 이를 해싱하거나 난수화를 하는 방법을 생각하고 있습니다. 감사합니다!
-
해결됨카프카 완벽 가이드 - 커넥트(Connect) 편
자문자답: JDBC Sink Connector가 PostgreSQL의 Schema를 바라보지 않습니다.
2025-02-24 추가) 해당 문제는 psql session 로그인 시도에서 database만 잘 접근하면 문제 없습니다. 강의대로 따라가시면 됩니다.psql -h localhost -U connect_dev -d ${database_name}p.s.) MySQL과 달리, PostgreSQL은 생각한 대로 JDBC Sink Config에서 connection.url의 첫 번째 파라미터를 데이터베이스 그대로 읽고, table.name.format 옵션에서 구분자.을 가지고 스키마와 테이블을 제대로 구분하네요. 제가 인지하지 못한 부분이 있다면 다음 사람을 위해서 댓글 남겨주시면 감사하겠습니다.안녕하세요 선생님. 이전에 MySQL Sink Config 파일에서 table.name.format 설정하는데 있어서, 데이터베이스 스키마를 바라보지 현상이 발생하여 질문 게시판에 자문자답을 남긴 적이 있습니다. 해당 PostgreSQL도 마찬가지로 JDBC Sink Connector가 해당 search_path를 제대로 읽어오지 못하고 에러가 발생하는 것을 확인했습니다. (모든 프로그램 버전은 강의와 동일합니다.) PostgreSQL도 실습하며 명확해졌네요. DBMS마다 관련 데이터베이스를 자동으로 연결해주는 기능(auto-creation)이 제대로 동작하지 않는 JDBC Sink Connector의 내부적인 문제 같습니다. 또한, 아직 kafka-connect-jdbc/issues/246 이슈가 close되지 않은 것으로 확인했습니다. 다른 해결 방안이 있어서 몇 년이 지나도 내부적으로 수정해주지 않는 것 같습니다...Error log 기존 postgres_jdbc_ops_sink_customers_avro_01.json{ "name": "postgres_jdbc_ops_sink_customers_avro_01", "config": { "connector.class": "io.confluent.connect.jdbc.JdbcSinkConnector", "tasks.max": "1", "topics": "mysqlavro-ops-customers", "connection.url": "jdbc:postgresql://localhost:5432/postgres", "connection.user": "connect_dev", "connection.password": "1234", "table.name.format": "ops_sink.customers_sink"혹여 같은 현상이 발생하신다면, 마찬가지로 connection url에 직접적인 schema 설정으로 문제를 해결할 수 있습니다. Solvedjdbc:postgresql://<host>:<port5432>/<database>?options=-c%20search_path=myschema,anotherschema
-
미해결[아파치 카프카 애플리케이션 프로그래밍] 개념부터 컨슈머, 프로듀서, 커넥트, 스트림즈까지!
shutdownThread 에 대한 문의 입니다.
7강 > 컨슈머의 안전한 종료에서컨슈머 애플리케이션의 안전한 종료를 위해서 shutdownThread 을 활용한다고 하셨는데요..개념을 설명하실때에는 컨슈머 그룹내 특정 컨슈머에 대한 문제 발생시 wakeup을 통하여 컨슈머를 종료시키고 리밸런싱 하여 특정 파티션이 컨슈머에 다시 할당되는 개념으로 이해를 했는데실습하는걸 보여주실때는 컨슈머그룹내 특정 컨슈머의 대한 종료가 아닌 전체 어플리케이션에 대한 종료로 보여지는데, 제가 이해한게 맞을까요?컨슈머 그룹내 n개의 컨슈머에 대한 동작 및 특정 컨슈머의 대한 문제발생시 이를 리밸런싱 하는 예제는 없나요?
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
Transactional Outbox 테스트 시간대 5:25
현재 카프카를 종료하고 API로 2개의 데이터를 넣고 다시 카프카를 켰을 때, delete 가 동작하지 않습니다.이전에 카프카를 켜놓은 상태에서 API 2개의 데이터 생성하는 경우는 바로 delete쿼리가 날라갔는데, 지금의 경우 어떤 부분에서 동작하지 않는지 잘 모르겠습니다. 따라서 압축 파일의 outbox-message-relay에 적으신 코드랑도 비교해봤는데, 동일하게 나오고 있습니다.일단 카프카를 종료하면 다음과 같은 에러가 나오는데, 강사님과 동일한 에러인지 궁금합니다. bernate: insert into article (board_id,content,created_at,modified_at,title,writer_id,article_id) values (?,?,?,?,?,?,?) Hibernate: update board_article_count set article_count = article_count + 1 where board_id = ? Hibernate: select bac1_0.board_id,bac1_0.article_count from board_article_count bac1_0 where bac1_0.board_id=? 2025-02-22T14:21:16.536+09:00 INFO 32925 --- [kuke-board-article-service] [nio-9000-exec-5] k.b.c.outboxmessagerelay.MessageRelay : [MessageRelay.createOutbox] outboxEvent=OutboxEvent(outbox=Outbox(outboxId=151558979476971520, eventType=ARTICLE_CREATED, payload={"eventId":151558979474350080,"type":"ARTICLE_CREATED","payload":{"articleId":151558979451625472,"title":"hi","content":"my content","boardId":1,"writerId":1,"createdAt":[2025,2,22,14,21,16,530575000],"modifiedAt":[2025,2,22,14,21,16,530575000],"boardArticleCount":9}}, shardKey=4, createdAt=2025-02-22T14:21:16.536478)) Hibernate: select o1_0.outbox_id,o1_0.created_at,o1_0.event_type,o1_0.payload,o1_0.shard_key from outbox o1_0 where o1_0.outbox_id=? Hibernate: insert into outbox (created_at,event_type,payload,shard_key,outbox_id) values (?,?,?,?,?) 2025-02-22T14:21:16.694+09:00 INFO 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Node 1 disconnected. 2025-02-22T14:21:16.694+09:00 WARN 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Connection to node 1 (localhost/127.0.0.1:9092) could not be established. Node may not be available. 2025-02-22T14:21:17.547+09:00 ERROR 32925 --- [kuke-board-article-service] [ mr-pub-event-3] k.b.c.outboxmessagerelay.MessageRelay : [MessageRelay.publishEvent] outboxEvent=Outbox(outboxId=151558979476971520, eventType=ARTICLE_CREATED, payload={"eventId":151558979474350080,"type":"ARTICLE_CREATED","payload":{"articleId":151558979451625472,"title":"hi","content":"my content","boardId":1,"writerId":1,"createdAt":[2025,2,22,14,21,16,530575000],"modifiedAt":[2025,2,22,14,21,16,530575000],"boardArticleCount":9}}, shardKey=4, createdAt=2025-02-22T14:21:16.536478) java.util.concurrent.TimeoutException: null at java.base/java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1960) ~[na:na] at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2095) ~[na:na] at kuke.board.common.outboxmessagerelay.MessageRelay.publishEvent(MessageRelay.java:46) ~[main/:na] at kuke.board.common.outboxmessagerelay.MessageRelay.publishEvent(MessageRelay.java:37) ~[main/:na] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:113) ~[spring-aop-6.1.11.jar:6.1.11] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na] 2025-02-22T14:21:17.695+09:00 INFO 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Node 1 disconnected. 2025-02-22T14:21:17.695+09:00 WARN 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Connection to node 1 (localhost/127.0.0.1:9092) could not be established. Node may not be available. 2025-02-22T14:21:18.697+09:00 INFO 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Node 1 disconnected. 2025-02-22T14:21:18.697+09:00 WARN 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Connection to node 1 (localhost/127.0.0.1:9092) could not be established. Node may not be available. Hibernate: select a1_0.article_id,a1_0.board_id,a1_0.content,a1_0.created_at,a1_0.modified_at,a1_0.title,a1_0.writer_id from article a1_0 where a1_0.article_id=? Hibernate: insert into article (board_id,content,created_at,modified_at,title,writer_id,article_id) values (?,?,?,?,?,?,?) Hibernate: update board_article_count set article_count = article_count + 1 where board_id = ? Hibernate: select bac1_0.board_id,bac1_0.article_count from board_article_count bac1_0 where bac1_0.board_id=? 2025-02-22T14:21:19.531+09:00 INFO 32925 --- [kuke-board-article-service] [nio-9000-exec-7] k.b.c.outboxmessagerelay.MessageRelay : [MessageRelay.createOutbox] outboxEvent=OutboxEvent(outbox=Outbox(outboxId=151558992038912000, eventType=ARTICLE_CREATED, payload={"eventId":151558992036290560,"type":"ARTICLE_CREATED","payload":{"articleId":151558992013565952,"title":"hi","content":"my content","boardId":1,"writerId":1,"createdAt":[2025,2,22,14,21,19,525215000],"modifiedAt":[2025,2,22,14,21,19,525215000],"boardArticleCount":10}}, shardKey=4, createdAt=2025-02-22T14:21:19.531129)) Hibernate: select o1_0.outbox_id,o1_0.created_at,o1_0.event_type,o1_0.payload,o1_0.shard_key from outbox o1_0 where o1_0.outbox_id=? Hibernate: insert into outbox (created_at,event_type,payload,shard_key,outbox_id) values (?,?,?,?,?) 2025-02-22T14:21:19.699+09:00 INFO 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Node 1 disconnected. 2025-02-22T14:21:19.699+09:00 WARN 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Connection to node 1 (localhost/127.0.0.1:9092) could not be established. Node may not be available. 2025-02-22T14:21:20.544+09:00 ERROR 32925 --- [kuke-board-article-service] [ mr-pub-event-4] k.b.c.outboxmessagerelay.MessageRelay : [MessageRelay.publishEvent] outboxEvent=Outbox(outboxId=151558992038912000, eventType=ARTICLE_CREATED, payload={"eventId":151558992036290560,"type":"ARTICLE_CREATED","payload":{"articleId":151558992013565952,"title":"hi","content":"my content","boardId":1,"writerId":1,"createdAt":[2025,2,22,14,21,19,525215000],"modifiedAt":[2025,2,22,14,21,19,525215000],"boardArticleCount":10}}, shardKey=4, createdAt=2025-02-22T14:21:19.531129) java.util.concurrent.TimeoutException: null at java.base/java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1960) ~[na:na] at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2095) ~[na:na] at kuke.board.common.outboxmessagerelay.MessageRelay.publishEvent(MessageRelay.java:46) ~[main/:na] at kuke.board.common.outboxmessagerelay.MessageRelay.publishEvent(MessageRelay.java:37) ~[main/:na] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:113) ~[spring-aop-6.1.11.jar:6.1.11] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na] 카프카 종료후 다시 연결해도 폴링은 되는ㄴ데 select만 하고 있고 기존에 outbox에 남아있는 2개의 데이터는 delete처리가 되지 않고 있습니다.
-
해결됨고성능 실시간 분산 시스템 RabbitMQ + Kafka + Redis 실전 프로젝트
노션 사용권한 이슈 문의 드립니다.
안녕하세요! 우선 좋은 강의 만들어 주셔서 너무너무 감사드립니다! [환경 구축 가이드라인 및 ppt 자료] 를 확인하려고 하는데링크 클릭 시 페이지 사용 권한 없음으로 나옵니다 흑흑.. ㅠ
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
강의자료
깃허브에서 강의자료를 다운받았는데암호가 걸려있어서 굿노트에서 열리지도 않고 파일에서 필기도 안되고 인쇄도 안됩니다.암호 안걸려있는 강의자료를 받을 수 있을까요.
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
Comment Mock 객체의 getDeleted 관련 질문
안녕하세요, 강의 잘 듣고 있습니다. "삭제할 댓글이 자식 있으면, 삭제 표시만 한다." 테스트 코드의 내부에서 commentService.delete(commentId); 가 호출되고, delete의 내부에는 댓글이 이미 삭제 됐는지 확인하는 .filter(not(Comment::getDeleterd)) 필터가 존재하는데, getDeleted에 대한 목 객체의 동작은 따로 선언하지 않는 것일까요? (ex) given(comment.getDeleted()).willReturn(false); 답변 주시면 감사하겠습니다.
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
댓글 최대 2 depth - CUD API 테스트 & 테스트 데이터 삽입 질문입니다.
안녕하세요 강의 잘 듣고 있습니다. 강의랑 버전 맞춰서 실행하고 있는데delete 메서드는 잘 동작하는데 deleted가 계속 0이네요..아래 질문글도 보고 해봤는데 저는 강의 버전이랑 딱 맞춰서 뭐가 문제인지 잘 모르겠습니다!.. 댓글 세 개 다 테스트 해봤는데 테스트는 잘 통과하는데 강의에서는 두번째 댓글부터 Empty Set이라고 나오는데저는 아래 사진처럼 나옵니다..
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
PK 생성 전략의 '유니크 문자열 또는 숫자' 단점 부분 질문있습니다.
안녕하세요. 오늘도 인덱스 관련해서 질문을 들고 왔습니다!(선생님이 "이런것도 질문해? 제발 질문 하지마 제발" 이라고 들 정도의 질문을 하는 학생들이 대부분 실력이 상승 한다고 해서 물음표 살인마가 되기로 했습니다. 지인들한테 강의 마구마구 홍보중입니다.. 한번만 봐주셉요..) 데이터 삽입 필요한 인덱스 페이지가 가득 찼다면 ,B+ tree 재구성 및 페이지 분할로 디스크 I/O 증가정렬된 상태를 유지하기 때문에 삽입시마다 B+tree 재구성으로 인해 정렬로 인한 성능 저하 된다는건 이해가 되었습니다.(맞다면..) 허나 페이지 분할은 잘 이해가 안가네요 ㅠ 페이지 분할에 대해 제가 이해한 바인 아래 내용이 맞는지 궁금합니다.PK가 AUTO_INCREMENT일 경우데이터가 항상 B+ Tree의 마지막(오른쪽 끝)에 삽입됨.하나의 페이지가 꽉 차면, 새로운 페이지가 오른쪽에 생성됨.1. [ Page 1 ] (꽉 참) → 데이터 추가 시 분할 필요 2. [ Page 1 (반) ] → [ Page 2 (새로운 페이지 생성) ] PK가 유니크 문자열 또는 숫자일 경우랜덤한 값이 삽입될 때, 페이지가 꽉 차지 않았더라도 균형을 맞추기 위해 강제적으로 새로운 페이지가 만들어질 수 있음.1. [ Page 1 ] (데이터 60% 차 있음) → 중간에 랜덤 값 삽입 시 균형 유지 필요 2. 균형 유지 과정에서 일부 데이터를 새로운 페이지로 이동하여 분산 3. [ Page 1 (30%) ] → [ Page 2 (새로운 페이지 생성) ] 즉, 유니크 문자열 또는 숫자는 페이지가 “완전히 가득 차지 않아도” 새로운 페이지가 생성될 수'도' 있다.
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
spring 부트 3.5 사용중인데 zuul 어떻게 해양할까요
deprecated돼서 spring initializr에 검색조차 안되는데그냥 강의 듣다보면 다른 해결방안 나오는건가요?
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
rows per chunk 에 대해서 궁금합니다.
이번에 커버링 인덱스를 설명하시면서 아 대충 왜 빠르게 조회가 되는지 이해가 되기 시작했습니다. 그런데 최근에 했던 프로젝트 중에 이와 비슷한데 왜 성능이 개선되었는지 모르는 것이 하나 있습니다. 아래 부분인데요..일단 created_at 은 index 가 적용되지 않았음을 알려드립니다. select ep1_0.employee_post_id, ep1_0.access_url, ep1_0.contact, ep1_0.contents, ep1_0.member_id, m1_0.member_id, m1_0.access_url, m1_0.authority, m1_0.birth_day, m1_0.email, m1_0.login_id, m1_0.name, m1_0.nick_name, m1_0.password, m1_0.personal_link, m1_0.personal_statement, m1_0.sex, m1_0.tmp_password, m1_0.twitter_link, m1_0.youtube_link, ep1_0.payment_amount, ep1_0.payment_method, ep1_0.title, wft1_0.work_field_tag_id, wft1_0.name, ep1_0.career_year, ep1_0.created_at, ep1_0.updated_at from employee_post ep1_0 left join work_field_tag wft1_0 on wft1_0.work_field_tag_id=ep1_0.work_field_tag_id join member m1_0 on m1_0.member_id=ep1_0.member_id where wft1_0.work_field_tag_id=1 order by ep1_0.created_at desc, ep1_0.employee_post_id desc limit 0,10;이것을 explain analyze 한다면 Limit: 10 row(s) (cost=1088 rows=10) (actual time=39.1..39.1 rows=10 loops=1) -> Nested loop inner join (cost=1088 rows=1968) (actual time=39.1..39.1 rows=10 loops=1) -> Sort: ep1_0.created_at DESC, ep1_0.employee_post_id DESC (cost=399 rows=1968) (actual time=39..39 rows=10 loops=1) -> Index lookup on ep1_0 using FK_work_field_tag_TO_employee_post (work_field_tag_id=1) (cost=399 rows=1968) (actual time=0.0949..7.91 rows=1968 loops=1) -> Single-row index lookup on m1_0 using PRIMARY (member_id=ep1_0.member_id) (cost=0.25 rows=1) (actual time=0.011..0.011 rows=1 loops=10)이렇게 나오고 성능이 무척 안좋은 것을 볼 수 있었습니다(using filesort 가 직접적인 원인) 근데 문제는 member 에 대한 inner join 을 빼면 -> Limit: 10 row(s) (cost=398 rows=10) (actual time=10.5..10.5 rows=10 loops=1) -> Sort: ep1_0.created_at DESC, ep1_0.employee_post_id DESC, limit input to 10 row(s) per chunk (cost=398 rows=1968) (actual time=10.5..10.5 rows=10 loops=1) -> Index lookup on ep1_0 using FK_work_field_tag_TO_employee_post (work_field_tag_id=1) (cost=398 rows=1968) (actual time=0.0712..6.03 rows=1968 loops=1) 위와 같이 나오면서 성능이 무척 개선된다는 점입니다. 제가 보았을 떄 핵심적인 부분은 10 rows per chunk 입니다. 혹시 10 rows per chunk 같은 키워드는 언제 언제 발생하는지 알 수 있을까요??(왜 member에 대한 join 을 빼면 나타나구, wft1_0 을 left outer join 을 하는 것은 영향이 없는지..)mysql 공식 문서를 계속 뒤져도 발견하지 못했습니다. 강의와 관련 없는 부분이라고도 생각하실 수 있는데 이런 질문 해서 정말 죄송합니다.. 관련해서 블로그 정리한 거 혹시 필요한 정보가 있을 수도 있으니 링크 남겨놓겠습니다...https://velog.io/@dionisos198/Query-DSL-%EC%84%B1%EB%8A%A5-%EA%B0%9C%EC%84%A0-%EB%B0%8F-fetch-join-%EA%B3%A0%EC%B0%B0
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
테스트 코드 실행에서 URL을 인식 못하면서 500 에러 발생 시 관련 참고 글
https://velog.io/@ghwns9991/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-3.2-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EC%9D%B4%EB%A6%84-%EC%9D%B8%EC%8B%9D-%EB%AC%B8%EC%A0%9C스프링 3.2 부터 uri 관련 매개변수 어노테이션을 잘 인식하지 못한다고 하나 봅니다. 저는 윗 글의 두 번째(-parameters) 방법으로 해결했습니다.
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
'soft Delete 시 index 설정' 답변한 내용에서 질문 있습니다.
https://www.inflearn.com/community/questions/1516484해당 게시글의 답변중 아래 문장이 이해가 잘 안갑니다 ㅠ 물론, 삭제된 데이터가 극히 적다면, 위 비용은 딱히 문제가 안될 수도 있긴 합니다.삭제되지 않은 데이터가 훨씬 많다면, 조건에 일치(isDeleted=false)하는 데이터를 빠르게 찾을 수 있으므로, 스캔하는 범위는 어차피 적을테니깐요.하지만 삭제된 데이터가 많아질수록 조건에 일치하는 데이터를 찾기 위해 스캔하는 범위가 길어질 수 있으므로, 인덱스를 걸어둬야 빠르게 조회가 가능합니다!인덱스를 걸지 않았을때 삭제되지 않은 데이터(isDeleted = false)가 훨씬 많다면 스캔하는 범위가 적은 이유를 잘 모르겠습니다..인덱스가 없으면 삭제된 데이터가 많든, 많지 않든 무조껀 풀 스캔을 해서 스캔 범위는 똑같은게 아닌걸까요?또한, 데이터 연속성도 스캔할시 관련이 있는건지 궁금합니다.인덱스가 없을때 where isDeleted = false 쿼리 실행시 id가 4번까지만 스캔해서 스캔 범위가 적은걸까요?ㄸ직전 조건와 같을때 위와 같이 데이터가 흐트러져있다면 풀스캔을 하는 걸까요? 인덱스 공부좀 해야겠네요 흙흙
-
미해결스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
테스트 실행 시 "ClassNotFoundException" 에러
테스트 실행 시 "ClassNotFoundException" 에러 나시는 분들은 https://bit.ly/4hIOchi 이 글 한번 참고해보세요. 이 글 보고 해결했습니다.
-
해결됨카프카 완벽 가이드 - ksqlDB
Compact Topic에 대하여
안녕하세요 항상 좋은 강의 해주셔서 감사합니다.다름이 아니라 제가 프로젝트 중에 유저가 알림 설정한 데이터를 kafka로 받아서 시세 데이터와 조인하여알림 메세지를 생성하려고합니다. 유저 알림 데이터는 boolean값을 가진 활성화여부와 삭제라는 기능이있습니다.그래서 kafka내에서 유저 알림 데이터를 최신화하기 위해서 찾아본 결과 compact topic이라는것을 발견하였고 실습중에 있습니다만 결과가 좋지않아서 질문드립니다. sudo docker exec -it kafka-1 kafka-topics --create --bootstrap-server 192.168.56.101:29092 --topic user-alert-set --partitions 6 --replication-factor 2 --config "cleanup.policy=compact" --config "min.compaction.lag.ms=5000" --config "max.compaction.lag.ms=10000 " --config "delete.retention.ms=3000" --config "segment.ms=3000" --config "min.cleanable.dirty.ratio=0.01"이런식으로 토픽을 생성하여 실습한 결과1. Key A: value1 넣음 -> [A:value1] 2. Key A: value2 넣음 -> [A:value1, A:value2] 3. Key B: value1 넣음 -> [ A:value2, B:value1] 4. Key B: value2 넣음 -> [A:value2, B:value1, B:value2]이렇게 진행되었습니다. 삭제를 위한 tombstone메세지 또한 위와같은 형식으로 진행되었습니다.제가 이해한 바로는 같은 키의 값이 들어오면 들어온 값으로 최신화 혹은 삭제를 하는 설정으로 이해를 해서이 결과가 저는 이해가 되지않습니다. gpt한테 물어보니 로그 컴팩션은 "head"와 "tail" 두 부분으로 나뉩니다:Tail: 이미 컴팩션이 완료된 부분 (깔끔한 상태)Head: 아직 컴팩션되지 않은 활성 부분 (더티 상태)예시:1. A:value1 입력 -> [A:value1] 2. A:value2 입력 -> [A:value1, A:value2] (컴팩션 발생) -> [A:value2] // A는 tail 부분으로 이동 3. B:value1 입력 -> [A:value2, B:value1] // B는 head 부분에 위치 즉, A는 이미 컴팩션되어 tail 부분에 최신 값만 있고, B는 아직 head 부분에 있어서 컴팩션되지 않은 상태로 남아있는 것입니다.이는 정상적인 동작이며, B도 시간이 지나면 컴팩션될 것입니다.라는 답변을 받았지만 시간이 지나도 키가 B인 데이터는 여전히 두개로 남아있었습니다.혹시 이유를 아신다면 설명해주시면 감사하겠습니다.