본문으로 건너뛰기

버그 제보

이상한 점을 알려 주시면 고칠게요. 지금 보고 있는 페이지와 브라우저 정보가 함께 담겨요.

페이지:

Algorithm

현실 시스템을 움직이는 알고리즘과 자료구조

추가
목차5개 항목
출처와 참고

ByteByteGo의 System Design 101 가이드 「10 Key Data Structures We Use Every Day」, 「Algorithms for System Design Interviews」, 「The 9 Algorithms That Dominate Our World」, 「How to Avoid Crawling Duplicate URLs at Google Scale?」를 바탕으로 재구성한 노트다. 블룸 필터의 거짓 음성이 없는 이유와 거짓 양성률 식은 fru1tworld/cs-basic 모의 면접 질문 목록의 「자료구조」 질문이 묻는 개념으로 보강했다.

알고리즘 공부는 구현에 치우치기 쉽다. 시스템을 설계할 때는 「이 알고리즘이 실제 시스템의 어느 문제를 푸는가」를 아는 것이 구현 세부보다 중요하다. 그래서 자료구조와 알고리즘을 쓰임새 중심으로 묶어 본다.

일상 속 자료구조

자료구조쓰이는 곳왜 그것인가
리스트SNS 피드순서대로 이어 붙이고 훑는다
배열수학 연산, 이미지 픽셀인덱스로 즉시 접근, 메모리에 연속 배치
스택편집기의 실행 취소·다시 실행마지막에 한 것을 먼저 되돌린다(스택)
큐프린터 작업, 게임의 사용자 입력 전송들어온 순서대로 처리한다(큐와 덱)
해시 테이블캐시 시스템키로 평균 O(1) 조회
힙작업 스케줄링우선순위가 가장 높은 것을 빨리 꺼낸다(힙과 우선순위 큐)
트리HTML 문서(DOM), AI의 결정 트리계층 구조를 표현한다(트리와 이진 탐색 트리)
접미사 트리문서 안 문자열 검색모든 접미사를 미리 색인해 부분 문자열을 빠르게 찾는다
그래프친구 관계, 길 찾기관계와 연결을 표현한다(그래프의 기본)
R-트리가까운 장소 찾기공간을 겹치는 사각형으로 나눠 위치 범위 질의를 빠르게 한다
버텍스 버퍼GPU 렌더링정점 데이터를 GPU 메모리에 한 번에 보낸다

기초 자료구조의 구현은 기초 자료구조에 있다.

시스템 설계에 자주 나오는 알고리즘

알고리즘·자료구조푸는 문제쓰이는 곳
일관된 해싱(Consistent Hashing)노드가 늘거나 줄 때 다시 옮길 키를 최소화한다분산 캐시, 샤딩, 로드 밸런서(데이터베이스 샤딩)
지오해시(Geohash)·쿼드트리(Quadtree)2차원 위치를 인덱싱해 "근처에 무엇이 있나"를 빨리 답한다주변 가게 찾기, 차량 호출
블룸 필터(Bloom Filter)원소가 집합에 "확실히 없다"를 적은 메모리로 판정한다크롤러의 중복 URL, DB의 불필요한 디스크 읽기 줄이기
HyperLogLog고유 원소 개수를 아주 적은 메모리로 근사한다고유 방문자 수 집계(Redis)
Count-Min Sketch스트림에서 원소별 빈도를 근사한다실시간 인기 검색어, 상위 K개
토큰 버킷·누출 버킷요청 속도를 제한한다API 속도 제한(rate limiting)
트라이(Trie)접두사로 문자열을 찾는다검색어 자동 완성(기초 자료구조)
머클 트리(Merkle Tree)두 데이터 집합에서 다른 부분만 빨리 찾는다복제본 동기화, Git, 블록체인
Raft·Paxos여러 노드가 하나의 값에 합의한다리더 선출, 분산 설정 저장소(etcd, ZooKeeper)
운영 변환(OT)·CRDT동시에 일어난 편집을 충돌 없이 합친다공동 문서 편집
증분 동기화(rsync)바뀐 블록만 보내 파일을 맞춘다파일 동기화·백업

이 중 일관된 해싱, 블룸 필터, 지오해시·쿼드트리처럼 여러 설계 문제에 반복해서 나오는 것을 먼저 이해한다. 합의 알고리즘이나 CRDT는 선임 수준에서 원리를 알아 두면 된다.

블룸 필터: 중복 URL 걸러 내기

웹 크롤러는 수십억 개의 URL 중 이미 본 것을 다시 넣지 않아야 한다. 선택지는 셋이다.

방법장점단점
메모리의 집합(Set)빠르고 정확하다URL 전체를 저장해 메모리가 감당이 안 된다
DB에 저장하고 조회정확하다조회마다 DB 부하가 크다
블룸 필터비트 배열만 써서 메모리가 매우 적고 빠르다가끔 "있다"고 잘못 답한다
flowchart LR
  M["비트 배열(크기 m)<br>0 0 0 0 0 0 0 0 0 0 0 0"]
  subgraph ADD["추가"]
    U1["url1"] --> H1["해시 A, B, C"] --> P1["위치 1, 5, 9를 1로"]
    U2["url2"] --> H2["해시 A, B, C"] --> P2["위치 3, 5, 11을 1로<br>(5는 겹친다)"]
  end
  subgraph GET["조회"]
    U3["url3"] --> H3["해시 A, B, C"] --> P3["위치 1, 3, 5"] -- "세 칸 모두 1" --> R3["#quot;아마 있다#quot;<br>실제로는 없다(거짓 양성)"]
    U4["url4"] --> P4["위치 2, 5, 9"] -- "2가 0" --> R4["#quot;확실히 없다#quot;"]
  end
  • 거짓 음성은 없고 거짓 양성만 있다. 비트는 0에서 1로 세우기만 하고 되돌리지 않으므로, 한 번 넣은 원소의 k칸은 언제까지나 1이다. 그래서 "없다"(어느 한 칸이 0)는 답은 항상 맞다. 반대로 "있다"는 다른 원소들이 세운 비트가 우연히 k칸을 모두 덮었을 때도 나오므로 틀릴 수 있다. 크롤러가 새 URL을 가끔 놓치는 것은 감수할 수 있으므로 잘 맞는다.
  • 거짓 양성률은 비트 배열 크기 m, 해시 함수 개수 k, 넣은 원소 수 n으로 정해진다. 근사식은 p ≈ (1 - e^(-kn/m))^k이고, 가장 낮아지는 k는 (m/n)·ln 2다. 이때 원소당 약 9.6비트면 1%, 14.4비트면 0.1%다. 원소가 기대보다 많이 들어오면 비율이 급격히 나빠지므로 기대 원소 수에 맞춰 크기를 미리 잡는다.
  • 해시 함수는 고르게 퍼지고 빨라야 한다. 암호 해시 대신 MurmurHash, xxHash 같은 비암호 해시를 쓴다.
  • 기본 블룸 필터는 원소를 지울 수 없다. 지우려고 비트를 0으로 되돌리면 그 비트를 함께 쓰던 다른 원소가 "없다"로 나와 거짓 음성이 생긴다. 삭제가 필요하면 칸마다 비트 대신 카운터를 두는 카운팅 블룸 필터나 쿠쿠 필터를 쓴다.

크롤러 전체 설계에서 블룸 필터가 놓이는 자리는 대규모 웹 크롤러 설계에 있다.

세상을 움직이는 아홉 가지 알고리즘

검색 엔진, SNS, Wi-Fi, 휴대폰, 위성까지 일상 기술 밑에는 다음 알고리즘이 있다.

알고리즘하는 일쓰이는 곳
정렬데이터를 순서대로 놓는다검색 결과, 데이터베이스, 거의 모든 곳(병합 정렬과 퀵 정렬)
다익스트라그래프에서 최단 경로를 찾는다지도 길 찾기, 네트워크 라우팅(다익스트라 최단 경로)
트랜스포머어텐션으로 시퀀스의 관계를 학습한다대규모 언어 모델, 번역
링크 분석(PageRank)링크 구조로 페이지의 중요도를 매긴다검색 순위
RSA공개키로 암호화하고 개인키로 푼다HTTPS 키 교환·서명(인코딩·암호화·해시)
정수 인수분해큰 수를 소인수로 나눈다. 어렵다는 사실 자체가 RSA의 안전 근거다암호학
합성곱 신경망(CNN)이미지의 지역 패턴을 학습한다이미지 인식, 얼굴 인식
허프만 부호화자주 나오는 기호에 짧은 부호를 준다압축(ZIP, JPEG, PNG의 일부 단계)
보안 해시(SHA)임의 데이터를 고정 길이 지문으로 만든다무결성 검사, 디지털 서명, Git, 블록체인

정리

  • 자료구조는 쓰임새로 기억한다. 실행 취소는 스택, 캐시는 해시 테이블, 스케줄링은 힙, 위치 검색은 R-트리다.
  • 대규모 시스템의 단골 알고리즘은 일관된 해싱, 지오해시·쿼드트리, 블룸 필터, 근사 집계(HyperLogLog, Count-Min Sketch), 속도 제한, 머클 트리, 합의다.
  • 블룸 필터는 "확실히 없다"를 싸게 판정한다. 거짓 양성을 감수할 수 있는 곳에 쓴다.
  • 설계에서는 구현보다 어떤 문제를 어떤 대가로 푸는지를 설명할 수 있어야 한다.

관련 노트: 기초 자료구조, 대규모 웹 크롤러 설계, 데이터베이스 샤딩, 시스템 설계의 선택지와 흔한 문제의 해법, 빅오 표기법과 시간 복잡도, 데이터 압축: 무손실과 손실, 실시간 트렌딩과 Top-K 집계

원본 기록5

댓글

GitHub 계정으로 댓글을 남길 수 있어요.