Apache Hadoop — Stand up and run HDFS and YARN in one pod
Reproduce why a 1-byte file is blocked by a 30 MB quota
한국어 원문으로 표시합니다.
목표
디렉터리에 이름 쿼터와 공간 쿼터를 걸고, 이름 쿼터가 디렉터리 자신까지 센다는 것과 공간 쿼터가 블록 크기 × 복제 계수만큼 미리 예약한다는 것을 거절 메시지로 확인한다. 블록 크기를 줄여 같은 파일을 들여보내고, 쿼터가 옮기기(mv)까지 막는다는 것도 본다.
왜 중요한가
여러 팀이 한 HDFS 를 나눠 쓰면 한 팀의 실수(무한히 파일을 만드는 잡, 작은 파일 수백만 개)가 NameNode 의 힙과 디스크를 모두의 것에서 빼앗는다. 쿼터는 그 피해를 디렉터리 하나에 가두는 장치다. 이름 쿼터는 파일과 디렉터리의 개수를, 공간 쿼터는 복제본까지 포함한 바이트를 제한한다. 공간 쿼터에는 함정이 하나 있다. 파일을 쓰기 시작할 때 NameNode 는 아직 몇 바이트를 쓸지 모르므로 블록 하나를 통째로(블록 크기 × 복제 계수) 예약한다. 그래서 남은 쿼터가 128MB 보다 작으면 1바이트 파일도 들어가지 못한다. 쓰기가 끝나면 실제 크기로 정산되지만, 시작조차 못 하면 소용없다. 운영에서 "쿼터가 남았는데 왜 못 쓰냐" 는 문의의 대부분이 이것이다. 쿼터는 새 이름이 생기는 모든 일에 걸린다. 다른 디렉터리에서 옮겨 오는 것도 그 디렉터리 입장에서는 새 이름이다.
단계
- HDFS /quota/team-a 를 만들고 이름 쿼터 10 을 거세요(
hdfs dfsadmin -setQuota). - 작은 로컬 파일을 하나씩 team-a 에 올려 거절될 때까지 채우고, 거절된
put의 오류 출력을 /root/hdp/quota/quota_err.txt 에 저장하세요. - /quota/team-b 를 만들고 공간 쿼터 30MB 를 거세요(
hdfs dfsadmin -setSpaceQuota 30m). - 1바이트짜리 로컬 파일 /root/hdp/quota/one.txt 를 만들어 /quota/team-b/one.txt 로 올려 보고, 오류 출력을 /root/hdp/quota/space_err.txt 에 저장하세요.
- 같은 파일을 블록 크기 1MiB(
-D dfs.blocksize=1048576)로 /quota/team-b/one-1m.txt 에 올리세요. hdfs dfs -count -q -v /quota/team-a /quota/team-b출력을 /root/hdp/quota/count.txt 에 저장하세요.- /quota/staging 을 만들어 파일 하나(/quota/staging/f.txt)를 올린 뒤, 그것을 team-a 로
-mv해 보고 오류 출력을 /root/hdp/quota/mv_err.txt 에 저장하세요. - /root/hdp/quota/report.md 에
## 이름 쿼터## 공간 쿼터## 쿼터가 막는 것세 절을 쓰세요. 첫 절에 team-a 에 실제로 들어간 파일 수를, 둘째 절에 예약하려던 바이트 수(134217728)를 넣으세요.
참고
- 쿼터를 거는 것은 관리자 명령(
hdfs dfsadmin)이고 슈퍼유저만 할 수 있습니다. 이 파드에서는 root 입니다. - 공간 쿼터의 단위는 바이트이고
30m·1g같은 접미사를 쓸 수 있습니다. 복제본도 셉니다 — 복제 계수 3 이면 1MB 파일이 3MB 를 씁니다. -count -q의 칸: QUOTA · REM_QUOTA · SPACE_QUOTA · REM_SPACE_QUOTA · DIR_COUNT · FILE_COUNT · CONTENT_SIZE · PATHNAME.- 흔한 실수: 이름 쿼터 10 이면 파일 10개가 들어간다고 여기는 것, 공간 쿼터의 남은 양만 보고 쓸 수 있다고 판단하는 것.
- 공식 문서: HDFS Quotas Guide · HDFS Commands — dfsadmin · FileSystem Shell — count · WebHDFS — Get Content Summary
이름 쿼터 걸기
HDFS /quota/team-a 를 만들고 hdfs dfsadmin -setQuota 10 /quota/team-a 로 이름 쿼터 10 을 거세요.
이름 쿼터는 그 디렉터리 아래(자신 포함)의 파일과 디렉터리 개수 상한입니다. 걸린 값은 hdfs dfs -count -q 의 첫 칸에서 봅니다.
10 인데 몇 개가 들어가나
작은 로컬 파일을 여러 개 만들어 하나씩 hdfs dfs -put 으로 /quota/team-a/ 에 올리다가, 거절된 put 의 오류 출력(표준 오류)을 /root/hdp/quota/quota_err.txt 에 저장하세요.
디렉터리 자신도 이름 하나로 셉니다. 그래서 파일은 쿼터보다 하나 적게 들어갑니다. 거절 메시지에 쿼터와 '넣으려던 뒤의 개수' 가 함께 찍힙니다.
공간 쿼터 걸기
HDFS /quota/team-b 를 만들고 hdfs dfsadmin -setSpaceQuota 30m /quota/team-b 로 공간 쿼터 30MB 를 거세요.
30m 은 30 × 1024 × 1024 바이트입니다. 공간 쿼터는 복제본까지 센 실제 디스크 사용량의 상한입니다.
1바이트가 막힌다
1바이트짜리 로컬 파일 /root/hdp/quota/one.txt 를 만들고(printf x > /root/hdp/quota/one.txt) hdfs dfs -put 으로 /quota/team-b/one.txt 에 올려 보세요. 오류 출력을 /root/hdp/quota/space_err.txt 에 저장하세요.
쓰기를 시작하는 순간 NameNode 는 블록 하나(블록 크기 × 복제 계수)를 예약합니다. 기본 블록 크기 128MB 는 30MB 쿼터보다 큽니다. 메시지의 두 숫자 — 쿼터와 필요했던 공간 — 를 견줘 보세요.
블록을 작게 잡으면 들어간다
같은 /root/hdp/quota/one.txt 를 hdfs dfs -D dfs.blocksize=1048576 -put 으로 /quota/team-b/one-1m.txt 에 올리세요.
블록 크기가 1MiB 면 예약도 1MiB 입니다. 쓰기가 끝나면 사용량은 실제 크기(1바이트 × 복제 계수)로 정산됩니다. -count -q 의 REM_SPACE_QUOTA 가 얼마나 줄었는지 보세요.
count -q 로 두 쿼터 읽기
hdfs dfs -count -q -v /quota/team-a /quota/team-b 출력을 /root/hdp/quota/count.txt 에 저장하세요.
쿼터가 없는 칸은 none/inf 로 찍힙니다. team-a 는 REM_QUOTA 가 0 이고, team-b 는 공간이 거의 그대로 남아 있습니다 — 거절은 '남은 양' 이 아니라 '예약할 양' 때문이었습니다.
옮기기도 쿼터에 걸린다
HDFS /quota/staging 을 만들어 파일 하나를 /quota/staging/f.txt 로 올린 뒤, hdfs dfs -mv /quota/staging/f.txt /quota/team-a/ 를 해 보고 오류 출력을 /root/hdp/quota/mv_err.txt 에 저장하세요.
옮기기는 바이트를 움직이지 않지만 team-a 입장에서는 이름이 하나 늘어납니다. 그래서 이름 쿼터가 거절하고, 파일은 staging 에 그대로 남습니다.
쿼터 문의에 답할 수 있게
/root/hdp/quota/report.md 에 ## 이름 쿼터 ## 공간 쿼터 ## 쿼터가 막는 것 세 절을 쓰세요. 첫 절에 team-a 에 실제로 들어간 파일 수를, 둘째 절에 4단계에서 예약하려던 바이트 수를 숫자로 넣으세요.
'쿼터 10 인데 왜 9개만 들어가요?', '30MB 가 남았는데 왜 1바이트도 못 써요?' 라는 문의에 답한다고 생각하고 쓰세요.