Введение
Коллекции Riverside нужен поисковый индекс шести HTML-документов устной истории. Предоставленный контейнерный инструмент действительно разбирает их HTML и считает слова Unicode, но его пакет с четырьмя обработчиками превышает лимит памяти 160 МиБ. Диагностируйте сбой по свидетельствам, связанным с конкретным контейнером, затем создайте полный индекс без повышения лимита и удаления документов.
Вы должны знать основы docker run, пути терминала и назначение bind-монтирований. Эта работа объясняет параметры памяти, фактические ID пользователя, пути в кавычках, подстановку команд и небольшой конвейер чтения свидетельств перед использованием. Программирование на Python, создание HTML и реализация алгоритма поиска не требуются. Docker, образ индексатора и Search Desk только для чтения подготовлены.
Корпус явно синтетический: каждый документ содержит 10 000 развёрнутых учебных отрывков, чтобы сделать реальную нагрузку парсера на память наблюдаемой. Результат — настоящий индекс этих байтов, а не имитация выделения памяти или гарантия производственной ёмкости. Выделите около 60 минут с учётом чтения и обычных ошибок; это оценка автора.
Соберите полный индекс в пределах лимита
На этом шаге вы изучите нормальный результат поиска, воспроизведёте сбой при ограниченной памяти, сопоставите собственные свидетельства системы и обработаете всю коллекцию с ограниченным пакетом.
Сначала используйте небольшой нормальный индекс
Начните в Search Desk и выберите Explore sample. Этот отдельный подготовленный образец содержит два небольших документа. Найдите café с помощью Search one word и Search. Обе записи имеют название Riverside memories, но разные ID, начинающиеся с sample-oral-. Откройте каждую, изучите хеш источника и выбранные частоты слов, затем используйте Back to collection. Через Download index изучите настоящий JSON-файл образца, затем выберите Back to Search Desk.
Две панели разделяют подготовленный образец и назначенную вам коллекцию. Ваш индекс изначально недоступен:

Обратный индекс связывает слово с ID документов и числом вхождений. Его метаданные documents фиксируют каждый ID, название и SHA-256 источника — отпечаток исходных байтов. Две записи с одинаковым названием не должны сливаться в одну идентичность. Просмотрщик использует только выбранный сохранённый индекс; он никогда не восполняет отсутствующую работу из исходного HTML.
Выберите Open your index. Сейчас отображается Collection not indexed с HTTP 503. Маленький образец не является вашим результатом из шести документов.
Разберитесь в путях и границе памяти
Переключитесь в 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. Обработчики разбирают настоящий HTML в деревья документов. Пакет удерживает выбранные деревья во время извлечения слов, затем освобождает их. Больше обработчиков может требовать больше памяти; это не обещание большей скорости.
Параметры Docker перед именем образа задают рабочие границы:
| Параметр | Значение здесь |
|---|---|
--name |
Сохранить контейнер с понятным именем для изучения его собственного состояния |
--memory 160m |
Установить лимит RAM 160 МиБ |
--memory-swap 160m |
Установить общий объём RAM и swap в то же значение без дополнительного swap |
--network none |
Заданию обработки файлов сеть не нужна |
--user |
Записывать результат от вашей фактической обычной учётной записи |
Два параметра --mount |
Только читать исходные входные данные; писать в отдельную выходную папку |
id -u и id -g выводят фактические числовые ID пользователя и группы; не предполагайте 1000. $(...) подставляет вывод команды в эту команду. Двойные кавычки сохраняют объединённые пользователя и группу и каждое полное значение монтирования как один аргумент, разрешая раскрытие $PWD, текущего каталога. Обратная косая черта в конце соединяет следующую физическую строку с той же командой.
Входной source/ хоста виден как /input в контейнере; output/ хоста — как /output. readonly защищает вход через это монтирование. Не добавляйте другой записываемый псевдоним источника. Сохраните оба параметра памяти без изменений и не отключайте OOM killer, не меняйте настройки платформы.
Воспроизведите и установите причину сбоя
Запустите предоставленную попытку с четырьмя обработчиками. Она намеренно должна завершиться с собственным кодом 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 читает собственные поля контейнера. Одинарные кавычки сохраняют каждый небольшой шаблон формата буквально. Сначала прочитайте код завершения и флаг OOM Docker, затем оба лимита в байтах:
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 этой работы иногда оставляет его 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 и путём oom_memcg, называющим этот полный ID контейнера Docker. Она указывает действие при нехватке памяти в группе управления памятью этого контейнера, а не постороннего процесса или всей платформы. Сравните её с остановленной попыткой и фактическими лимитами. Не создавайте поддельные журналы и не заменяйте эту попытку процессом, уничтоженным вручную.
Уменьшите пакет, сохраните всю работу
Лимит фиксирован. Уменьшение пакета до одного обработчика удерживает по одному настоящему разобранному дереву документа, сохраняя все шесть документов и тот же алгоритм подсчёта слов. Это выполнимый выбор для этого корпуса, а не утверждение, что один обработчик всегда оптимален. Другие выполнимые значения принимаются, если всё задание действительно завершается с теми же лимитами.
Создайте отдельный сохраняемый контейнер поставки. Сохраните оба монтирования, подготовленный entrypoint и параметры памяти; измените имя выходного файла и число обработчиков:
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 сообщает об отсутствующем источнике bind-монтирования до обработки: вернитесь в указанный рабочий каталог, изучите ls source output, исправьте путь в кавычках и повторите. Не создавайте подменные входные данные для сокрытия ошибки.
Используйте настоящий переданный индекс
Переключитесь в Search Desk, при необходимости выберите Back to Search Desk, затем Open your index. Должны отображаться шесть индексированных документов, а не два ID образца. Найдите café: должны появиться все шесть документов с 10 000 вхождений в каждом. Откройте обе записи Riverside memories по отдельным ID oral-0 и oral-1. Их хеши источников и связи слов должны оставаться раздельными.
Переданная коллекция содержит все шесть исходных ID, включая обе записи с одинаковым названием:

Вернитесь через Back to collection, найдите résumé, затем naïve и убедитесь, что все шесть записей остаются доступными для поиска с настоящими частотами. Найдите notawordinthiscollection: совпадений не должно быть. Используйте Download index и изучите настоящий переданный JSON; его документы, хеши источников и списки вхождений относятся ко всем исходным входным данным. Просмотрщик не создаёт отсутствующие результаты заново.
Проверки сопоставляют точное событие группы управления памятью этого запуска с контейнером, изучают действующий лимит и монтирования успешной поставки и независимо потоково читают каждый исходный байт HTML для проверки всех частот Unicode по словам и документам. Они не запускают повторно ваше задание в учебном окружении и не записывают индекс за вас.
Восстанавливайте только неудачную поставку
Если попытка поставки тоже исчерпала память, изучите остановленное состояние и журналы, выберите выполнимый пакет и удалите только этот неудачный контейнер index-delivery командой docker rm index-delivery перед повтором показанной команды поставки. Сохраните index-attempt и все исходные HTML-файлы как свидетельства. Успешный повтор перезаписывает собственный результат полным индексом; не редактируйте частоты вручную и не копируйте маленький образец в поставку.
Резюме
Вы связали настоящее действие OOM группы управления памятью с конкретным контейнером и его действующими лимитами, затем уменьшили фактическую параллельность пакета HTML для завершения всего индекса в том же лимите 160 МиБ. Сохранённый индекс сохраняет все шесть идентичностей, повторяющиеся названия, исходные хеши и частоты слов Unicode и остаётся пригодным после завершения контейнера.



