LabHub
배우기 러닝패스 코스

Apache Hadoop — 1つのPodにHDFSとYARNを立てて運用する

消したファイルを戻す二つの道 — ゴミ箱とスナップショット

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

한 줄 요약

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

概念マップ: 휴지통・스냅샷・사람의 손가락 실수・디렉터리의 과거 상태 자체

왜 두 길이 필요한가

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

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

어떻게 동작하나

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

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

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

스냅샷은 NameNode 가 붙잡는다

스냅샷 문서는 스냅샷을 파일 시스템의 읽기 전용 시점 사본이라고 정의한다. 사본이라는 말에 겁먹을 필요는 없다. 문서가 꼽는 구현의 성질이 핵심이다.

그러니 스냅샷은 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.xmldfs.namenode.snapshot.max.limit 기본값도 65536 이다. 그리고 스냅샷이 남아 있는 디렉터리는 지우거나 이름을 바꿀 수 없다. 스냅샷을 모두 지워야 한다.

두 길을 나란히 놓으면

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

현장에서 만나는 모습

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

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

셋째, 스냅샷 차이는 증분 복제의 재료다. DistCp 문서-diff-update 와 함께 쓰여, 두 스냅샷의 차이 보고서로 원본과 대상의 차이를 찾아 대상에 적용한다. 매번 전체를 훑지 않고 바뀐 것만 옮긴다.

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

실무에서 진짜 중요한 것

다음 실습에서 할 것

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