한도 안에서 컬렉션 색인하기

DockerBeginner
지금 연습하기

소개

Riverside 컬렉션에는 구술사 HTML 문서 여섯 개의 검색 가능한 색인이 필요합니다. 제공된 컨테이너 도구는 실제로 HTML을 해석하고 Unicode 단어를 세지만, 4-worker 배치는 160 MiB 메모리 한도를 초과합니다. 정확한 컨테이너에 연결된 증거로 실패를 진단한 다음 한도를 높이거나 문서를 제거하지 않고 완전한 색인을 만드세요.

기본 Docker run, 터미널 경로, 바인드 마운트의 목적을 알고 있어야 합니다. 이 실습은 메모리 옵션, 실제 사용자 ID, 따옴표 경로, 명령 치환, 작은 증거 읽기 파이프라인을 사용 전에 설명합니다. Python 프로그래밍, HTML 작성, 검색 알고리즘 구현은 필요하지 않습니다. Docker, 색인 이미지, 읽기 전용 Search Desk가 준비되어 있습니다.

코퍼스는 명시적으로 합성 자료입니다. 실제 파서의 메모리 압박을 관찰할 수 있도록 각 문서에 확장된 교육용 발췌문 10,000개가 들어 있습니다. 결과는 해당 바이트의 실제 색인이며 모의 할당이나 운영 용량 보장이 아닙니다. 읽기와 일반적인 실수를 포함해 약 60분을 예상하세요. 이는 저자의 예상 시간입니다.

한도 안에서 완전한 색인 만들기

이 단계에서는 정상적인 검색 결과를 확인하고, 메모리 제한 실패를 재현하며, 시스템이 직접 기록한 증거를 연결한 뒤 제한된 배치로 전체 컬렉션을 완성합니다.

작은 정상 색인 먼저 사용하기

Search Desk에서 Explore sample을 선택하세요. 별도로 준비된 이 샘플에는 작은 문서 두 개가 있습니다. Search one word와 Search로 café를 검색합니다. 두 레코드의 제목은 Riverside memories로 같지만 sample-oral-로 시작하는 ID는 서로 다릅니다. 각 레코드를 열어 소스 해시와 선택된 단어 수를 확인한 뒤 Back to collection으로 돌아오세요. Download index로 실제 샘플 JSON 파일을 확인하고 Back to Search Desk로 돌아갑니다.

두 패널은 준비된 샘플과 할당된 컬렉션을 구분합니다. 여러분의 색인은 처음에는 사용할 수 없습니다.

할당된 색인을 생성하기 전의 Search Desk

역색인은 단어를 문서 ID 및 출현 횟수와 연결합니다. documents 메타데이터는 각 ID, 제목, 원본 바이트의 지문인 소스 SHA-256을 기록합니다. 제목이 같아도 두 레코드의 식별값을 하나로 합치면 안 됩니다. 리더는 선택된 저장 색인만 사용하며 소스 HTML로 빠진 작업을 채우지 않습니다.

Open your index를 선택하세요. 현재 HTTP 503과 함께 Collection not indexed라고 표시합니다. 작은 샘플은 여섯 문서의 결과물이 아닙니다.

경로와 메모리 경계 이해하기

Workstation으로 전환하세요. 시작 위치는 /home/labex/project/collection-index입니다. cd는 그곳으로 돌아가고 ls는 파일을 나열합니다.

cd /home/labex/project/collection-index
ls source output

source/에는 원본 HTML 파일 여섯 개가 있습니다. output/은 쓰기 가능한 전달 디렉터리입니다. 원본, 준비된 이미지 dk06-indexer:1, 별도 샘플 리더를 온전히 유지하세요. 과정 컨테이너와 색인 출력만 생성합니다.

이미지의 entrypoint는 이미 색인 프로그램을 실행합니다. 이미지 이름 뒤의 --source /input, --output /output/attempt.json, --workers 4는 Docker 플래그가 아닌 프로그램 인수입니다. worker는 실제 HTML을 문서 트리로 해석합니다. 배치는 선택한 트리를 유지하면서 단어를 추출한 뒤 해제합니다. worker가 많으면 메모리가 더 필요할 수 있으며 더 빠른 속도를 보장하지 않습니다.

이미지 이름 앞의 Docker 옵션은 동작 경계를 설정합니다.

옵션 여기서의 의미
--name Docker에 기록된 실제 상태를 확인할 수 있도록 명확한 이름의 컨테이너 보존
--memory 160m 160 MiB RAM 한도 적용
--memory-swap 160m RAM과 swap 합계를 같은 양으로 설정하여 추가 swap을 허용하지 않음
--network none 파일 처리 작업에는 네트워크가 필요하지 않음
--user 실제 일반 계정으로 출력 작성
두 --mount 옵션 원본 입력은 읽기만 하고 별도 출력 폴더에 쓰기

id -u와 id -g는 실제 숫자 사용자 및 그룹 ID를 출력합니다. 1000이라고 가정하지 마세요. $(...)는 이 명령 안에 명령의 출력을 치환합니다. 큰따옴표는 결합된 사용자/그룹과 각 마운트 전체 값을 하나의 인수로 유지하면서 현재 디렉터리인 $PWD의 확장을 허용합니다. 줄 끝의 역슬래시는 다음 물리적 줄을 같은 명령으로 연결합니다.

호스트 입력 source/는 컨테이너 내부의 /input으로, 호스트 output/은 /output으로 보입니다. readonly는 해당 마운트를 통한 입력을 보호합니다. 소스에 대한 다른 쓰기 가능한 별칭을 추가하지 마세요. 두 메모리 옵션을 변경하지 말고 OOM killer를 비활성화하거나 플랫폼 설정을 변경하지 마세요.

실패 재현 및 원인 연결하기

제공된 4-worker 시도를 실행하세요. 색인을 완성하기 전에 명령 자체가 종료 상태 137을 반환하며 끝날 것으로 의도적으로 예상됩니다.

docker run --name index-attempt \
  --memory 160m --memory-swap 160m --network none \
  --user "$(id -u):$(id -g)" \
  --mount "type=bind,src=$PWD/source,dst=/input,readonly" \
  --mount "type=bind,src=$PWD/output,dst=/output" \
  dk06-indexer:1 --source /input --output /output/attempt.json --workers 4

중지 전 초기 Parsing batch 줄만 보일 수 있습니다. 중지된 컨테이너를 보존하세요. 식별값과 실효 설정이 중요하므로 --rm은 없습니다.

docker inspect는 Docker에 기록된 실제 컨테이너 필드를 읽습니다. 작은따옴표는 각 짧은 형식 템플릿을 그대로 유지합니다. 먼저 종료 코드와 Docker의 OOM 플래그를 읽은 다음 두 제한을 바이트로 읽으세요.

docker inspect index-attempt --format '{{.State.ExitCode}} {{.State.OOMKilled}}'
docker inspect index-attempt --format '{{.HostConfig.Memory}} {{.HostConfig.MemorySwap}}'
docker logs index-attempt

설정된 제한 값은 둘 다 167772160, 즉 160 × 1024 × 1024바이트입니다. 종료 137만으로는 이 메모리 실패와 강제 종료를 구분할 수 없습니다. Docker의 OOMKilled 플래그를 기록해야 하지만, 이 실습에서 테스트한 Engine은 커널이 진짜 메모리 cgroup 강제 종료를 보고해도 때때로 false로 남을 수 있습니다. 어느 한 필드만 설명으로 삼지 말고 실제 커널 증거를 교차 확인하세요.

전체 컨테이너 ID를 셸 변수에 읽어 넣으세요. 대입에는 = 주위에 공백이 없으며 명령 치환은 inspect의 결과를 담습니다.

container_id=$(docker inspect --format '{{.Id}}' index-attempt)

이 변수는 해당 Workstation 셸에 속합니다. 브라우저 탭을 전환해도 바뀌지 않지만 새 셸을 열면 대입을 반복하세요. sudo dmesg는 보호된 커널 로그를 지우지 않고 읽습니다. 파이프 |는 출력을 grep으로 전달합니다. -F는 정확한 ID가 일반 텍스트로 포함된 줄을 선택하고 따옴표는 값을 하나의 인수로 유지합니다.

sudo dmesg | grep -F "$container_id"

CONSTRAINT_MEMCG와 이 전체 Docker 컨테이너 ID를 지정하는 oom_memcg 경로가 있는 줄을 찾으세요. 관련 없는 프로세스나 플랫폼 전체 부족이 아닌, 이 컨테이너의 메모리 제어 그룹에서 발생한 메모리 부족 동작을 식별합니다. 중지된 시도 및 실제 제한과 비교하세요. 가짜 로그를 만들거나 수동으로 죽인 프로세스로 이 시도를 대체하지 마세요.

배치를 줄이고 전체 작업 유지하기

한도는 고정되어 있습니다. 배치를 worker 하나로 줄이면 여섯 문서와 같은 단어 계산 알고리즘을 유지하면서 실제 해석된 문서 트리를 한 번에 하나씩 유지합니다. 이는 이 코퍼스에서 가능한 선택이며 worker 하나가 항상 최적이라는 뜻은 아닙니다. 같은 제한에서 전체 작업이 실제로 완료된다면 다른 가능한 worker 값도 허용됩니다.

별도의 보존할 전달 컨테이너를 생성하세요. 두 마운트, 준비된 entrypoint, 메모리 옵션을 유지하고 출력 파일 이름과 worker 수를 바꿉니다.

docker run --name index-delivery \
  --memory 160m --memory-swap 160m --network none \
  --user "$(id -u):$(id -g)" \
  --mount "type=bind,src=$PWD/source,dst=/input,readonly" \
  --mount "type=bind,src=$PWD/output,dst=/output" \
  dk06-indexer:1 --source /input --output /output/index.json --workers 1

모든 배치 뒤에 Indexed 6 documents and ... terms와 정상 종료 상태 0이 예상됩니다. 용어 총수는 관찰이며 그 자체로 증거는 아닙니다.

docker inspect index-delivery --format '{{.State.ExitCode}}'
ls -l output/index.json

출력은 일반 사용자/그룹 소유이며 컨테이너 종료 뒤에도 편집할 수 있습니다. 중지된 두 컨테이너를 보존하세요. 입력 경로를 잘못 쓰면 Docker는 처리 전에 바인드 소스 누락을 보고합니다. 명시된 작업 디렉터리로 돌아가 ls source output을 살펴보고 따옴표 경로를 수정한 뒤 반복하세요. 실수를 감추려고 대체 입력을 만들지 마세요.

실제 전달 색인 사용하기

Search Desk로 전환하고 필요하면 Back to Search Desk를 선택한 다음 Open your index를 엽니다. 샘플 ID 두 개가 아닌 색인된 문서 여섯 개를 보여 주어야 합니다. café를 검색하면 여섯 문서가 모두 각각 10,000회 출현으로 나타나야 합니다. 서로 다른 oral-0과 oral-1 ID로 두 Riverside memories 레코드를 여세요. 소스 해시와 단어 관계가 별도로 유지되어야 합니다.

전달된 컬렉션에는 같은 제목의 두 레코드를 포함하여 원본 ID 여섯 개 전체가 있습니다.

Search Desk의 전체 전달 컬렉션

Back to collection으로 돌아가 résumé, naïve 순서로 검색하고 실제 횟수로 여섯 레코드를 모두 계속 검색할 수 있는지 확인하세요. notawordinthiscollection을 검색하면 일치하는 문서가 없어야 합니다. Download index로 실제 전달 JSON을 확인하세요. 문서, 소스 해시, 포스팅은 모든 원본 입력에 속해야 합니다. 리더는 누락된 결과를 재생성하지 않습니다.

검사는 이 실행의 정확한 메모리 cgroup 이벤트를 컨테이너와 연결하고 성공한 전달의 실효 한도와 마운트를 확인하며, 원본 HTML의 모든 바이트를 독립적으로 스트리밍하여 Unicode 단어/문서별 횟수 전체를 검증합니다. 실제 작업을 다시 실행하거나 색인을 대신 쓰지 않습니다.

실패한 전달만 복구하기

전달 시도도 메모리 부족이 나면 중지 상태와 로그를 확인하고 가능한 배치를 선택한 뒤 docker rm index-delivery로 실패한 index-delivery 컨테이너만 제거하고 표시된 전달 명령을 재시도하세요. 증거를 위해 index-attempt와 모든 원본 HTML 파일을 보존합니다. 성공한 재실행은 자체 출력을 완전한 색인으로 덮어씁니다. 횟수를 직접 편집하거나 작은 샘플을 전달물에 복사하지 마세요.

요약

실제 메모리 cgroup OOM 동작을 정확한 컨테이너와 실효 제한에 연결한 뒤, 실제 HTML 배치 동시성을 줄여 같은 160 MiB 한도 안에서 전체 색인을 완성했습니다. 저장된 색인은 여섯 식별값 전체, 중복 제목, 원본 소스 해시, Unicode 단어 수를 보존하며 컨테이너 종료 후에도 사용할 수 있습니다.