Добро пожаловать в представление моей серии статей Инженерия данных с помощью Rust и Apache Arrow DataFusion. Вы можете получить доступ к следующей части здесь.

Мне нравится играть с языком Rust, чтобы создавать простые и эффективные инструменты командной строки. Программа CLI должна быть простой и компонуемой с достаточно хорошим набором функций, соответствующих философии Unix.

Но простота не является главной задачей классических инструментов обработки данных. Вместо этого фреймворки сложны, имеют множество зависимостей и разработаны с использованием нескольких сетевых служб. В результате использование этих инструментов часто связано с дорогостоящей инфраструктурой.

В этой серии статей показано, как использовать экосистему Apache Arrow и инфраструктуру Apache Arrow DataFusion для создания простого инструмента командной строки для обработки данных. Эта структура основана на формате Arrow и обеспечивает быстрое и простое преобразование данных файлов CSV или Parquet.

Путь обучения и цели

Моя цель — создать простой инструмент командной строки со следующими функциями:

  • Сначала прочитайте и обработайте аргументы командной строки конечного пользователя.
  • Затем прочитайте файл Parquet или CSV, используя корзину Apache Arrow DataFusion.
  • Затем примените простое преобразование к набору данных.
  • Наконец, запишите результаты в виде файла Parquet или CSV.

Я описываю реализацию этих функций с помощью Rust в серии статей из трех частей.

Примечание: в разделах кода этой серии используется синтаксис грамотного программирования[1]: каждый блок двойных угловых скобок (например, <<code-block>>) относится к определению кода, расширенному на месте в финальном исходный код программы.

Часть 1 описывает, как приложение может считывать и проверять параметры пользователя на основе Clap Crate.

Ниже вы можете увидеть интерфейс командной строки нашего окончательного приложения с определенными параметрами.

Обратите внимание, что cargo run -- запустите полученный двоичный файл со всеми аргументами, которые следуют за двумя дефисами.

$ cargo run -- --help
 
mdata_app 0.1.0
 
USAGE:
    mdata_app [OPTIONS] --input <INPUT> --output <OUTPUT> [SUBCOMMAND]
 
OPTIONS:
    -f, --format <FORMAT>    Output format [default: undefined] [possible values: undefined, csv,
                             parquet]
    -h, --help               Print help information
    -i, --input <INPUT>      Input path
    -l, --limit <LIMIT>      Limit the result to the first <limit> rows [default: 0]
    -o, --output <OUTPUT>    Output path
    -s, --schema             Display the schema
    -v, --verbose            Verbose level
    -V, --version            Print version information
 
SUBCOMMANDS:
    eq      Add equality test in the where clause
    help    Print this message or the help of the given subcommand(s)

Конечные пользователи могут указывать входные и выходные пути в соответствующем формате. Добавлены некоторые параметры для детализации журнала трассировки (--verbose) и проверки предполагаемой схемы (--schema).

Я определяю подкоманду, включающую настраиваемые справочные сообщения и проверку для настраиваемого преобразования данных. Например, я добавляю простую операцию фильтрации с помощью подкоманды eq с двумя аргументами:

  • ‹COLUMN›: имя столбца фильтра.
  • ‹VALUE›: значение фильтра.
$ cargo run -- eq --help
 
mdata_app-eq 0.1.0
Add equality test in the where clause
 
USAGE:
    mdata_app --input <INPUT> --output <OUTPUT> eq <COLUMN> <VALUE>
 
ARGS:
    <COLUMN>    
    <VALUE>     
 
OPTIONS:
    -h, --help       Print help information
    -V, --version    Print version information

В Части 2 я описываю операции чтения/записи и реализацию преобразования фильтра с использованием платформы Apache Arrow DataFusion.

В этом процессе я покажу, как управлять проверкой пользовательского ввода и настраивать пользовательские преобразования.

В последней Части 3япоказываю стратегии тестирования приложений для работы с данными. В частности, я выделяю две проблемы:

  • Модульное тестирование небольших отдельных частей кода с использованием интегрированной среды тестирования Rust.
  • Приемочное тестирование функций работы с данными и пользовательского интерфейса командной строки с настраиваемыми поддельными наборами данных.

Например, я сгенерировал простой CSV-файл, используя fake-rs crate, чтобы показать возможности приложения.

Этот образец набора данных содержит четыре столбца: id, col_key, col_bool и col_value. Каждый столбец случайным образом выбирается из спецификации, написанной с помощью фейкового ящика.

$ head tests/inputs/test.csv
 
id,col_key,col_bool,col_value
1627,A971hmwwXKSMCUh,true,0.51049227
1525,0C8NOuocYR,false,0.92079586
1506,EfUQ6DIOpbkhI2dvW,true,0.6692676
1883,HzVbQk7gWmH6,false,0.13097137
1759,pRqw8E0qK4,true,0.7207628
1192,1Ueyu3oV6XLL0,true,0.6408737
1699,8ipERPr9HpwT,true,0.3659184
1283,v8YjQXj,false,0.5097597
1208,UameWzlzuUSMWMG0V,false,0.1739344

С помощью приложения командной строки мы можем прочитать этот CSV-файл и переписать его в формате Parquet с ограничением размера вывода.

$ cargo run -- --input tests/inputs/test.csv \
    --output tests/outputs/out_test \
    --format parquet --limit 5

Эта команда дает следующий результат.

$ tree tests/outputs/out_test
 
tests/outputs/out_test
└── part-0.parquet
 
0 directories, 1 file

И, наконец, мы используем наш оператор фильтра для преобразования нашего набора данных. В этом случае мы фильтруем все строки со значением true в столбце «col_bool».

$ cargo run -- -i tests/inputs/test.csv \
    -o tests/outputs/test_csv_filtered \
    eq col_bool true

Этот оператор фильтра дает следующий результат.

$ head -q tests/outputs/test_csv_filtered/part-*
 
id,col_key,col_bool,col_value
1627,A971hmwwXKSMCUh,true,0.51049227
1506,EfUQ6DIOpbkhI2dvW,true,0.6692676
1759,pRqw8E0qK4,true,0.7207628
1192,1Ueyu3oV6XLL0,true,0.6408737
1699,8ipERPr9HpwT,true,0.3659184
1388,n36xdSEM4Rkks,true,0.18349582
1461,FQlJEx4fSdZYW2,true,0.855797
1916,JplFowr,true,0.103708684
1215,GayUaRMjjwbfGTllC,true,0.2439853

Примечание. Выходной формат представляет собой каталог с несколькими файлами «part-x.csv», каждый из которых представляет собой файл CSV. Почему? Механизм Apache Arrow DataFusion может обрабатывать большие объемы данных и использовать секционирование для масштабирования своих операций.

Заворачивать

В завершение мы начнем с простого двоичного шаблона груза и итеративно улучшаем его, выполнив следующие шаги:

Часть 1 — CLI-приложение с Clap

  • Шаг 1. Определите каталоги проекта и зависимости.
  • Шаг 2. Определите структуру программы и опишите основные блоки кода.
  • Шаг 3. Анализ аргументов командной строки с помощью контейнера Clap.


Часть 2. Загрузка, преобразование и запись с помощью Apache Arrow DataFusion

  • Шаг 4 — Определите некоторые утилиты и структуру для управления ошибками.
  • Шаг 5 — Загрузка, преобразование и запись данных.


И в ближайшие несколько недель :)

Часть 3. Тестирование приложения для работы с данными

  • Шаг 6. Модульное тестирование и создание временного файла/каталога.
  • Шаг 7. Приемочное тестирование программы командной строки с поддельными сгенерированными данными.

Наслаждаться!

Рекомендации

[1] Д. Э. Кнут, «Грамотное программирование», Компьютерный журнал, том. 27, нет. 2, стр. 97–111, 1984.