좋은 발표 감사합니다! 제가 초보자라 궁금한게 조금 있어 여쭈고 싶네요. 혹시 마지막 멀티 스레드를 위해 ForkJoinFool의 parallel Stream을 통해서 처리를 하셨는데 앞서 다룬 CompletableFuture 의 비동기 방식과 어떤 차이가 있는지 알 수 있을까요? 제가 잘못 아는거일 수 있는데 둘 다 여러 쓰레드를 사용할 수 있지 않나요? 제가 모르는 부분이 많아 알려주신다면 정말 감사할것 같습니다.
궁금해서 찾아보니 CompletableFuture로 나이브하게 사용하는 경우에 포크조인풀의 commonPool()을 호출해서 사용하게되는데, 이 스레드풀이 어플리케이션 전역적으로 사용하고 있는 풀이라 다른 비동기 처리에도 영향이 생길 수 있다고 하네요. 다른 비동기 처리에 영향을 주지 않게 독립된 풀을 생성해서 사용하려고 하신게 아닐까요..?
일부 개념이 비슷한 프로젝트를 진행중인데 궁금한게 있어서 질문드립니다! 카프카는 사용해보지 않아서 잘 모르지만, UserID를 해싱하여 특정한 partition으로 전달되도록 하는 것 같은데 (아마도요..!) 실제로 Consumer를 연결할 때, 특정 partition에 연결하는 것을 명시하나요? (RabbitMQ의 vhost처럼) 혹은 카프카 자체적으로 Consumer를 분산시켜 연결하는 것인가요? 발표 내용에서 partition >= consumer을 유지하려는 것은 partition : consumer가 1 : N이 되는 순간 UserLock에 의한 송금실패가 또 발생하기 때문인 것 같은데 그래서 일부러 1 : 1을 유지한 것인가요? 아니면 1 : N이 가능하지만, 서비스 로직 상 1 : 1을 유지해야 되는 것인가요? :)
개발자가 produce 할 때, 메시지 recordKey에 userId 처럼 지정해서 넣어주면, (카프카 코드를 까보니) 해싱을 통해 특정 파티션으로 전달되도록 하네요. 개발자가 컨슈머 설정에서 파티션 할당 전략(Range, Round Robin, Sticky, Cooperative Sticky)을 지정해줄 수가 있는데, 파티션 할당 전략에 따라 파티션과 컨슈머가 연결됩니다. 디폴트 전략은 kafka 버전에 따라 다른 것으로 알고 있습니다. UserLock에 의한 송금 실패를 막기 위해 일부러 1 : 1 유지한 것입니다. 관심있게 봐주셔서 감사합니다:)
14:00 에서 설명해주신거 같은데 기본 전제조건은 파티션 하나당 할당된 컨슈머는 하나여야 하기때문에(동일 컨슈머 그룹 기준) 컨슈머를 더 늘려도 파티션을 할당 받지 않은 유휴 컨슈머들이 생깁니다. 서비스 로직 레벨은 아니고 카프카 제약 사항이고 억지로 컨슈머 그룹을 쪼갠다면 같은 파티션을 여러 노드에서 읽을 순 있겠으나 카프카는 오프셋을 컨슈머그룹 레벨로 관리하기에 당연히 다른 컨슈머 그룹이 컨슘한 메시지간에는 중복이 있고 이를 해결하려면 득보다 실이 많아질거 같네요
같은 유저의 송금건은 같은 컨슈머로 보내게 된 후 유저락은 필요 없어지게 보일 수 있으나ㅎㅎ 송금 실행 서버에서 유저 잔액이 꼬이지 않게 하기 위해서 유저락은 계속 사용하고 있습니다~! 그렇다보니 17:11 코드에 써놓은 것처럼 컨슈머에서 벌크로 읽어온 후, userId 로 groupBy 쳐서, 멀티쓰레드 돌릴 때 같은 사용자 송금건들은 같은 thread 에서 처리되도록 했습니다! 관심있게 봐주셔서 감사합니다 :)
귀에 쏙쏙 박혀요!! 최고입니다.
지연이체 서비스 개발 과정을 상세히 공유해주셔서 감사합니다. Kafka, Zuul Proxy 등 새로운 기술 키워드를 알아갑니다. 좋은 발표 감사합니다!
10:36 record 키 값에 UserId를 넣음으로써, 같은 Partition, 같은 Consumer가 소비하도록 설정
쉽게 설명해주셔서 좋아요❤❤
좋은 발표 너무 감사합니다🎉🎉
잔잔바리 발표 봐주셔서 감사합니다😀
덕분에 지연이체를 등록하고 꿀잠을 잘 수 있게 되었습니다! 감사합니다!
@@김민수-q2o7o 감사합니다😀 하지만 지연이체 뭐 온콜 울리면 같이 꿀잠 깨셔야합니다^^
좋은 발표 잘 들었습니다. 감사합니다!
들어주셔서 감사합니다!🙏
17:16 err메세지가 좀 야시꾸리하네요
좋은 발표 감사합니다!
제가 초보자라 궁금한게 조금 있어 여쭈고 싶네요.
혹시 마지막 멀티 스레드를 위해 ForkJoinFool의 parallel Stream을 통해서 처리를 하셨는데 앞서 다룬 CompletableFuture 의 비동기 방식과 어떤 차이가 있는지 알 수 있을까요?
제가 잘못 아는거일 수 있는데 둘 다 여러 쓰레드를 사용할 수 있지 않나요?
제가 모르는 부분이 많아 알려주신다면 정말 감사할것 같습니다.
궁금해서 찾아보니 CompletableFuture로 나이브하게 사용하는 경우에 포크조인풀의 commonPool()을 호출해서 사용하게되는데, 이 스레드풀이 어플리케이션 전역적으로 사용하고 있는 풀이라 다른 비동기 처리에도 영향이 생길 수 있다고 하네요. 다른 비동기 처리에 영향을 주지 않게 독립된 풀을 생성해서 사용하려고 하신게 아닐까요..?
CompletableFuture, ForkJoinPool 이라는 키워드로 검색하면 정리자료들이 꽤 나오는 것 같아요!
@@j3ssu9 좋은 의견 너무 감사합니다!
관련해서 저도 조금 더 공부해보겠습니다!
일부 개념이 비슷한 프로젝트를 진행중인데 궁금한게 있어서 질문드립니다!
카프카는 사용해보지 않아서 잘 모르지만,
UserID를 해싱하여 특정한 partition으로 전달되도록 하는 것 같은데 (아마도요..!)
실제로 Consumer를 연결할 때, 특정 partition에 연결하는 것을 명시하나요? (RabbitMQ의 vhost처럼)
혹은 카프카 자체적으로 Consumer를 분산시켜 연결하는 것인가요?
발표 내용에서 partition >= consumer을 유지하려는 것은 partition : consumer가 1 : N이 되는 순간 UserLock에 의한 송금실패가 또 발생하기 때문인 것 같은데
그래서 일부러 1 : 1을 유지한 것인가요? 아니면 1 : N이 가능하지만, 서비스 로직 상 1 : 1을 유지해야 되는 것인가요? :)
개발자가 produce 할 때, 메시지 recordKey에 userId 처럼 지정해서 넣어주면, (카프카 코드를 까보니) 해싱을 통해 특정 파티션으로 전달되도록 하네요.
개발자가 컨슈머 설정에서 파티션 할당 전략(Range, Round Robin, Sticky, Cooperative Sticky)을 지정해줄 수가 있는데, 파티션 할당 전략에 따라 파티션과 컨슈머가 연결됩니다. 디폴트 전략은 kafka 버전에 따라 다른 것으로 알고 있습니다.
UserLock에 의한 송금 실패를 막기 위해 일부러 1 : 1 유지한 것입니다.
관심있게 봐주셔서 감사합니다:)
14:00 에서 설명해주신거 같은데 기본 전제조건은 파티션 하나당 할당된 컨슈머는 하나여야 하기때문에(동일 컨슈머 그룹 기준) 컨슈머를 더 늘려도 파티션을 할당 받지 않은 유휴 컨슈머들이 생깁니다. 서비스 로직 레벨은 아니고 카프카 제약 사항이고 억지로 컨슈머 그룹을 쪼갠다면 같은 파티션을 여러 노드에서 읽을 순 있겠으나 카프카는 오프셋을 컨슈머그룹 레벨로 관리하기에 당연히 다른 컨슈머 그룹이 컨슘한 메시지간에는 중복이 있고 이를 해결하려면 득보다 실이 많아질거 같네요
처음에 중복 송금을 방지하기 위해 상태체크 + 분산락(UserLock)이 필요했지만 파티셔닝 활용 이후엔 분산락이 필요 없어져서 벌크 컨슘 + 멀티쓰레드 처리가 가능해진게 맞을까요?
같은 유저의 송금건은 같은 컨슈머로 보내게 된 후 유저락은 필요 없어지게 보일 수 있으나ㅎㅎ 송금 실행 서버에서 유저 잔액이 꼬이지 않게 하기 위해서 유저락은 계속 사용하고 있습니다~!
그렇다보니 17:11 코드에 써놓은 것처럼 컨슈머에서 벌크로 읽어온 후, userId 로 groupBy 쳐서, 멀티쓰레드 돌릴 때 같은 사용자 송금건들은 같은 thread 에서 처리되도록 했습니다!
관심있게 봐주셔서 감사합니다 :)
어휴.. 이런 거 개발하면 매일매일이 문제 생길까봐 불안해서 못살듯..
ㅋㅋㅋ 괴롭게 즐겁게 살고 있습니다ㅎㅎ