미국달팽이
@americasnail
수강생
615
수강평
24
강의 평점
4.5
2025.06 ~ 현재:
미국 실리콘밸리 AI Coding Agent, 6K+ 스타트업 창업 (ex. Claude Code, Codex)
스레드 3.8K 시스템 디자인, 실리콘밸리, 테크, AI 글 계정 운영중 (rich_I_2024)
2024.05 ~ 2025.05:
미국 실리콘밸리 AI 핀테크 스타트업, 소프트웨어 엔지니어
2023.08 ~ 2024.04:
미국 빅테크(OpenAI, Meta, Apple, etc) 엔지니어 펠로우십 풀스택 소프트웨어 엔지니어 펠로우
~2022.10 @국내 기업 재직(검색포털/핀테크, AI)
강의
로드맵
전체 1수강평
- 고성능 실시간 분산 시스템 RabbitMQ + Kafka + Redis 실전 프로젝트
- 고성능 실시간 분산 시스템 RabbitMQ + Kafka + Redis 실전 프로젝트
- 고성능 실시간 분산 시스템 RabbitMQ + Kafka + Redis 실전 프로젝트
- 고성능 실시간 분산 시스템 RabbitMQ + Kafka + Redis 실전 프로젝트
- 고성능 실시간 분산 시스템 RabbitMQ + Kafka + Redis 실전 프로젝트
게시글
질문&답변
simcached를 검색을 했을때 해당 자료가 나오지 않는데 혹시 MemcachedGPU 라고 불리는 기술을 말씀하시는건가요?
안녕하세요. BBB AAA 님,감사합니다. 좋은 질문 해주셨습니다. “Sim cached”라는 표현은 주로 시스템 디자인 인터뷰나 아키텍처 토론에서 나오는 슬랭/약어 입니다.제가 인도계, 미국 빅테크 구글, 메타, OpenAI, 어도비 등의 엔지니어 분들과 직접 토론하며, 배웠었는데 그러다보니, 저도 모르게 슬랭/약어를 사용하게 되었습니다.실제 Memcached, Redis, ElastiCache 같은 분산 캐시(distributed cache)를 쓰지 않고 → 그냥 한 서버(한 프로세스) 안에서 HashMap, dict, LRU Cache 등으로 흉내 내서 구현한 캐시를 의미합니다. 감사합니다. 좋은 하루 되세요!
- 0
- 1
- 28
질문&답변
유튜브 예제에서 흐름 관련 질문있습니다
안녕하세요. 고병찬님. 질문을 늦게 해결하게 되어 매우 죄송한 말씀 드리며, 다음 부터는 늦는 일이 없도록 하겠습니다. 양해를 구하며 답을 작성합니다. 좋은 질문 감사드립니다. 영상 스트리밍 요청은 일반적으로 API Gateway를 거치지 않고, CNAME으로 매핑된 CDN Edge로 바로 전달됩니다. API Gateway는 메타데이터 조회, 권한 검증, 추천 API와 같은 제어 요청만 처리하고, 실제 대용량 비디오 데이터는 성능과 확장성을 위해 CDN이 직접 서빙합니다.따라서,스트리밍 서비스에서는 메타데이터 요청과 실제 비디오 데이터 요청이 분리되어 처리됩니다.메타데이터나 권한 확인 같은 제어 요청은 API Gateway를 통해 처리되고,실제 대용량 비디오 스트림(적응형 스트리밍 매니페스트 및 조각)은 CDN으로 직접 서빙됩니다.CDN 도메인은 CNAME으로 매핑되어 있어 클라이언트가 직접 요청하며,cache hit 시 edge에서 바로 응답되고 miss 시에는 origin blob storage에서 읽어옵니다.경우에 따라 권한 체크나 signed URL 발급이 필요하면 API Gateway를 통해 토큰/URL을 받은 뒤,클라이언트가 해당 URL로 CDN에 직접 스트리밍 요청을 보내는 방식으로 처리합니다. 감사합니다. 다시 한 번 늦어서 죄송하다는 말씀 드립니다.좋은 하루 되세요!
- 0
- 2
- 30
질문&답변
Spotify 서비스 설계에서 transcoder service에 대해 문의 드립니다.
안녕하세요. 바쁜 일 때문에 늦어진 질문이 있는지 파악하지 못했습니다. 죄송한 말씀 드립니다. 네 이해하신 게 맞습니다. Transcoder는 업로드된 원본 음악 파일을 여러 비트레이트 및 스트리밍 포맷으로 변환한 뒤, 그 결과 파일을 object storage에 저장하는 역할입니다. 특별히 다른 의미라기보다는, 스트리밍 최적화를 위한 인코딩/변환 서비스로 보시면 됩니다. 그부분은 구두로 설명하거나 생략을 해도 무방하다고 고려되었으나, 추후에 다시 업데이트가 필요한 부분인 것 같습니다.감사합니다.
- 0
- 1
- 50
질문&답변
[위치 이름 기반으로 호텔을 조회하는 메서드] 코드 질문 드립니다.
안녕하세요 :) 질문 정말 좋습니다.1) Hotel ↔ Location 서로 참조 관계에 대해결론부터 말씀드리면 둘 다 가능하지만, 실무에서는 보통 “단방향”을 더 많이 선택합니다.Location이 “호텔을 위해 만들어진 종속 모델”이라면말씀하신 것처럼 Location → Hotel 단방향도 논리적으로 말이 됩니다.다만 Booking 같은 도메인에서는 Location이 특정 Hotel만을 위해 존재한다기보다는“주소/도시/지역” 같은 공통 개념(값 객체/별도 엔티티) 로 보는 경우가 많아서,보통은 Hotel이 locationId(또는 Location)를 참조하는 단방향이 더 흔합니다.강의에서 양쪽 참조처럼 보이게 둔 건, 관계를 직관적으로 보여주기 위한 교육용 표현이었고,실무에서는 한쪽만 참조 + 조회는 별도 계층에서 처리하는 쪽이 유지보수성이 좋습니다.2) 위치 기반 호텔 조회 메서드는 어디에 있어야 하나?이 부분도 아주 좋은 질문이에요.findHotelsByLocationName() 같은 기능은Location “자기 자신”의 행위라기보다는 데이터 조회(Query) 성격이 강합니다.그래서 OOD 관점에서는 보통Location 엔티티 안에 넣기보다는HotelRepository / SearchService / AvailabilityService 같은 조회 전용 계층에 두는 게 더 자연스럽습니다.이유는 간단합니다.조회 로직에는 보통 인덱스/DB 조인/캐시/검색엔진 같은 인프라 최적화가 붙고,그걸 Location 엔티티에 넣으면 오히려 엔티티가 “도메인 모델”이 아니라 “DB 접근 객체”처럼 변해버리는 문제가 생깁니다.즉,Location: 값/정보 모델로 단순하게 유지조회: Service/Repository에서 처리이 구조가 가장 깔끔하다고 할 수 있습니다.3) bruteforce 탐색은 의도된 baseline 예시입니다네, 질문하신 것처럼 강의의 전체 탐색 로직은 일단 동작하는 baseline(개념 검증용) 입니다.좋은 피드백이에요. Object Oriented Design 설계 강의 이기 때문에 이 강의 단계에서는코어 로직에 대한 최적화는 포함되지 않았습니다. 현재 오픈소스 강의 개선작업중이기 때문에이 작업이 완료되면 OOD 강의 또한 주신 피드백을 반영해서 업데이트 될 예정입니다.피드백 감사합니다.4) 최적화 방향최적화 방법들은 다음 시스템 디자인 강의 섹션에서 배우실 수 있습니다.질문 주신 “조인/인덱싱/2-step 조회”가 실무에서 가장 흔한 방식입니다.대표적인 최적화는 아래처럼 단계적으로 갑니다.가장 정석: DB 인덱스 + 조인Location(name) 인덱스Hotel(location_id) 인덱스WHERE location.name = ? 로 조인해서 바로 조회2-step 조회locationName -> locationIdlocationId -> hotels 조회High Availability - 캐시/역인덱스Redis에 locationName -> hotelIds 저장상세는 hotelId로 조회검색 요구가 커지면 Search 분리자동완성/오타/동의어/필터까지 붙으면OpenSearch/Elasticsearch로 분리하는 게 일반적입니다.질문 감사합니다. 다른 질문 있으시면 언제든지 남겨주세요!좋은 하루 되세요!
- 0
- 2
- 34
질문&답변
특별 학습 자료 프로모션 1년 멤버십 무료 제공 지원 확인 방법
https://forms.gle/diKHUhvUe61JwzXF7이 구글 폼을 통해 수강 닉네임과 substack 계정 이름 또는 이메일을 입력해주시면 구매자 검토후유료 멤버십을 1년간 무료로 제공해드립니다 감사합니다
- 0
- 2
- 46
질문&답변
14강. 영화 DVD 대여 시스템 데이터베이스 스키마 설계에서 Inventory 테이블 질문있습니다.
안녕하세요. 3831568님,쉽지 않은 생각과 사고로 질문해주신 부분 대단하신 것 같습니다.너무 좋은 질문 해주셔서 감사합니다.제가 방금 캐나다 벤쿠버에서 오는 바람에 늦게 답을 하게 되었습니다.먼저 분리하는 게 좋다고만 말씀드린 부분 설명부족에 대해 동의하면서 개선할 부분으로메모를 해두겠습니다. 피드백 감사합니다.질문해주신 부분에 대해 의견을 드려보자면, Inventory 테이블로 분리하는 것입니다. DVD 가 한 타이틀의 재고가 10만건이든, 10건이든, Items 테이블은 그 타이틀 하나당 딱 한 행입니다.재고가 초당 수백번 차감되거나 복구된다면 그 한 행에 WRITE lock 이 계속 걸리고 동시에 관리자가이 영화 설명 좀 수정하기를 원한다면, 그 행을 기다려야 합니다. 그래서 정적 메타데이터 테이블 Movies, Books, Games 등과 같이 구성되고 Inventory 테이블을 movie_id (FK)store_id / location_id (옵션)status (‘available’, ‘rented’, ‘lost’ 등)available_copies (또는 개별 copy를 한 행씩 관리)이렇게 하면재고 차감 → Inventory 행만 UPDATE (핫스팟은 여전히 있지만 메타데이터 행은 안 건드림)관리자가 영화 설명 수정 → Movies 행만 UPDATE (재고 트래픽과 완전 분리)따라서, 분리하는 것을 권장드립니다.두번째는유형별 재고 관리 정책인데 초기에는 모든 아이템이 그냥 수량만 있다면 OK 될 수 있습니다.예를 들어, Inventory { item_id, available_count } 이렇게 구성되는 것입니다.하지만 나중에 요구사항이 생기게 되면 확장이 필요합니다.유형별로 요구사항은 아래와 같을 것 입니다.DVD/블루레이 → 만료일 없음식품 → 유통기한 필요콘서트 티켓 → 좌석 번호, 구역 필요전자책 → 만료일 + 동시 대여 수 제한 필요NFT 렌탈 → 소유권 이전 로직 필요다양한 제한과 확장이 필요할 것입니다.그래서 아래와 같이 1번 초기부터 3번으로 점점 업그레이드 하는 것을 권장드릴 수 있을 것 같습니다.JSONB / JSON 컬럼으로 유연 속성 보관 (PostgreSQL, DynamoDB 등) – 초중반에 제일 많이 씀수직 분할 (Vertical Partitioning)공통: InventoryCommonDVD용: InventoryDVD (expires_at 등)Food용: InventoryFood (expiry_date, batch_no) → JOIN은 귀찮지만 타입 안정성 최고수평 분할 + Polymorphic Association (제가 제일 추천하는 최종 진화형) Inventory { id, item_id, item_type, available_count, reserved_count, … }별도 확장 테이블들 → item_type이 ‘dvd’면 InventoryDVD 테이블 조인 → item_type이 ‘ticket’면 InventoryTicket 테이블 조인 (Uber는 결제 수단, Netflix는 콘텐츠별 권한 이렇게 사용될 수 있습니다.)초기엔 JSONB로 한 다음, 특정 아이템 유형이 너무 복잡해지면 그때 3번으로 분리합니다.그리고 말씀하신 트래픽이 정말 많아지면 available_count 차감은 결국 Redis / DynamoDB 같은 분산 카운터로 옮기고, DB는 이벤트 소싱이나 사가 패턴으로 최종 일관성만 맞춥니다. (넷플릭스 DVD 재고, 아마존 재고 모두 이렇게 구성될 수 있습니다.)감사합니다.좋은 하루 되세요!
- 0
- 2
- 73
질문&답변
Matching Service의 MQ 필요성, Cassandra의 필요성, Cassandara - RDB 동기화
안녕하세요. 한재현님,먼저 수강해주셔서 감사드리며 좋은 질문을 해주셔서 기쁘네요 Matching Service의 MQ와 /swipe의 matching 응답값 강의에서는 REST API는 지연이 발생할 수 있으므로 MQ를 사용했다고 말씀하셨습니다. 이때 API 명세에 있는 matching 값의 해석이 헷갈립니다. matching은 swipe 시점에서 자신이 상대와 매칭되었는지 알 수 있는 값이라고 생각되는데, 그러면 동기 처리가 필요한 것 아닌가 생각이 듭니다. 즉 Cassandra에서 inverse swipe이 존재하는지를 확인한 뒤에야 API 응답을 보낼 수 있는 것 아닌가요? 강의에서는 /swipe는 빠르게 “접수”만 응답하고, 매칭 확정은 MQ 기반 비동기로 처리하는 것을 목표로 하였습니다. 좀 더 세부적으로 말씀 드리면, /swipe는 20–40ms 내에 “요청을 접수했다(accepted)”고만 돌려주고, 실제 매칭 확정은 MQ(Kafka/SQS)로 흘려 Matching Service가 비동기 처리합니다. 하지만 왜 굳이 비동기를 하였느냐인데, inverse swipe 를 동기로 처리하게 되면 Region 간의 지연 또는 hot partition 이 인기있는 사용자에게 발생할 수 있는 부분 그리고 스와이프는 초당 수십만건의 데이터 쓰기가 발생하는 점을 고려해서 병목, 즉 수십만 건의 쓰기의 부하에 취약할 수 있습니다. 이러한 운영에 안정된 파이프라인을 구성하였습니다. 따라서, /swipe 응답은 20–40ms 내에 accepted만 보장하고, 실제 매칭 여부는 Kafka/SQS로 전달된 이벤트를 Matching Service가 처리해 WebSocket/푸시로 최종 통지합니다.Cassandra의 필요성RDB 조회만으로 inverse swipe 여부를 파악할 수 있을 것 같습니다. 그러면 Cassandra는 캐싱 용도로 사용한 것이라고 보아야 하나요? 원래 설계에서 Cassandra가 자연스럽게 도입된 이유가 궁금합니다.Cassandra 의 경우는 inverse swipe 여부를 사실상 나에게 온 좋아요 리스트 즉, 인접리스트의 구간을 매주 자주 데이터를 읽어야 합니다. 그렇기 때문에 Cassandra 는 부하가 일어나는 swipe 를 싸게 받아서 파티션 키 = 사용자를 기준으로 최근 범위의 데이터 읽기를 빠르게 제공합니다. 물론 RDB 로도 불가능하지 않지만, 대규모에서 샤딩과 인덱스 또는 Race condition 과 같은 비용이 커져 총 비용과 지연이 급증할 수 있습니다. 결국 데이터 접근은 단일 파티션의 최근 범위가 되기 때문에 Cassandra 에 좀 더 적합하다고 할 수 있습니다. 좋은 질문을 해주셨습니다. Cassandra - RDB 동기화 여부swipe 기록을 RDB와 Cassandra에도 모두 저장할 때, 일시적 오류 등으로 한쪽에만 저장될 수도 있을 것 같은데, 이런 상황에 대비해 RDB와 Cassandra 간 동기화가 필요한지 궁금합니다.한쪽만 저장되는 것처럼 보이는 상황은 대부분 Consumer 의 지연 또는 일시적인 실패이기 때문에 재시도로 복구 될 수 있습니다. 별도의 양방향 동기화 트랜잭션은 권장되지 않습니다. 오히려 장애가 일어나는 범위가 늘어나는 것이라 권장되지 않습니다. 훌륭한 질문을 해주셨습니다. 감사합니다. 좋은 하루되세요!
- 0
- 2
- 72
질문&답변
Imgur 이미지 호스팅 서비스 질문
안녕하세요. 장준혁님,먼저 수강해주셔서 감사의 말씀 드립니다.아주 좋은 질문을 해주셔서 기분이 좋아지는 하루입니다. PreSigned URL 을 발급 한 후 클라이언트에서 직접 direct 로 blob storage 즉, AWS S3 를 예시로 들어 해당 blob storage 로 업로드 됩니다. 그 과정에서 청크의 진행상황을 탐지하고 이 진행상황을 key-value storage 즉 nosql 데이터베이스에 업데이트 하는 시스템 구조가 궁금하신 것으로 이해하였습니다. 여기서 클라이언트가 직접 direct 로 AWS S3 에 pre-signed url 로 업로드를 하게 되는데 이 과정에서 Multipart upload api 를 사용하여야 청크가 분할되어 s3 에 업로드 되게 됩니다. 그 후에 Key-value storage 에는 아래와 같이 저장을 합니다. { "id": "ul_xxx", "userId": "u1", "key": "uploads/2025/10/img.png", "uploadId": "XYZ", "partSize": 8388608, "status": "INITIATED", "totalBytes": 123456789, // 알면 저장 "bytesUploaded": 0, "partsDone": [], // [{partNumber, etag, size}] "expiresAt": "...", "lastHeartbeatAt": "..." }그리고나서 클라이언트는 파일을 청크로 분할 해서 s3 에 직접 업로드를 하게 되고 전송된 바이트를 시스템의 목적에 따라 WS(웹소켓)/SSE/HTTP 로 주기적으로 업데이트를 합니다. 각 파트가 업로드 되면 응답헤더의 ETag 를 읽어서 "partsDone": [], // [{partNumber, etag, size}] 에 업데이트해서 bytesUploaded를 갱신하여 근사 % 계산 하는 방식으로 시스템을 설계할 수 있습니다. 그리고 나서 s3 버킷의 Event Notification (SQS, SNS, Lambda) 을 수신해서 status 를 완료 처리하고 후속작업을 할 수 있습니다. 후속작업은 예시로 썸네일, 리사이즈 등이 있습니다. 하지만, 폴링 polling 방식은 폴링은 비용,지연만 늘리고 정확도는 낮아서 권장되지 않습니다. 추가적으로 네트워크 끊김 시 uploadId로 ListParts 조회해서 미완료 청크 부터 재시도 할 수 있습니다. 감사합니다. 좋은 하루 되세요!
- 0
- 2
- 66
질문&답변
쿠폰 문의
안녕하세요 nameunskadms 님, 새로운 쿠폰을 발급해드렸습니다. https://inf.run/1D24g감사합니다.
- 0
- 1
- 73
질문&답변
Redis 랜덤 값 추가 시 메타데이터 저장
안녕하세요 강토토님,좋은 질문을 해주셨습니다.Redis는 내부적으로 각 키에 대한 메타데이터(예: 데이터 타입, 만료 시간, 메모리 위치 등)를 자동으로 관리합니다. 이 메타데이터는 Redis 내부의 in-memory 데이터 구조에 저장되며, 사용자가 별도로 Map이나 딕셔너리 형태로 외부에서 관리해줄 필요는 없습니다. 예를 들어, Redis는 해시 테이블 기반의 dict 구조를 통해 키-값을 저장하고 탐색할 수 있도록 설계되어 있어서 O(1) 시간 복잡도로 키 탐색이 가능합니다. 이 dict 자체가 Redis 내부의 메타데이터를 포함하는 구조이며, Redis가 이를 바탕으로 빠르게 키를 찾을 수 있게 해줍니다. 즉, 질문하신 “메타데이터를 programmatically하게 Map이나 딕셔너리에 저장하는 의미냐”는 질문은 아니오에 가깝고, Redis가 이미 내부적으로 이런 메타데이터 구조를 포함하고 있기 때문에, 사용자가 따로 관리할 필요는 없습니다.감사합니다
- 0
- 1
- 72





