"'이게 어느 영상?', '바뀌었나?', '정확히 이 바이트야?' 는 세 질문이야. 답도 셋이 필요해."
'그 파일' 뒤에 숨은 세 질문
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 하나가 이력의 실을 쥐고, 나머지가 그 위에서 재료가 바뀐 걸 감지해. 이 일들은 서로 다른 손에 맡겨.