Indexe a coleção dentro do limite

DockerBeginner
Pratique Agora

Introdução

A coleção Riverside precisa de um índice pesquisável de seis documentos HTML de história oral. A ferramenta de contêiner fornecida realmente analisa seu HTML e conta palavras Unicode, mas seu lote com quatro workers excede um limite de memória de 160 MiB. Diagnostique essa falha usando evidências vinculadas ao contêiner exato e depois produza o índice completo sem aumentar o limite nem remover documentos.

Você deve conhecer os comandos básicos docker run, caminhos no terminal e a finalidade dos bind mounts. Este laboratório explica as opções de memória, os IDs reais de usuário, os caminhos entre aspas, a substituição de comandos e o pequeno pipeline de leitura de evidências antes do uso. Não é necessário programar em Python, escrever HTML nem implementar algoritmos de pesquisa. O Docker, a imagem de indexação e o Search Desk somente de leitura estão preparados.

O conjunto de documentos é explicitamente sintético: cada documento contém 10.000 trechos didáticos expandidos para tornar observável a pressão real de memória do analisador. O resultado é um índice real desses bytes, não uma alocação simulada nem uma garantia de capacidade de produção. Reserve cerca de 60 minutos para leitura e erros comuns; essa é uma estimativa do autor.

Crie o índice completo dentro do limite

Nesta etapa, você conhecerá um resultado normal de pesquisa, reproduzirá uma falha por memória limitada, correlacionará evidências nativas e concluirá a coleção inteira com um lote limitado.

Use primeiro um pequeno índice normal

Comece em Search Desk e selecione Explore sample. Esta amostra preparada separada contém dois documentos pequenos. Pesquise café usando Search one word e Search. Os dois registros compartilham o título Riverside memories, mas têm IDs distintos que começam com sample-oral-. Abra cada registro, examine seu hash de origem e as contagens de palavras selecionadas e use Back to collection. Use Download index para examinar o arquivo JSON real da amostra e depois Back to Search Desk.

Os dois painéis separam a amostra preparada da coleção atribuída a você. Seu índice começa indisponível:

Search Desk antes da criação do índice atribuído

Um índice invertido conecta uma palavra a IDs de documentos e contagens de ocorrências. Seus metadados documents registram cada ID, título e SHA-256 da origem, uma impressão digital dos bytes originais. Dois registros com o mesmo título não devem se fundir em uma identidade. O leitor usa apenas o índice salvo selecionado; nunca preenche trabalho ausente a partir do HTML de origem.

Selecione Open your index. Atualmente mostra Collection not indexed com HTTP 503. A pequena amostra não é seu resultado de seis documentos.

Entenda os caminhos e o limite de memória

Mude para Workstation, que inicia em /home/labex/project/collection-index. cd volta para lá e ls lista os arquivos:

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

source/ contém seis arquivos HTML originais. output/ é seu diretório gravável de entrega. Mantenha intactos os originais, a imagem preparada dk06-indexer:1 e o leitor separado da amostra. Você criará somente contêineres do curso e a saída do índice.

O entrypoint da imagem já executa seu programa de indexação. --source /input, --output /output/attempt.json e --workers 4 após o nome da imagem são argumentos do programa, não opções do Docker. Os workers analisam HTML real e constroem árvores de documentos. Um lote mantém suas árvores selecionadas enquanto extrai palavras e depois as libera. Mais workers podem exigir mais memória; não são uma promessa de maior velocidade.

As opções Docker antes do nome da imagem definem os limites de operação:

Opção Significado aqui
--name Manter um contêiner com nome claro para inspeção nativa
--memory 160m Impor um limite de RAM de 160 MiB
--memory-swap 160m Definir o total de RAM mais swap no mesmo valor, sem margem adicional de swap
--network none O trabalho de processamento de arquivos não precisa de rede
--user Gravar a saída como sua conta normal real
Duas opções --mount Ler somente a entrada original; gravar na pasta separada de saída

id -u e id -g mostram seus IDs numéricos reais de usuário e grupo; não presuma 1000. $(...) substitui a saída de um comando neste comando. As aspas duplas mantêm o usuário/grupo combinado e cada valor completo de montagem como um único argumento, permitindo expandir $PWD, o diretório atual. Uma barra invertida no fim da linha une a próxima linha física ao mesmo comando.

A entrada source/ do host aparece como /input dentro do contêiner; output/ do host aparece como /output. readonly protege a entrada por meio dessa montagem. Não adicione outro alias gravável da origem. Mantenha as duas opções de memória inalteradas e não desative o OOM killer nem altere configurações da plataforma.

Reproduza e atribua a falha

Execute a tentativa fornecida com quatro workers. Espera-se deliberadamente que ela encerre com status nativo 137 antes de completar seu índice:

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

Você pode ver apenas uma linha inicial Parsing batch antes de ela parar. Mantenha o contêiner parado: não há --rm, porque sua identidade e suas configurações efetivas importam.

docker inspect lê campos nativos do contêiner. As aspas simples mantêm cada pequeno modelo de formato literal. Primeiro leia o código de saída e a indicação OOM do Docker; depois os dois limites em bytes:

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

Os valores de limite configurados são ambos 167772160, ou 160 × 1024 × 1024 bytes. A saída 137 sozinha não distingue esta falha de memória de uma interrupção forçada. A indicação OOMKilled do Docker deve ser registrada, mas o Engine testado deste laboratório pode às vezes deixá-la como false mesmo quando o kernel informa uma interrupção genuína por memory cgroup. Confira as evidências reais do kernel, em vez de tratar qualquer campo isolado como explicação.

Leia o ID completo do contêiner em uma variável do shell. A atribuição não tem espaços ao redor de =; a substituição de comando captura o resultado de inspect:

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

A variável pertence a este shell de Workstation. Mudar de aba no navegador não a altera; se abrir um novo shell, repita a atribuição. sudo dmesg lê o log protegido do kernel sem limpá-lo. Um pipe | alimenta grep com essa saída; -F seleciona as linhas que contêm o ID exato como texto comum, e as aspas preservam seu valor como um único argumento:

sudo dmesg | grep -F "$container_id"

Encontre a linha que contém CONSTRAINT_MEMCG e um caminho oom_memcg que nomeia esse ID completo de contêiner Docker. Ela identifica uma ação por falta de memória no grupo de controle de memória deste contêiner, em vez de um processo não relacionado ou escassez em toda a plataforma. Compare-a com a tentativa parada e seus limites reais. Não crie logs falsos nem substitua esta tentativa por um processo morto manualmente.

Reduza o lote, mantenha o trabalho completo

O limite é fixo. Reduzir o lote a um worker mantém uma árvore real de documento analisado por vez, preservando os seis documentos e o mesmo algoritmo de contagem de palavras. Essa é uma escolha viável para este conjunto, não uma alegação de que um worker seja sempre ideal. Outros valores viáveis de workers são aceitos se o trabalho completo realmente terminar sob os mesmos limites.

Crie um contêiner separado de entrega que será mantido. Preserve as duas montagens, o entrypoint preparado e as opções de memória; altere o nome do arquivo de saída e a quantidade de workers:

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

Espere todos os lotes seguidos de Indexed 6 documents and ... terms e status de saída normal 0. O total de termos é uma observação, não uma prova por si só:

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

A saída pertence ao seu usuário/grupo normal e continua editável depois que o contêiner encerra. Mantenha os dois contêineres parados. Se um caminho de entrada estiver digitado incorretamente, o Docker informa uma origem de bind mount ausente antes do processamento: volte ao diretório de trabalho indicado, examine ls source output, corrija o caminho entre aspas e repita. Não crie uma entrada substituta para esconder o erro.

Use o índice real entregue

Mude para Search Desk, selecione Back to Search Desk se necessário e depois Open your index. Ele deve mostrar seis documentos indexados, não os dois IDs da amostra. Pesquise café: os seis documentos devem aparecer com 10.000 ocorrências cada. Abra os dois registros Riverside memories por seus IDs distintos oral-0 e oral-1. Seus hashes de origem e relações entre palavras devem permanecer separados.

A coleção entregue contém os seis IDs originais, incluindo os dois registros de mesmo título:

A coleção completa entregue em Search Desk

Volte com Back to collection, pesquise résumé e depois naïve, e confirme que os seis registros continuam pesquisáveis com suas contagens reais. Pesquise notawordinthiscollection: nenhum documento deve corresponder. Use Download index e examine o JSON real entregue; seus documentos, hashes de origem e listas de ocorrências pertencem a todas as entradas originais. O leitor não regenera resultados ausentes.

As verificações correlacionam o evento exato de memory cgroup desta execução com seu contêiner, examinam o limite efetivo e as montagens da entrega bem-sucedida e leem de forma independente, em fluxo, todos os bytes HTML originais para verificar todas as contagens Unicode de palavras/documentos. Elas não executam novamente seu trabalho real nem escrevem o índice para você.

Recupere somente uma entrega sem sucesso

Se sua tentativa de entrega também ficar sem memória, examine seu estado parado e logs, escolha um lote viável e remova somente esse contêiner index-delivery sem sucesso com docker rm index-delivery antes de tentar novamente o comando de entrega mostrado. Mantenha index-attempt e todos os arquivos HTML originais como evidência. Uma nova execução bem-sucedida sobrescreve sua própria saída com um índice completo; não edite contagens à mão nem copie a pequena amostra para a entrega.

Resumo

Você vinculou uma ação OOM real de memory cgroup ao seu contêiner exato e aos limites efetivos; depois reduziu a concorrência real de lotes HTML para terminar o índice completo sob o mesmo limite de 160 MiB. O índice salvo preserva as seis identidades, títulos duplicados, hashes originais das fontes e contagens de palavras Unicode, e continua utilizável depois que seu contêiner encerra.