안녕하세요.
IT 서비스 대기업 개발자로 근무하며, 대규모 시스템을 지탱하기 위해 다양한 기술을 활용해보고 있습니다.
실무 관점의 개발 지식을 공유하고자 개설하였고, 많은 도움이 되었으면 좋겠습니다.
[문의]
Email : kukekyakya@gmail.com
講義
受講レビュー
- 分散データモデリング
- Spring Bootで直接作りながら学ぶ大規模システム設計 - 掲示板
- Spring Bootで直接作りながら学ぶ大規模システム設計 - 掲示板
投稿
Q&A
카프카 메시지 순서 관련 문의
rlapwl님, 안녕하세요! 순서에 대해서 완벽하게 보장하는 것은 쉬운 문제는 아닙니다.주문 id를 파티션 키로 지정한다고 하더라도, 순서가 변경될 수 있는 상황은 분명 있습니다.말씀하신대로 비동기 상황에서는 producer가 순서를 바꿔서 보낼 수도 있고,컨슈머가 모종의 이유로 실패하여 별도의 재처리 토픽에서 retry를 시도하다가 순서가 바뀔 수도 있고,이벤트 전송을 동시에 처리하는 설정일 수도 있고(max.in.flight.requests.per.connection),파티션 수를 늘리는 과정에는 파티션 키는 동일하더라도 새로운 이벤트가 다른 파티션으로 이벤트가 적재될 수도 있는 등..이러한 상황을 해결하기 위해서는 Producer가 발행하는 이벤트에 대해 넘버링을 할 수도 있을 것 같고요(컨슈머는 반드시 마지막 시퀀스와 최신 시퀀스에 대해 diff=+1인 이벤트만 정상 이벤트로 간주),논리적인 관계(주문 완료 상태가 아닌데, 주문 취소 상태 이벤트가 먼저 수신될 수는 없음)를 이용할 수도 있을 것 같습니다.또는, 이벤트를 컨슈머에서 append-only로 저장하다가 모두 수신 됐을 만한 충분한 시간을 대기한 후에, 순차적으로 처리하는 것도 하나의 방법일 것 같습니다. 논리적인 관계가 복잡하지 않고 명확하고 간단히 정의되어있다면 해당 방법만을 채택할 것 같고,더욱 복잡한 상황이라면 넘버링 정책으로 컨슈머가 순서 변경도 감지하고,평시에는 실시간으로 즉시 처리하다가 문제가 발생한 데이터에 대해서 알람 또는 모니터링 후에 수동 처리 및 관련 원인 개선을 해나갈 것 같습니다.파티션 수를 늘리는 과정에 대한 문제는, 일시적으로 이벤트를 모두 소진한 뒤에 잠시 중단 상태로 만들 수도 있고요.(시스템 점검과 같은 상황에 처리) 파티션 id를 고정으로 지정할 수도 있을 것 같습니다.사실 시스템 장애 상황에는 아키텍처에 따라 순서 변경 여지에 대해서 완벽하게 방지할 수는 없으므로, 여러 가지 방법을 복합적으로 고려해봐야할 것 같습니다!(참고 - 예전에 유사한 질문이 있었네요.)
- 0
- 2
- 13
Q&A
카프카 학습에 관한 질문
riley님, 안녕하세요! Kafka Cluster에 대해서는 강의에서 20분 정도로 언급 되었고, 분명 부가적인 공부도 필요합니다.하지만 사실.. 직접 클러스터 세팅하고 운영하는게 아니라면, 처음 적용하려는 개발자 관점에서는 이걸로도 (거의) 충분하긴 합니다. 딱 개발자에게 필요한 핵심 부분만 요약을 한 것이었거든요.각 개념에 대해서 조금 더 차분하게 심도 있게 배워보고 싶으시면, 저는 보통 책을 선호하는 편입니다.물론, 공식 문서도 잘 되어있지만 직접 이슈 해결하는 과정 속에 있거나 뭔가 아는게 있어야 읽히더라고요.(영어가 익숙치 않다면 접근성이 떨어질 수 있고, ai한테 궁금한거 물어보는게 더 편하기도 하고요.)카프카 관련 강의는 수강한 적이 없어서 잘 모르겠네요.저도 처음에는 책(카프카인액션, 데이터중심애플리케이션설계 등 카프카에 대한 책 뿐만 아니라 다방면으로 공부는 필요하고, cs 지식이 있으면 수월합니다.)으로 공부했고 이해하는데 많은 도움 되었지만,결국 현업에서 직접 경험하면서, 이슈 하나씩 해결하고 공식 문서 살펴보며 배우는게 더욱 와닿긴 하더라고요.그리고 개발자 관점에서는 카프카 자체가 어렵다기보단, 카프카를 전체적인 시스템에서 어떻게 활용하고 다룰 수 있을지, 프로듀서와 컨슈머가 이벤트를 다룰 때 발생할 수 있는 문제(유실, 중복, 순서 변경, 지연 등)들을 어떻게 해결할 수 있을지 고민하는 것이 더욱 어려운 것 같습니다.카프카 공부도 필요하지만 어디까지 공부를 할지 경계를 잘 설정하는 것도 좋을 것 같고, 결국 개발 실무와 활용 관점에서 학습이 필요한 범위는 다를 수 있다는 점도 인지해 두시면 좋을 것 같네요!
- 0
- 1
- 18
Q&A
완강 후 학습 방향에 대한 질문
westhan님, 안녕하세요!연휴 기간임에도 열심히 잘 수강해 주셔서 감사합니다! 말씀하신대로 강의에서 제시된 기술들을 한번에 모두 적용하려는 것은 너무 복잡하고 쉬운 작업은 아닙니다.실제로 각자 속한 환경에서는 모든 기술이 다 필요하지 않을 수 있을 것 같고요! 개념과 용어들에 대해서 챕터별로 실무 우선순위를 정해보자면..게시글 챕터(클러스터드/세컨더리/커버링 인덱스 개념 이해 및 최적화)좋아요 챕터(DB 트랜잭션과 락에 대한 이해)조회수 챕터(인메모리 데이터베이스와 캐시에 대한 이해, 레디스 활용)인기글 챕터(카프카에 대한 이해와 활용)게시글 조회 최적화 챕터(CQRS, 캐시 전략 등 적용하면 좋지만, 정말 이 정도까지 최적화가 필요할 때 적용하면 충분. 돈도 들어가고 복잡도도 엄청 높아지고 어렵습니다.)댓글 챕터(대규모 데이터의 계층형 테이블을 다룰 일이 있다면 필요하겠지만, 다룰 일이 없다면 필요할 때 적용하면 충분)이렇게 될 것 같습니다. 분산 DB나 MSA도 알아두고 잘 활용할 수 있으면 좋긴 하겠지만.. 당장에 경험할 수 없는 환경이면 실제 적용하기도 어렵고 시스템 복잡도도 엄청나게 많이 올라갑니다. 4~5번이 이러한 내용들이라서 쉽게 적용하긴 어려우실 수는 있을 것 같습니다.개인적으로 DB가 가장 중요하다고 생각하는게, 실제 병목이나 장애 지점이 되는 것도 보통 DB이고, 리소스도 최대한 절약하며 효율적으로 사용해야하는 것도 DB이기 때문에,대규모 시스템을 당장 다룰 일이 없다면 RDB 내부 동작만 제대로 이해하고 적용할 수 있으면 충분하다고 생각합니다! (분산 DB가 아니라 데이터베이스 이론을 말하는 것입니다.) 아무튼 정리하면, 1~3번 활용할 수 있는 방향을 먼저 중점적으로 살펴보시면 좋을 것 같고요.지금도 충분하다고 생각되신다면, 굳이 꼭 복잡한 기술들을 바로 적용할 필요도 없습니다!인덱스나 쿼리가 잘 최적화되어있는지 점검해보시고, 성능적으로 아쉬운 부분들 하나씩 확인하며 개선해 나가면 충분하다고 생각되네요!
- 0
- 1
- 18
Q&A
Transactional Outbox 테이블 관련하여 질문드립니다
learnlearn님, 안녕하세요! 질문 주신 내용은 꼭 정답이 있다기 보단, 팀과 시스템에서 어떤 식으로 운영하고 싶은지에 따라서 정책을 달리할 수 있을 것 같습니다.실무에서도 단순하게 삭제 방식을 취해도 되고, 발행 완료 상태로 업데이트 한다거나 별도의 테이블에 한동안 관리할 수도 있습니다.어떠한 방법을 취하든 크게 상관은 없겠지만,발행 완료된 이벤트에 대해서도 저장하고 있다면 추후 이벤트 추적 등에 유리한 측면은 분명 있습니다.문제 상황 발생 시에 특정 기간 동안의 이벤트를 리플레이 할 수도 있고, 어떠한 이벤트가 언제 발행되었는지 추적해볼 수도 있습니다.(이러한 관점에 대해서는 이벤트 소싱이라는 개념이 있습니다.)다만, 이러한 필요성이 딱히 안보인다면, 발행 완료 이벤트에 대해 직접 관리하고 별도 삭제 태스크도 만들어야하는 복잡성이 생기긴 합니다.결국 삭제 여부나 주기도 팀과 시스템에서 정한 정책에 따라서 달리할 수 있는 것이고, 별도 배치나 스케줄러에서 수행될 수 있습니다.
- 0
- 2
- 15
Q&A
만약 조회수가 중요한 데이터라면 어떻게 해야 되나요?
민우님, 안녕하세요!열심히 수강해 주셔서 감사합니다. 중요한 정보인데 쓰기가 자주 발생하는 상황에서 In-Memory 저장소를 메인으로 사용하고 RDB를 백업용으로 사용하면 위험하지 않나? 라는 생각이 들었습니다!이럴 때에는 보통 어떻게 처리하시나요? (이럴 때 NoSQL을 사용하나요?)정말 100% 유실이 없어야 하는지부터 다시 한번 고민해볼 것 같습니다.현재 강의에서는 100개 단위의 백업 전략을 취하고 있는데요, 단순하게 50개 또는 10개 단위로 백업 개수를 줄여도 됩니다. 사실 평시에는 유실될 일이 거의 없기도 하고, 정말 큰 문제로 보기 어려울 수도 있고요. 그래도 유실이 없어야 한다면, 좋아요 수처럼 처음부터 안전한 저장소에서 관리해도 됩니다.쓰기 트래픽의 우려가 다시 나오게 되는데요, 조회수에 대해서도 부가적으로 샤딩해서 저장할 수도 있습니다.예를 들어, 조회수 테이블을 N개로 분산하고, 랜덤한 테이블만 1 증가, 조회할 때에는 N개의 샤드에 모두 조회해서 더하는 방식입니다. 그러면 쓰기 트래픽은 분산되므로 단일 레코드에 대한 락도 N개로 분산되는 것이고, 읽기 비용은 일부 늘어나게 되겠네요.정확도가 중요한 영역에서는 안전한 저장소에서 조회하고, 정확도보단 성능이 중요한 영역에서는 지금 전략처럼 여전히 더욱 빠른 저장소에서 이중으로 관리하며 조회해도 됩니다. 또, 고민해볼 수 있는 방법은 append-only 방식으로 저장하고, 카운트 집계는 비동기로 처리하는 방안입니다.조회가 일어나면 각 이벤트에 대해 오직 삽입만 수행하고, 후처리로 별도의 태스크에서 정확한 카운트를 집계하는 것입니다.조회수에 대해 약간의 지연은 생길 수 있겠지만, 적재되어 있던 조회 이벤트를 기반으로 정확한 조회수를 계산해낼 수 있습니다. 정리하면, 요구사항이나 특성마다 어디까지 감안할 수 있는지 또는 보여지는 클라이언트 영역마다 어떤 부분을 중점으로 봐야하는지 등에 따라서 모두 다를 수 있을 것 같습니다.그렇기 때문에 꼭 한가지 방법을 채택한다기 보단, 클라이언트 영역마다 여러 가지 방법을 복합적으로 적용해볼 수도 있을 것 같네요!빅데이터 실시간 처리에 대해서는 람다 아키텍처나 카파 아키텍처도 한번 참고해보시면 좋을 것 같네요!
- 0
- 1
- 13
Q&A
최적화 순서
민서님, 안녕하세요! 간단히 답변 드릴 수 있는 내용은 아니군요!결국 복합적으로 다 보면서 고민하는데요, 간단히 말씀 드려보겠습니다. 최적화 고민 순서에 대해서는, 일단 가장 쉽게 대응할 수 있는 방법을 먼저 고민해 봅니다.여기에서 쉽다라는건 개발 자체의 어려움을 말하는 것은 아닙니다.변경의 범위가 크지 않고, 부하를 크게 늘리지 않고, 실제로 돈이 더 들어가지 않는 방향 등을 말합니다.단순히 설정 값을 바꾼다든가, 이미 운영중인 캐시 시스템이 있었다면 붙인다든가, 애플리케이션 코드가 비효율적인 부분이 있으면 개선한다든가 등이 있겠네요.위처럼 처리가 어려울 때의 다른(복잡한) 방안을 고민해보게 되는데요,코드의 큰 작업 단위, 인덱스 추가, 서버 증설, 개발이 정말 많이 어려운 경우 등이 있겠네요. 트래픽이 몰리면, 일단 저는 개발자 입장이므로 애플리케이션 서버/연동중인 플랫폼들(DB/카프카/캐시 시스템/외부 연동 서버 등)의 지표들을 확인해보고, 트래픽이 얼마나 증가했고 아직까지 감당 가능한 상황인지 등 점검해보는 것 같네요.개선 방향을 정하는 것은 문제 상황마다 모두 다를 것 같습니다.DB 질의가 느리다? -> 인덱스나 쿼리를 재점검DB 부하가 크다? -> 캐시 적용 또는 DB 분리응답이 느리다? -> 연결되는 흐름 모두 파악 후 병목 지점 파악하여 개선연결이 안된다? -> 애플리케이션이 죽었는지, 서버가 죽었는지, 네트워크 문제인지, 장비 문제인지, 설정 문제인지, 코드 문제인지 모두 점검이처럼 원인도 하나가 아닌 여러 개 일 수 있고, 확인하다보면 모든걸 다 봐야할 때도 있어서 정확한 기준은 없는 것 같네요.보통 전 초기 개발 단계부터 현재 할당된 리소스 범위 내에서는 최적화가 이미 되어 있는 방향으로 설계를 진행하고,이후에 놓쳐진 부분은 운영하면서 지속 모니터링 및 개선하게 되는 것 같습니다. 간단히 답변 드릴 수 있는 부분은 아니라 만족스러운 답변이 되었을지 모르겠네요, 혹시 더 궁금한 점 있으시면 편히 남겨주세요!
- 0
- 2
- 13
Q&A
Kafka 대신 Redis Pub/Sub을 사용할 수도 있을까요?
hobit22님, 안녕하세요!아주 좋은 질문이네요. Kafka를 선택하신 이유 또는 기준이 무엇인지가장 큰 기준은 안정성일 것 같습니다.Kafka는 여러 개의 브로커로 장애 시에 가용성을 유지할 수도 있고, 디스크 쓰기와 복제를 통해서 이벤트 유실 문제에 대해서도 해결할 수 있습니다. 데이터의 offset도 기록하고 있다보니, 애플리케이션 재시작이나 재처리 필요 시에도 유용하고요.Kafka는 뿐만 아니라 확장성이나 성능도 좋기 때문에 대규모 데이터를 다루는데 아주 유리합니다.Redis는 이러한 측면들에서 Kafka보다 불리한 측면이 많다고 생각되네요.(확장성(파티션), 가용성, 안정성(offset, 브로커, 디스크, 백프레셔) 등)사실 대규모 이벤트를 안전하게 중개하기 위한 시스템으로 Kafka는 이미 안정성도 많이 입증되었고 꾸준히 관리도 되고 있다보니, 거의 표준처럼 사용되는 것 같습니다.물론, Redis를 이미 운영중이고 익숙하며 안정성에 크게 우려가 없다면 Redis를 채택해도 전혀 문제 되진 않습니다.Kafka는 아무래도 운영도 어렵고 설정이나 내부 구조도 더욱 복잡할 수 있으니깐요.하지만 복합적으로 다른 요인들도 같이 고려해 본다면, Redis의 pub/sub을 채택하는게 옳은 선택일지는 고민해볼 수 있을 것 같습니다. 이벤트 브로커(Event Broker)와 메시지 브로커(Message Broker)의 개념적 차이이벤트와 메시지의 용어 차이를 이해해 보시면 좋을 것 같습니다!메시지는 1:1로 대상과 방향이 있는 개념이라면, 이벤트는 1:N으로 대상과 방향이 정해져 있지 않습니다.물론 카프카도 Message Broker로 사용할 수 있지만, 강의에서는 이벤트를 중개하기 위한 시스템으로 채택한 것이고, 공식 사이트에서도 Distributed Event Streaming Platform이라고 소개합니다. 제가 이해하기로는 Redis는 단순한 메시지 전달 중심,Kafka는 이벤트 스트리밍 및 데이터 파이프라인 중심으로 알고 있는데,이 부분이 맞는 방향인지도 확인해보고 싶습니다.Redis를 단순히 메시지 전달 중심이라고 정의하긴 애매할 것 같습니다.Redis도 이벤트 브로커로 사용될 수 있는 것이고, 앞선 답변에서 어느 정도 해소되었을 것 같네요!결국 Redis와 Kafka 둘다 이벤트 브로커 또는 메시지 브로커로 사용할 수 있지만(Kafka는 외에도 제공하는 기능 및 활용 방식이 훨씬 많습니다),제공하는 범위가 다르기 때문에 현재 시스템에서 어떠한 지표까지 감당해야 하는 상황인지,시스템 운영 복잡도는 얼마나 높여지는지 등을 고려해보시면 될 것 같습니다!
- 0
- 2
- 17
Q&A
무한 뎁스 댓글 테스트 데이터 삽입 질문
시안님, 안녕하세요! 해당 부분은 사실 특별한 이유가 있다기보단..계층 구조로 생성하지 않는게 코드 작성도 간단하고, 데이터 초기화도 빠르게 처리할 수 있어서 그랬습니다..!계층 구조에 대한 테스트는 별도로 진행되므로, 초기화 방식에 대해서는 딱히 의도가 있던건 아니라 크게 염두에 두시진 않아도 괜찮을 것 같네요!
- 0
- 2
- 11
Q&A
게시글 정보와 게시글 조회수 동시에 필요한 API 조회 질문
leebs0521님, 안녕하세요! 결론부터 말씀드리면, 두 방식(+부가적인 방식들도) 모두 사용합니다. 프론트엔드에서 각 API를 별도로 호출한다고 하더라도, 크게 문제되지 않을 수도 있겠습니다.하지만 API를 개별적으로 클라이언트에서 호출 및 조합한다면, 각 API별 실패에 대해서 정책 정리가 필요할 수도 있고, 여러번 서버 네트워크에 호출해야 하므로 전체적으로 화면을 그려내는 비용이 증가할 수 있습니다.또, API 팀과 프론트엔드 팀이 별도로 분리되어 있으면, 사실 API 팀의 입장만 고려할 수도 없습니다. 결국 분리된 API를 조합하려면 클라이언트의 개발 복잡도는 분명 올라가게 되고, 부가적인 소통이 필요할 수도 있습니다.다른 문제로는, 클라이언트가 웹 프론트엔드뿐만 아니라 앱(and/ios), 다른 연동 서버 등 다양할 수도 있다는 것인데요.이러한 경우에 클라이언트는 각자의 구현 방식이 모두 다를 수 있고 일관되지 않는다면, 문제 시에 원인 추적이 더욱 어려워질 수도 있습니다. 물론, 항상 클라이언트를 위한 API를 제공해주는 것도 어렵긴 합니다.클라이언트의 요구사항을 위한 모델과 API에서 바라보고 있는 도메인은 절대 일치가 될 수 없기도 하고,클라이언트 요구사항을 항상 인지하고 대응해 주는 것도 쉽지 않기 때문입니다.이 경우에는 클라이언트에서 각각 호출한 뒤 병합하는 방식으로 처리하게 되네요. 적어도, API에서 클라이언트 요구사항을 어렵지 않게 맞춰줄 수 있는 상황이라면,또는, 클라이언트 복잡도가 너무 커진다면(예를 들어, 게시글 영역 하나 그리는데, 게시글/조회수/좋아요수 일일이 별도로 호출하는 것도 복잡하고 이상합니다)API에서 클라이언트 요구사항 맞춰서 제공할 수도 있는 것 같네요.BFF를 구성하거나 서버에서 데이터 조합하는 레이어를 둘 수도 있는 것이고요.말씀하신대로 같은 도메인으로 묶어낼 수도 있습니다.(클라이언트 요구사항과 무관하게 묶어도 괜찮은 도메인이라면) 팀의 규모나 사정, 구성원들이 익숙한 개발 방식은 모두 다를 수 있다보니, 꼭 정답이 있기보단 서로 조율하는 과정은 필요한 것 같습니다!
- 0
- 2
- 13
Q&A
실제 실무에서도 이런식으로 쿼리를 작성하는지 궁금합니다!
g_a_m_e_님, 안녕하세요!열심히 잘 수강해주셔서 감사합니다! 실무에서도 커버링 인덱스에 대해 최적화가 필요하다면, 이런 식으로 서브쿼리를 흔히 사용합니다.강의에서 설명드리는 페이지 번호 방식의 목록성 데이터는 위와 같은 쿼리가 일반적이라고 봐주시면 될 것 같네요.(DB에 따라서 offset/limit 문법을 지원하지 않을 수도 있지만, 결국 InnoDB의 동작 원리만 이해하고 있다면 모두 유사하게 최적화할 수 있습니다.)물론, 시스템 전체적인 관점에서 본다면 서브쿼리뿐만 아니라 다른 해결책도 많습니다.(부하를 다른 곳에 분산하거나 성능을 더욱 높인다든지 등의 관점이고, "게시글 조회 최적화" 챕터에서 학습하게 됩니다.)참고로 이 부분은 당연히 인지하시겠지만, 모든 경우에 대해서 서브쿼리가 적절하다는 것은 아니고,목록성 데이터 조회 요구사항의 최적화에서 적절했다는 의미입니다!서브쿼리는 중간 임시 테이블을 만들어낼 수도 있고 잘못 사용하면 오히려 문제가 될 수 있기 때문에,실제 사용하고자하는 쿼리에 대해서는 플랜도 분석해 보시고 검수하신 후에 채택하시면 될 것 같습니다.
- 0
- 2
- 17