LabHub
배우기 러닝패스 코스

고객 데이터 다루기 · 다 못 올리는 파일 · 실습

노트북에서는 됐는데 파드에서 죽는다

LabHub 에서 이어서 보기

목표

큰 파일을 메모리에 올리지 않고 다루는 도구 stream.py 를 만들고, 메모리 상한을 걸어 그것이 정말로 스트리밍인지 종료 코드로 증명한다. 집계·상위 N·고유값 세기·외부 정렬·검증을 모두 손에 쥐는 것의 개수로 설계한다.

왜 중요한가

파일을 통째로 읽는 코드는 작은 파일에서 더 짧고 더 빠르다. 그래서 처음 쓸 때는 의심할 이유가 없고, 파일이 커지는 것은 우리가 아니라 고객이 결정한다. 컨테이너가 메모리 한도를 넘으면 커널이 프로세스를 죽이는데, 그 죽음은 파이썬 예외로 잡히지 않고 표준출력에도 아무것도 남지 않는다.
설계의 기준은 파일 크기가 아니라 어느 시점에도 손에 쥐고 있는 것의 개수다. 집계는 한 줄, 상위 N 건은 N 개면 된다. 그런데 고유값 세기는 스트리밍이어도 메모리가 값의 가짓수에 비례한다 — 이 차이를 모르면 "스트리밍으로 짰는데 왜 죽죠" 가 된다.
그리고 "돌려 봤더니 되던데요" 는 증명이 아니다. 그때 그 파일에서 됐다는 뜻일 뿐이다. 상한을 걸고 통과해야 증명이고, 그 결과는 문장이 아니라 종료 코드로 남아야 다음 사람이 다시 묻지 않는다.
채점기는 여러분의 문구를 믿지 않는다. 임시 디렉터리에 채점기가 만든 로그를 차려 놓고 여러분의 도구를 메모리 상한 아래에서 실제로 실행해 답을 대조한다. 건수와 금액은 실행마다 바뀐다.

단계

1. /root/stream/gen_events.py 를 만들어 실행해 /root/stream/data/events.csv 를 만드세요. 30만 줄입니다.
2. /root/stream/stream.pyagg <파일> 을 만들어 한 줄씩 읽어 건수·합계·평균·최소·최대를 내게 하세요.
3. top <파일> <N> 을 더해 힙으로 상위 N 건만 유지하게 하세요.
4. distinct <파일> <칼럼> 을 더해 고유값을 세고 그때의 최대 메모리를 함께 내게 한 뒤, 가짓수가 적은 칼럼과 많은 칼럼을 비교해 /root/stream/distinct.json 에 적으세요.
5. /root/stream/cap.py/root/stream/slurp.py 를 만들어 메모리 상한 64MiB 아래에서 두 판을 나란히 돌리고 결과를 /root/stream/limit.json 에 적으세요.
6. sortmerge <파일> <칼럼> <청크행수> 를 더해 분할·정렬·병합으로 외부 정렬하게 하세요.
7. verify <파일> <칼럼> 을 더해 정렬 여부와 순서에 무관한 지문을 내게 하고, 원본과 정렬본을 대조해 /root/stream/verify.json 에 적으세요.
8. 전체를 한 장으로 정리해 /root/stream/stream_report.json/root/stream/stream_report.md 를 만드세요.

참고

단계 8개

  1. 한 번에 못 읽는 파일 만들기
  2. 한 줄씩 읽어 집계하기
  3. 상위 N 건만 손에 쥐기
  4. 고유값 세기의 메모리는 어디에 비례하나
  5. 상한을 걸어 증명하기
  6. 분할·정렬·병합으로 외부 정렬하기
  7. 중간 산출물 없이 검증하기
  8. 증명을 한 장으로 남기기