안녕하세요.
|
개발자 심기영입니다.

thumbnail
음악 스트리밍 파이프라인 만들기 - 09. 번외, 로컬 Docker DB가 랜섬 공격당했다

어느 날 애플리케이션이 뜨지 않았다 M3 작업 중 bootRun 이 으로 실패했다. 어제까지 멀쩡했던 로컬 DB 다. 안에 들어가 보니: 데이터베이스 안에는 이런 내용이 있었다. All your data was backed up by us. You must pay 0.013 bitcoin to … or in 48 hours, your data will be publicly disclosed and deleted. 노출된 MySQL/MariaDB 를 스캔해서 약한 비밀번호로 로그인하고, DB 를 삭제한 뒤 랜섬 노트를 남기는 자동화 봇의 전형적인 수법이다. 뚫린 경로 거창한 취약점이 아니다. 조합이 문제였다. Docker 포트 매핑의 기본값은 모든 인터페이스()다. “로컬 개발용이니까”라고 쓴 root/root 와 만나는 순간, 네트워크에서 접근 가능한 무인 DB 가 된다. 공유기 NAT 뒤라고 안심할 수 없다 — IPv6 는 공인 주소가 직접 붙는 경우가 많고, 같은 네트워크의…

July 24, 2026
Music_Pipeline
음악 스트리밍 파이프라인 만들기 - 08. HLS 스트리밍, 온디맨드 패키징이 기각당한 이유

선택 모듈 — 오디오를 실제로 흘려보내기 메타데이터와 집계만 있던 파이프라인에 실제 재생 경로를 붙였다. 제약: 기존 코드 무변경 — 패키지와 테이블만 추가. 원본 음원은 ffmpeg 합성 사인파다. 저작권 문제가 없고, 길이를 와 정확히 일치시킬 수 있어 검증이 깨끗하며, 저장소엔 바이너리 대신 재현 방법을 버전관리한다. 트랙마다 주파수를 trackId 에서 유도해서 “다른 트랙인데 같은 소리” 같은 배선 오류를 귀로 잡을 수 있게 했다. HLS 구조 — RFC 8216 을 코드에 대응시키기 variant 인코딩·분할은 ffmpeg 에 맡기고 마스터 플레이리스트는 직접 썼다 — (비트레이트 + TS 오버헤드)와 (“mp4a.40.2” = AAC-LC)가 어디서 오는지 코드에 남는다. 플레이어는 이 두 값으로 다운로드 전에 variant 를 고른다. ABR 의 선택 근거가 마스터에 선언돼 있다는 게 HLS 구조의 핵심이다. 검증은 ffprobe 교차 검증 — 우리가 만든 산출…

July 24, 2026
Music_Pipeline
음악 스트리밍 파이프라인 만들기 - 07. N+1, 쿼리 수만 세면 fetch join에 속는다

문제를 일부러 만들다 이전 직장에서 N+1 로 60~90초 걸리던 조회를 개선한 경험이 있는데, MyBatis 환경이었다. JPA 환경에서 같은 문제를 재현하고 개선 전략을 수치로 비교하고 싶었다. 앨범 목록 API(앨범 + 대표 아티스트명 + 트랙 목록)를 만들었다. Album→Artist(ToOne), Album→Tracks(OneToMany) 모두 LAZY. 리포지토리는 하나 — 코드 어디에도 반복 조회가 없다. 그런데: 쿼리는 리포지토리가 아니라 DTO 변환 중(지연 로딩 접근)에 나간다. 이게 N+1 이 늦게 발견되는 이유다. MyBatis 는 resultMap 의 collection 쿼리가 XML 에 보이는데, JPA 는 한 줄이 조용히 SELECT 를 만든다. 그리고 응답은 완전히 정확하다 — N+1 은 틀린 결과가 아니라 느린 결과라서 기능 테스트로는 절대 안 잡힌다. 측정은 Hibernate Statistics()로 했다. “느린 것 같다”가 아니라 쿼리 수를 …

July 24, 2026
Music_Pipeline
음악 스트리밍 파이프라인 만들기 - 06. Redis 캐시와 스탬피드, 그리고 캐시가 무의미했던 순간

문제 집계 테이블 기반 “실시간 TOP 100 차트” API. 모든 사용자가 같은 것을 본다 — 전형적인 읽기 편중 + 핫키 하나 워크로드다. 결정이 세 겹이었다. 결정 1 — 차트를 어디서 만드나: Redis Sorted Set 기각 “Redis 차트면 ZINCRBY + ZREVRANGE 지” 싶었는데, 기각했다. 결정타는 멱등성이다. 컨슈머가 같은 배치를 재처리하면 DB 는 로 걸러내지만 ZINCRBY 는 그대로 두 번 더해진다. 04편에서 세운 멱등성 체계 밖에 비원자 이중 쓰기 경로를 만드는 구조다. Redis 에도 중복 판정을 만들면 되지만, 그건 같은 체계를 두 번 구현하는 것이다. DB 집계(TOP 100 쿼리) + 캐시로 갔다. 설계 결정은 독립적이지 않다 — 앞의 결정이 뒤의 선택지를 제약한다. 결정 2 — Look-aside Write-through 는 기각: 쓰기 주체(컨슈머, 초당 수백 건)와 읽기 주체(차트 API)가 달라서, 아무도 안 읽는 사이에도 집계…

July 24, 2026
Music_Pipeline