Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
В этой статье я бы хотел рассказать о такой технологии как S3 со стороны дата-инженерии.
S3 – это один из сервисов, который используется для построения Data Lake и обмена файлами.
Давайте начнем с определения:
S3 (Simple Storage Service) — протокол передачи данных, разработанный компанией Amazon. Также — объектное хранилище.
Что мы имеем по итогу? Это по своей идеи файлообменник. Как вы у себя на компьютере организуете хранение файлов точно таким же образом это можно и организовать и в S3.
Ниже в статье мы S3 будем использовать для создания некого Data Lake.
Поэтому давайте введем несколько терминов, которые нам понадобятся:
bucket – это контейнер, в котором вы можете хранить свои файлы (папка)
path – это ссылка, которая указывает на конкретную часть bucket (путь в проводнике)
object – это какой-то физический файл, который находится по path в bucket. Может иметь разные форматы. (файл)
access key – ключ доступа к bucket (логин)
secret key – секретный ключ доступа для bucket (пароль)
Так как обычно S3 разворачивается где-то, то для подключения к нему можно использовать разные клиенты с UI:
CyberDuck
Commander One
etc
Но в нашем случае мы будем общаться с S3 через Python.
Давайте для начала развернем этот сервис локально в Docker (весь код и все исходники будут доступны в моём репозитории)
version: "3.9"
services:
minio:
image: minio/minio:RELEASE.2024-07-04T14-25-45Z
restart: always
volumes:
- ./data:/data
environment:
- MINIO_ROOT_USER=minioadmin
- MINIO_ROOT_PASSWORD=minioadmin
command: server /data --console-address ":9001"
ports:
- "9000:9000"
- "9001:9001"
И для запуска сервиса необходимо выполнить команду: docker-compose up -d
.
Затем перейдем по адресу http://localhost:9001/browser и увидим Web UI нашего объектного хранилища.
Начнём с перехода в пункт Access Keys
и создадим первые ключи доступа, при нажатии на кнопку Create access key +
мы перейдем в интерфейс, в котором мы сможем создать наши Access Key
и Secret Key
. Для дальнейшего использования S3 их необходимо сохранить.
Теперь мы можем работать с нашим S3 через Python
Для этого сначала создадим локальное окружение командой и установим все зависимости для проекта:
python3.12 -m venv venv && \
source venv/bin/activate && \
pip install --upgrade pip && \
pip install -r requirements.txt
Затем создадим небольшой код, который будет проверять существование bucket в нашем S3:
from minio import Minio
# Импорт из локальной переменной секретных данных
from cred import s3_minio_access_key, s3_minio_secret_key
# Не меняется, это единый endpoint для подключения к S3
endpoint = 'localhost:9000'
# access key для подключения к bucket
access_key = s3_minio_access_key
# secret key для подключения к bucket
secret_key = s3_minio_secret_key
client = Minio(
endpoint=endpoint,
access_key=access_key,
secret_key=secret_key,
secure=False, # https://github.com/minio/minio/issues/8161#issuecomment-631120560
)
buckets = client.list_buckets()
for bucket in buckets:
print(bucket.name, bucket.creation_date)
Если его запустить, то мы ничего не увидим, так как в нашем S3 ещё нет ни одного bucket. Так давайте же создадим новый bucket следующим кодом:
from minio import Minio
# Импорт из локальной переменной секретных данных
from cred import s3_minio_access_key, s3_minio_secret_key
# Не меняется, это единый endpoint для подключения к S3
endpoint = 'localhost:9000'
# access key для подключения к bucket
access_key = s3_minio_access_key
# secret key для подключения к bucket
secret_key = s3_minio_secret_key
client = Minio(
endpoint=endpoint,
access_key=access_key,
secret_key=secret_key,
secure=False, # https://github.com/minio/minio/issues/8161#issuecomment-631120560
)
client.make_bucket(
bucket_name='test-local-bucket'
)
И если ещё раз запустить предыдущий код для проверки bucket. то он он отобразит наличие bucket test-local-bucket
Важно, что в S3 не поддерживается нижнее подчеркивание и поэтому вместо него необходимо использовать тире.
Давайте теперь загрузим какой-нибудь файл в наш bucket. Для этого воспользуемся следующим кодом:
import pandas as pd
# Импорт из локальной переменной секретных данных
from cred import s3_minio_access_key, s3_minio_secret_key
bucket_name = 'test-local-bucket'
file_name = 'titanic.csv'
df = pd.read_csv('https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv')
df.to_csv(
path_or_buf=f's3://{bucket_name}/{file_name}',
index=False,
escapechar='\\',
compression='gzip',
storage_options={
"key": s3_minio_access_key,
"secret": s3_minio_secret_key,
# https://github.com/mlflow/mlflow/issues/1990#issuecomment-659914180
"client_kwargs": {"endpoint_url": "http://localhost:9000"},
},
)
В Web UI вы можете проверить наличие файла
Важное свойство, которое стоит знать при работе с path в bucket – это то что можно указать свой path руками. Если посмотреть на пример выше, то у нас path выглядит так:
file_name = 'titanic.csv'
, но можно задать любой path, для примера вот так: file_name = 'raw/kaggle/2022-04-01/titanic.csv'
и получим в bucket такую структуру:
Также стоит отметить, что если мы удалим файл по данному path, то весь path исчезнет и не нужно будет очищать пустой path.
Теперь также для чтения нам необходимо будет указать весь этот path. Давайте воспользуемся кодом ниже для чтения нашего .csv
из bucket
import pandas as pd
# Импорт из локальной переменной секретных данных
from cred import s3_minio_access_key, s3_minio_secret_key
bucket_name = 'test-local-bucket'
file_name = 'titanic.csv'
# file_name = 'raw/kaggle/2022-04-01/titanic.csv'
df = pd.read_csv(
filepath_or_buffer=f's3://{bucket_name}/{file_name}',
escapechar='\\',
storage_options={
"key": s3_minio_access_key,
"secret": s3_minio_secret_key,
# https://github.com/mlflow/mlflow/issues/1990#issuecomment-659914180
"client_kwargs": {"endpoint_url": "http://localhost:9000"},
},
compression='gzip'
)
print(df)
Вообще, все примеры того, как можно использовать S3 Minio описаны в официальном GitHub пакета.
В данной статье я показал только основы того как можно взаимодействовать с S3 для своих пет-проектов.
Вообще, S3 набирает популярность в дата-инженерии, потому что довольно простой по своей структуре сервис и покрывает множеств задач дата-инженеров.
Также S3 можно улучшать при помощи сторонних сервисов:
Apache Hudi
LakeFS
etc
Пишите в комментариях, что ещё хотели бы узнать про S3 и сервисы для дата-инженеров.
Также если вам необходима консультация/менторство/мок-собеседование и другие вопросы по дата-инженерии, то вы можете обращаться ко мне. Все контакты указаны по ссылке.