LabHub
배우기 러닝패스 코스

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

LabHub 에서 이어서 보기

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

목표

디렉터리에 이름 쿼터와 공간 쿼터를 걸고, 이름 쿼터가 디렉터리 자신까지 센다는 것과 공간 쿼터가 블록 크기 × 복제 계수만큼 미리 예약한다는 것을 거절 메시지로 확인한다. 블록 크기를 줄여 같은 파일을 들여보내고, 쿼터가 옮기기(mv)까지 막는다는 것도 본다.

왜 중요한가

여러 팀이 한 HDFS 를 나눠 쓰면 한 팀의 실수(무한히 파일을 만드는 잡, 작은 파일 수백만 개)가 NameNode 의 힙과 디스크를 모두의 것에서 빼앗는다. 쿼터는 그 피해를 디렉터리 하나에 가두는 장치다. 이름 쿼터는 파일과 디렉터리의 개수를, 공간 쿼터는 복제본까지 포함한 바이트를 제한한다. 공간 쿼터에는 함정이 하나 있다. 파일을 쓰기 시작할 때 NameNode 는 아직 몇 바이트를 쓸지 모르므로 블록 하나를 통째로(블록 크기 × 복제 계수) 예약한다. 그래서 남은 쿼터가 128MB 보다 작으면 1바이트 파일도 들어가지 못한다. 쓰기가 끝나면 실제 크기로 정산되지만, 시작조차 못 하면 소용없다. 운영에서 "쿼터가 남았는데 왜 못 쓰냐" 는 문의의 대부분이 이것이다. 쿼터는 새 이름이 생기는 모든 일에 걸린다. 다른 디렉터리에서 옮겨 오는 것도 그 디렉터리 입장에서는 새 이름이다.

단계

  1. HDFS /quota/team-a 를 만들고 이름 쿼터 10 을 거세요(hdfs dfsadmin -setQuota).
  2. 작은 로컬 파일을 하나씩 team-a 에 올려 거절될 때까지 채우고, 거절된 put 의 오류 출력을 /root/hdp/quota/quota_err.txt 에 저장하세요.
  3. /quota/team-b 를 만들고 공간 쿼터 30MB 를 거세요(hdfs dfsadmin -setSpaceQuota 30m).
  4. 1바이트짜리 로컬 파일 /root/hdp/quota/one.txt 를 만들어 /quota/team-b/one.txt 로 올려 보고, 오류 출력을 /root/hdp/quota/space_err.txt 에 저장하세요.
  5. 같은 파일을 블록 크기 1MiB(-D dfs.blocksize=1048576)로 /quota/team-b/one-1m.txt 에 올리세요.
  6. hdfs dfs -count -q -v /quota/team-a /quota/team-b 출력을 /root/hdp/quota/count.txt 에 저장하세요.
  7. /quota/staging 을 만들어 파일 하나(/quota/staging/f.txt)를 올린 뒤, 그것을 team-a 로 -mv 해 보고 오류 출력을 /root/hdp/quota/mv_err.txt 에 저장하세요.
  8. /root/hdp/quota/report.md## 이름 쿼터 ## 공간 쿼터 ## 쿼터가 막는 것 세 절을 쓰세요. 첫 절에 team-a 에 실제로 들어간 파일 수를, 둘째 절에 예약하려던 바이트 수(134217728)를 넣으세요.

참고

이름 쿼터 걸기

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.txthdfs 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바이트도 못 써요?' 라는 문의에 답한다고 생각하고 쓰세요.