LabHub
배우기 러닝패스 코스

Apache Hadoop — HDFS 와 YARN 을 한 파드에 세우고 운영한다 · 스냅샷과 휴지통 · 이론

지운 파일을 되돌리는 두 길 — 휴지통과 스냅샷

LabHub 에서 이어서 보기

한 줄 요약

HDFS 에서 지운 것을 되돌리는 길은 둘이다. 휴지통은 셸이 지우는 대신 옮겨 두는 클라이언트 쪽 장치이고 기본으로 꺼져 있다. 스냅샷은 NameNode 가 디렉터리의 한 시점을 통째로 붙잡아 두는 장치라 -skipTrash 로 지운 것까지 되살린다. 대신 붙잡은 블록은 지워도 공간이 돌아오지 않는다.

개념 지도: 휴지통 · 스냅샷 · 사람의 손가락 실수 · 디렉터리의 과거 상태 자체

왜 두 길이 필요한가

분산 파일 시스템에서 실수는 크게 난다. 경로 하나를 잘못 친 rm -r 이 몇 TB 를 지우고, 잘못된 잡이 어제의 결과를 덮어쓴다. 로컬 디스크라면 백업에서 꺼내면 되지만 HDFS 의 데이터는 백업하기에 너무 큰 경우가 많다.

그래서 HDFS 는 성격이 다른 두 장치를 둔다. 하나는 사람의 손가락 실수를 겨냥한 가벼운 장치다. 셸로 지운 파일을 잠시 다른 곳에 보관한다. 다른 하나는 디렉터리의 과거 상태 자체를 남기는 장치다. 누가 어떤 길로 지우고 덮어썼든 그 시점으로 돌아갈 수 있다. 둘은 동작하는 곳도, 막아 주는 범위도, 치르는 값도 다르다.

어떻게 동작하나

먼저 휴지통이다. [설계 문서](https://hadoop.apache.org/docs/r3.5.0/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html)의 공간 회수 절은 휴지통 설정이 켜져 있으면 FS 셸로 지운 파일을 곧바로 지우지 않고 휴지통 디렉터리로 옮긴다고 설명한다. 사용자마다 /user/<이름>/.Trash 가 있고, 막 지운 파일은 .Trash/Current 아래에 원래 경로 그대로 들어간다. 정해진 간격마다 Current 를 날짜 이름의 체크포인트로 바꾸고, 수명이 지난 체크포인트는 지운다. 그때 비로소 NameNode 가 이름을 지우고 블록이 풀린다.

휴지통의 수명은 [core-default.xml](https://hadoop.apache.org/docs/r3.5.0/hadoop-project-dist/hadoop-common/core-default.xml) 의 fs.trash.interval 이고 단위는 분이다. 기본값은 0 이고 0 이면 휴지통이 꺼진다. 설치만 하고 설정을 건드리지 않은 클러스터에서 rm 은 즉시 삭제다. 이 코스의 실습 이미지는 이 값을 1440 분, 곧 하루로 켜 두었다. 이 값은 서버와 클라이언트 양쪽에 둘 수 있는데, 서버 쪽이 켜져 있으면 서버 값을 쓰고 클라이언트 값은 무시한다. 서버 쪽이 꺼져 있을 때만 클라이언트 설정을 본다.

여기서 이 장치의 성격이 드러난다. 휴지통은 지우는 대신 옮기는 것이고, 그 결정을 셸이 한다. [셸 문서](https://hadoop.apache.org/docs/r3.5.0/hadoop-project-dist/hadoop-common/FileSystemShell.html)의 rm 설명도 휴지통이 켜져 있으면 파일을 휴지통 디렉터리로 옮긴다고 적는다. 그러니 -skipTrash 를 주면 곧바로 지워지고, 셸을 거치지 않고 파일 시스템 API 로 직접 지우는 프로그램에는 이 안전망이 있다고 가정하지 않는 편이 안전하다. 덮어쓰기도 막지 못한다. 휴지통은 "지운 파일" 만 보관한다.

스냅샷은 NameNode 가 붙잡는다

[스냅샷 문서](https://hadoop.apache.org/docs/r3.5.0/hadoop-project-dist/hadoop-hdfs/HdfsSnapshots.html)는 스냅샷을 파일 시스템의 읽기 전용 시점 사본이라고 정의한다. 사본이라는 말에 겁먹을 필요는 없다. 문서가 꼽는 구현의 성질이 핵심이다.

그러니 스냅샷은 NameNode 의 메타데이터 장치다. 파일을 지워도 스냅샷이 그 블록 목록을 들고 있으므로 블록은 풀리지 않는다. 그래서 -skipTrash 로 지운 파일도 되살릴 수 있다.

hdfs dfsadmin -allowSnapshot /data/sales          # 관리자: 스냅샷을 허용hdfs dfs -createSnapshot /data/sales s1           # 소유자: 한 시점을 찍는다hdfs dfs -rm -skipTrash /data/sales/2026-09.csv   # 휴지통을 건너뛴 삭제hdfs dfs -cp -ptopax /data/sales/.snapshot/s1/2026-09.csv /data/sales/hdfs snapshotDiff /data/sales s1 .                # s1 과 지금의 차이

스냅샷은 .snapshot 이라는 예약된 경로 아래 이름으로 읽는다. 되살리기는 그 경로에서 복사하는 것이다. 문서의 예는 -ptopax 로 시각·소유자·권한·ACL·확장 속성을 함께 보존한다. snapshotDiff 는 두 스냅샷, 또는 스냅샷과 현재(.)의 차이를 +(생김) -(지워짐) M(바뀜) R(이름 바뀜)으로 보여 준다. 스냅샷 디렉터리 밖으로 옮긴 것은 지워진 것으로, 밖에서 들어온 것은 새로 생긴 것으로 나온다.

스냅샷 이름을 주지 않고 만들면 s20130412-151029.033 처럼 만든 시각으로 이름이 붙는다. 어떤 디렉터리가 스냅샷 가능한지는 hdfs lsSnapshottableDir 로, 한 디렉터리의 스냅샷 목록은 hdfs lsSnapshot 으로 본다. 규칙적으로 찍는다면 이름에 날짜를 넣어 두는 편이 보존 정책을 돌리기 쉽다.

제약도 분명하다. 스냅샷 허용은 슈퍼유저의 일이고, 만들기·지우기·이름 바꾸기는 그 디렉터리 소유자의 일이다. 스냅샷을 허용한 디렉터리의 조상이나 자손에는 다시 허용할 수 없다(중첩 금지). 디렉터리 하나에 동시에 둘 수 있는 스냅샷은 65,536 개이고, [hdfs-default.xml](https://hadoop.apache.org/docs/r3.5.0/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml) 의 dfs.namenode.snapshot.max.limit 기본값도 65536 이다. 그리고 스냅샷이 남아 있는 디렉터리는 지우거나 이름을 바꿀 수 없다. 스냅샷을 모두 지워야 한다.

두 길을 나란히 놓으면

| | 휴지통 | 스냅샷 |
|---|---|---|
| 어디서 | 클라이언트(셸)가 옮긴다 | NameNode 가 메타데이터로 붙잡는다 |
| 기본 상태 | 꺼짐(fs.trash.interval 0) | 디렉터리마다 허용해야 함 |
| 막는 것 | 셸로 지운 파일 | 지우기·덮어쓰기·이름 바꾸기 모두 |
| 못 막는 것 | -skipTrash, 덮어쓰기 | 스냅샷을 찍기 전의 변경 |
| 공간 | 수명이 지나면 풀린다 | 스냅샷을 지울 때까지 붙잡는다 |

현장에서 만나는 모습

첫째, 휴지통이 켜져 있는지부터 확인한다. 기본값이 0 이라 새로 만든 클러스터는 대개 꺼져 있다. rm 뒤에 "trash 로 옮겼다" 는 메시지가 없었다면 즉시 삭제였다.

둘째, 스냅샷은 공간을 붙잡는다. 지운 파일의 블록을 스냅샷이 들고 있으므로 지워도 여유 공간이 늘지 않는다. 셸 문서대로 count-x 를 주지 않으면 스냅샷 안의 것까지 센다. 오래된 스냅샷을 규칙적으로 지우는 보존 정책이 함께 있어야 한다.

셋째, 스냅샷 차이는 증분 복제의 재료다. [DistCp 문서](https://hadoop.apache.org/docs/r3.5.0/hadoop-distcp/DistCp.html)의 -diff-update 와 함께 쓰여, 두 스냅샷의 차이 보고서로 원본과 대상의 차이를 찾아 대상에 적용한다. 매번 전체를 훑지 않고 바뀐 것만 옮긴다.

넷째, 스냅샷을 찍어 둔 디렉터리는 정리할 때 막힌다. 프로젝트를 끝내고 디렉터리를 지우려는데 실패하면 남은 스냅샷을 먼저 본다.

실무에서 진짜 중요한 것

다음 실습에서 할 것

디렉터리에 스냅샷을 허용하고 첫 스냅샷을 찍은 뒤, 평범한 rm 으로 지운 파일이 휴지통으로 가는 것(이 실습 이미지는 휴지통을 하루로 켜 두었다)과 휴지통을 건너뛰어 지운 파일을 스냅샷에서 복사해 되살리는 것을 차례로 해 본다. 파일 끝에 줄을 덧붙이고 두 번째 스냅샷을 찍어 snapshotDiff 로 무엇이 바뀌었는지 읽는다. 스냅샷이 남아 있는 디렉터리를 통째로 지우려다 거절되는 것을 확인하고, 두 번째 스냅샷의 이름을 바꿔 본 뒤 휴지통과 스냅샷의 차이를 보고서로 정리한다.