Всем привет. Сегодня я хочу рассказать про относительно новый продукт в стеке Apache Software Foundation для инженерии данных — OpenDAL.
Из официального описания на сайте проекта: OpenDAL предоставляет унифицированную абстракцию, которая помогает разработчикам получать доступ ко всем сервисам хранения данных.
Это описание само по себе настолько общее, что в таком виде бесполезно и может охватывать что угодно, от CURL до JDBC. При этом сразу же вспоминается картинка Universal Converter Box.
DAL появился в конце 2021 года в недрах Databend - опенсорс альтернативы Snowflake, а в феврале 2022 года DAL отделился от репозитория кода Databend и стал самостоятельным проектом под названием OpenDAL. В феврале 2023 года было получено одобрение на вступление в инкубатор Apache Software Foundation (ASF). А в марте 2024 года проект, пройдя через серию оценочных этапов, успешно выпустился из инкубатора и получил статус Top Level Project ASF. Сейчас у OpenDAL около 3000 звезд и больше 1600 контрибьюторов на GitHub. https://github.com/apache/opendal
До появления OpenDAL, как утверждают авторы, каждый проект должен был создать свои абстракции для доступа к хранилищам, а затем интегрировать различные SDK. В этом процессе возникает множество проблем, и весь процесс представлял собой проблему "m * n".
После внедрения OpenDAL необходимо только подключиться к OpenDAL как к единому проекту для доступа к десяткам различных служб хранения, включая такие популярные как S3, HDFS и Redis. Таким образом процесс интеграции упрощается до "m + n".
Таким образом одним из главных преимуществ OpenDAL является его способность унифицировать доступ к разнообразным хранилищам данных, что позволяет разработчикам писать код взаимодействия с одним хранилищем и затем переиспользовать этот код для работы с другими хранилищами без дополнительных изменений.
Кроме того в связи с ростом популярности мультиоблачных архитектур, организации сталкиваются с проблемой управления данными, которые распределены между разными облачными платформами. Это вызывает необходимость в решениях для перемещения данных, не требующих изменений в коде или архитектуре приложений. OpenDAL решает эту проблему, предоставляя возможность легкого подключения и интеграции и перемещения данных между облачными сервисами.
OpenDAL уменьшает зависимость от специфических API и SDK, которые могли бы требоваться для каждого типа хранилища отдельно. Разработчики могут использовать единый API OpenDAL для работы с данными, будь то локальные файловые системы, облачные хранилища, как S3 или Google Cloud Storage, или распределенные файловые системы, как HDFS.
Поддерживаемые службы хранения данных
OpenDAL на текущий момент поддерживает 63 сервиса, охватывающих широкий спектр систем хранения данных, включая объектные хранилища (например, S3 и совместимые, GCS, OSS), файловые хранилища (например, HDFS, Azure Data Lake), облачные хранилища для потребителей (например, Yandex Disk, Google Drive, OneDrive) и системы хранения типа ключ-значение (например, RocksDB, Redis), а также кэш-хранилища (например, Memcached, Moka). С полным списком можно ознакомиться на сайте.
Для этих сервисов доступны различные операции, такие как получение статистики по файлам и папкам (stat), чтение (read) и запись (write) данных, создание директорий (create_dir), удаление (delete) файлов и директорий, копирование (copy) и переименование (rename) файлов, а также перечисление (list) файлов в директории. Эти операции поддерживаются большинством сервисов.
Однако функции, такие как добавление данных в конец файла (append), сканирование содержимого (scan), создание предварительно подписанных URL (presign) и блокирующие операции (blocking), доступны не для всех сервисов и зависят от конкретных возможностей каждой системы хранения данных и реализации API.
Чем OpenDAL не является
Теперь, после того разобрались, чем является OpenDAL, давайте рассмотрим, чем OpenDAL не является. Важно подчеркнуть, что OpenDAL не является прокси-сервисом. OpenDAL предоставляется в виде библиотеки, а не службы или приложения-прокси для различных частей хранилища данных. Если вы хотите интегрировать OpenDAL в существующий проект, вам необходимо вызвать интерфейс OpenDAL напрямую.
Также стоит отметить, что OpenDAL не является агрегатором SDK. В традиционных проектах, при подключении различных служб хранения, используется их SDK, например, широко используемый SDK S3 и SDK AzBlob, и другие. OpenDAL не просто вызывает различные SDK сервисов хранения данных. Была разработана собственная интеграцию с различными сервисами хранения на основе унифицированного ядра на Rust, чтобы обеспечить сглаживание различий между сервисами.
Например, для S3 OpenDAL самостоятельно формирует HTTP-запросы и анализирует HTTP-ответы, чтобы гарантировать соответствие всех действий спецификациям API и полный контроль со стороны OpenDAL. Благодаря тому, что OpenDAL напрямую управляет процессом доступа к данным, стало возможным реализовать унифицированные механизмы повторных попыток и ведения журнала для различных систем хранения данных и обеспечить единообразие поведения.
Для сервисов, совместимых с S3, из-за ограничений родных сервисов хранения и различий в реализации API совместимость и детали поведения могут отличаться от S3. Например, для OSS необходимо установить независимый заголовок, чтобы обеспечить единообразное поведение для диапазона.
Как начать работать с OpenDAL
Ядро OpenDAL написано на Rust, но также поддерживаются другие языки, такие как Python, Node.js, Java, и активно разрабатываются привязки для других языков.
Точки входа API OpenDAL — это Operator и BlockingOperator. Все публичные API доступны через оператор. Чтобы начать работу с OpenDAL, вам нужно:
Инициализировать сервис.
Настроить слои.
Использовать оператор.
Инициализация сервиса
Первый шаг — выбор сервиса и его инициализация с помощью конструктора. Все поддерживаемые сервисы можно найти в разделе сервисов.
Возьмем в качестве примера services::S3:
use opendal::services;
use opendal::Operator;
use opendal::Result;
fn main() -> Result<()> {
// Pick a builder and configure it.
let mut builder = services::S3::default();
builder.bucket("test");
// Init an operator
let op = Operator::new(builder)?.finish();
Ok(())
}
Настройка слоев
Следующий шаг — настройка слоев. Слои — это модули, которые добавляют дополнительные функции к каждой операции.
В качестве примера рассмотрим слой layers::LoggingLayer; этот слой добавляет ведение журнала ко всем операциям, выполняемым OpenDAL.
use opendal::layers::LoggingLayer;
use opendal::services;
use opendal::Operator;
use opendal::Result;
#[tokio::main]
async fn main() -> Result<()> {
// Pick a builder and configure it.
let mut builder = services::S3::default();
builder.bucket("test");
// Init an operator
let op = Operator::new(builder)?
// Init with logging layer enabled.
.layer(LoggingLayer::default())
.finish();
Ok(())
}
Использование оператора
Последний шаг — использование оператора. OpenDAL поддерживает как асинхронный Operator, так и блокирующий BlockingOperator. Выберите тот, который подходит для вашего случая использования.
Каждый API оператора следует одному и тому же шаблону, рассмотрим на примере операции чтения:
· read: Выполнить операцию чтения.
· read_with: Выполнить операцию чтения с дополнительными параметрами, такими как диапазон и условие совпадения (if_match).
· reader: Создать объект для потоковой передачи данных, обеспечивая гибкий доступ.
· reader_with: Создать объект для потоковой передачи данных с расширенными настройками.
use opendal::layers::LoggingLayer;
use opendal::services;
use opendal::Operator;
use opendal::Result;
#[tokio::main]
async fn main() -> Result<()> {
// Pick a builder and configure it.
let mut builder = services::S3::default();
builder.bucket("test");
// Init an operator
let op = Operator::new(builder)?
// Init with logging layer enabled.
.layer(LoggingLayer::default())
.finish();
// Fetch this file's metadata
let meta = op.stat("hello.txt").await?;
let length = meta.content_length();
// Read data from `hello.txt` with range `0..1024`.
let bs = op.read_with("hello.txt").range(0..1024).await?;
Ok(())
}
Альтернативы
Так как OpenDAL не единственный проект, решаюший проблему предоставления абстракции доступа к данным, то не упомянуть его конкурентов было бы неправильно. Как минимум есть еще пара очень похожих инструментов.
Object_store - это библиотека для асинхронного взаимодействия с объектными хранилищами, разработанная первоначально для InfluxDB IOx и позже переданная в проект Apache Arrow. OpenDAL и object_store разработаны на Rust и предназначены для работы с объектными хранилищами, но имеют немного разные цели и функциональности. OpenDAL предлагает универсальный слой доступа к данным, скрывая детали реализации за абстракцией Operator. Object_store фокусируется на асинхронной работе с хранилищами, предоставляя прямой доступ через трейт ObjectStore. OpenDAL поддерживает немного более широкий спектр сервисов и включает уникальные функции, такие как кэширование метаданных и слои для логирования и метрик, тогда как object_store ориентирован на базовые операции и производительность. Но в принципе, кажется, что два продукта достаточно похожи.
Fsspec - это библиотека Python, предназначенная для абстракции и унификации доступа к различным файловым системам и хранилищам данных. Библиотека предоставляет единый интерфейс для работы с файлами, независимо от того, находятся ли они локально, на удаленных серверах или в облачных хранилищах. fsspec поддерживает множество различных протоколов и хранилищ, включая, но не ограничиваясь, такими как S3, HDFS, GCS (Google Cloud Storage), FTP, HTTP и многие другие. тесно интегрируется с популярными инструментами анализа данных в экосистеме Python, такими как Pandas и Dask.
Надеюсь донес до вас какую-то новую информацию, заинтересовал характеристиками OpenDAL и сподвигнул попробовать что-то новое. Если кто-то уже имеет опыт пользования OpenDAL - ставьте лайки, буду рад увидеть ваши комментарии. До встречи.
NightShad0w
А какая добавочная ценность у OpenDAL для проектов не в экосистеме Apache?
Отрицая родные SDK и переизобретая реализации конкретных сервисов, OpenDAL сразу становится отстающим по функционалу от родных SDK.
Как максимально общий интерфейс взаимодействия, он же сводится к минимальному общему функционалу, а все особенности и локальные улучшения становятся или неподдерживаемыми, или протекающими абстракциями.
Нет ничего хуже для интегрированного приложения, как использовать единый общий интерфейс, с костылями под каждый сервис на уровне приложения. Вместо N зависимостей от SDK, получаем N+1, и хорошо еще если вообще можно какой-никакой доступ в нижним слоям получить и напрямую в SDK присунуть требуемое.
Проще уж проектное архитектурное решение принять, привнести в проект стандартную зависимость от конкретных официальных SDK, и реализовать диктуемые конкретными требованиями проекта интерфейсы абстракций, учитывая в первую очередь нужды продукта, а не цель общности абстракции.
Phoenix-616
Когда проект связан ровно с одним типом хранилища, OpenDAL будет не нужной прослойкой (при условии, что гарантируется отсутствие необходимости смены хранилища). А вот когда типов хранилищ сразу несколько, то он встанет в полный рост, т.к. общий функционал будет реализован ровно один раз, а функционал специфичный для хранилища одного типа и необходимый в проекте все равно нужно будет как-то имплементировать для остальных типов хранилищ.
По сути аналог ODBC/JDBC для баз данных.
Sergei-Shaikin Автор
Это справедливо если у вас только одно хранилище. А также если вы не планируете никогда подкючать новые, организовывать многооблачность или мигрировать на другие хранилища.
Для проектов с очень специфичными требованиями и функциональностью, использование официальных SDK может быть оправдано. С другой стороны если проекту требуются специфические функции конкретного хранилища, то OpenDAL можно дополнить, реализовав необходимые расширения, так как есть поддержка обращения я к низкоуровневым API через методы raw, дает возможность использовать уникальные функции конкретного хранилища.
Хотя если брать тот же самый S3 то из всего списка операций поддерживаются stat, read, write, create_dir, delete, copy, list, scan, presign. И не реализованы только rename и blocking, что в принципе не выглядит какой-то проблемой.