C.W.K.
Stream
Lesson 02 of 04 · published

video vs fingerprint

~11 min · video-id, fingerprint, content-hash, cost-tiers

Level 0Empty Shelf
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"'이게 어느 영상?', '바뀌었나?', '정확히 이 바이트야?' 는 세 질문이야. 답도 셋이 필요해."

'그 파일' 뒤에 숨은 세 질문

Recall 이 영상 수천 개를 스캔할 때, '이게 전과 같은 파일이야?' 는 알고 보면 세 개의 다른 질문이고, 각각 다른 identity 와 — 결정적으로 — 각각 다른 비용이 필요해. 그걸 엉키게 하면 스캔이 못 견디게 느려지거나, 바뀐 영상이 안 바뀐 척하게 돼.

  • video_id = source 랑 상대 경로의 hash. 이건 안정된 논리적 identity — 슬롯이야. 2026/07/talk.mov 의 파일은 재-export 해서 교체해도 같은 video_id 를 유지해. '우리가 어느 영상 얘기하나?' 에 답하고, 모든 durable 행이 여기 매달려.
  • cheap_fingerprint = source, path, 크기, 수정 시각의 hash. 이건 변화를 감지해. 관찰된 바이트가 바뀌는 즉시 움직여 — 새 export 는 새 크기나 mtime 을 가져 — 근데 파일 내용을 안 읽고 계산해. '지난번 본 뒤로 바뀌었나?' 에 싸게 답해.
  • source_sha256 = 파일 내용 전체의 hash. 이건 정확하고, 비싸고, ground-truth 인 바이트의 identity 야. 모든 바이트를 읽어야 해서, Recall 은 job 이 실제 선택돼 돌 때까지 미뤄. '문자 그대로 같은 바이트야?' 에 확실히 답해.

왜 셋이고, 진짜 hash 만 아냐?

뻔한 순수주의 수는 '그냥 파일을 SHA-256 해 — 그게 진짜 identity 야' 야. 몇 기가짜리 4K 영상 아카이브에선 그게 시작부터 안 돼: 스캔마다 모든 파일의 모든 바이트를 hash 하면 인벤토리가 몇 시간 걸리고 네트워크 파일시스템을 두들겨. 그래서 Recall 은 identity 를 비용으로 계층화해. cheap fingerprint 는 스캔 중 변화 감지의 상시, 대용량 작업을 하고; 비싼 full hash 는 job 이 실제 건드리는 몇 개 영상에만 계산돼. 싼 비용은 항상, 비싼 비용은 중요할 때만 내.

이건 네가 이미 쓰는 도구 뒤의 바로 그 패턴이야. 동기화 프로토콜은 싼 신호(크기, 타임스탬프) 를 비교해 비싼 바이트 수준 작업을 할지 결정해. HTTP cache 는 싼 fingerprint 를 보내 서버가 전체 body 재전송 없이 '안 바뀜' 이라 말하게 해. 원리는 같아: 싼 identity 가 비싼 걸 gate 해. 변화는 싸고 상시 감지; identity 는 비싸고 드물게 확인.

슬롯을 그 내용과 분리하기

셋 중 가장 깊은 아이디어는 슬롯(video_id) 을 내용(fingerprint 와 full hash) 과 분리하는 거야. video_id 가 편집 너머로 안정적이니까, 논리적 영상의 모든 이력 — release, 교정, 요약 — 이 밑 파일이 재-export 돼도 붙어 있어. 그다음 fingerprint 랑 full hash 가 그 안정된 슬롯 밑의 내용이 움직인 걸 추적해서, Recall 이 이력을 잃거나 아무것도 안 바뀐 척하는 대신 '같은 영상, 새 바이트' 라고 말할 수 있어. identity 하나가 이력의 실을 쥐고; 다른 것들이 그 위 재료가 바뀐 걸 감지해. 그 일들을 다른 손에 둬.

Code

identity 셋, 비용 셋, 일 셋·python
import hashlib

# 1. 안정된 논리적 슬롯 — 싸고 상시. 이력이 여기 매달림.
video_id = sha256(f"{source_id}\x00{relative_path}")
#   같은 경로 재-export 를 살아남음 -> '이게 어느 영상?'

# 2. 변화 감지 — 싸고, 파일 안 읽음. 스캔마다 돎.
cheap_fingerprint = sha256(
    f"{source_id}\x00{relative_path}\x00{size_bytes}\x00{modified_ns}"
)
#   관찰 바이트가 움직이면 움직임 -> '바뀌었나?'

# 3. ground-truth 바이트 — 비쌈, 전체 파일 읽음.
#    선택된 job 이 실제 돌 때까지 미룸.
source_sha256 = sha256(open(path, 'rb').read())
#   정확한 바이트 identity -> '문자 그대로 같은 바이트야?'

# cheap fingerprint 가 비싼 full hash 를 gate 한다.

External links

Exercise

네 일에서 '진짜' identity 가 계산에 비싼 걸 찾아 — 큰 파일, 큰 데이터셋, 통째로 가져와야 할 외부 record. 변화 확인마다 비싼 identity 를 계산해, 아니면 싼 proxy 가 있어? 두-계층 방식을 설계해: 싼 변화-감지기(크기, 타임스탬프, 버전 태그) + 싼 게 변화를 신호하거나 job 이 실제 필요할 때만 계산되는 비싼 정확한 identity.
Hint
매 pass 마다 전부 재-hash/재-fetch 하거나(너무 느림) 타임스탬프만 콘텐츠인 양 믿는(안전하지 않음) 곳을 찾아. 균형 설계는 싼 신호로 귀찮을지 결정하고, 비싼 정확한 identity 로 확인해 — 그리고 논리적 슬롯엔 세 번째 안정 identity 를 둬 내용이 바뀌어도 이력이 살아남게.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.