Недавно на работе мне нужно было просмотреть наши архивные файлы и предоставить результаты к концу дня. Вот параметры запроса:
- Архивные файлы зашифрованы и хранятся в HDFS (не спрашивайте, почему мы храним их в HDFS).
- Файлы различаются по размеру от 3 до 9 ГБ.
- Общее количество файлов для поиска было 300+
- Расшифровка каждого файла занимает от 1 до 2 минут.
В прошлом были запросы на поиск в одном архивном файле. В этих случаях мы будем копировать файл из HDFS на сервер. Затем запустите сценарий оболочки, чтобы расшифровать файл и выполнить поиск. Программа расшифровки требует 2 аргумента: зашифрованный файл и файл для записи расшифрованных данных. Это означает, что расшифрованный и зашифрованный файл находятся на диске одновременно.
При средней скорости 1,5 минуты для расшифровки одного файла для 300 файлов требовалось 450 минут (7,5 часов). Чтобы добавить к моей дилемме, не было достаточно времени, чтобы написать собственный RecordReader . Единственным решением было бы передавать файлы параллельно. Но есть 2 проблемы с этим подходом:
- На сервере недостаточно места для 20 (10 зашифрованных и 10 расшифрованных) файлов одновременно.
- Код дешифрования выполняет чтение из стандартного ввода или запись в стандартный вывод.
Что делать? Используйте именованные каналы, конечно!
Ускоренный курс по именованным каналам
Трубы используются для составления узконаправленных программ для решения более широких задач. Например :
В этом примере мы используем анонимные каналы (обозначаемые символом «|»). Трубы, используемые в командной строке или в сценариях, живут только в течение текущего процесса. Именованные каналы похожи с этими исключениями:
- Вы создаете именованные каналы с помощью команды
mkfifo name-of-pipe
. - Может использоваться повторно несколькими процессами.
- Namped трубы сохраняются, пока не будут удалены с помощью команды
rm name-of-pipe
. - Существуют в файловой системе и отображаются в виде файлов для других процессов.
- Разрешить межпроцессное взаимодействие.
Вот пример создания именованного канала и как он выглядит в файловой системе:
Обратите внимание, что именованный канал отображается в ls
результатах, и первый столбец слева — это p
. Если вам больше не нужен именованный канал, просто удалите его, как файл с командой rm pipe1
.
Мое решение с именованными трубами
Сначала я создал файл, состоящий из путей к архивам. Затем скрипт перебрал файл и запустил 10 процессов дешифрования / поиска параллельно. После запуска 10 процессов сценарий будет ожидать завершения всех 10 процессов, прежде чем запускать другой пакет.
Вот код для processFile
функции.
Хотя processFile
функция проста, есть несколько шагов, которые мы должны объяснить:
- Строка 2: создайте переменную с базовым именем зашифрованного файла из полного пути.
- Строка 3: создайте переменную имени зашифрованного файла за вычетом
.enc
расширения файла. - Строки 5,6: Создание именованных каналов для зашифрованного и расшифрованного файла.
- Строка 8: поток зашифрованный файл из HDFS и перенаправить на зашифрованный именованный канал и фоновый процесс.
- Строка 9: Запустите
cat
команду для расшифрованного файла. Затем передайте результатыawk
и найдите нужную информацию. Это тоже фоновое. - Строка 11: вызов сценария дешифрования с необходимыми параметрами файла.
- Строка 12: после расшифровки и поиска файла удалите именованные каналы.
Вывод
Использование именованных каналов позволило мне расшифровать и найти более 300 файлов примерно за 1,5 часа. Я также избежал проблемы с пространством, так как мне никогда не приходилось записывать файл на диск. Хотя именованные каналы не нужны каждый день, они являются полезным инструментом в вашем арсенале.