Инфраструктура для data engineer S3

от автора

В этой статье я бы хотел рассказать о такой технологии как 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 вы можете проверить наличие файла

Наличие файла titanic.csv

Наличие файла titanic.csv

Важное свойство, которое стоит знать при работе с path в bucket – это то что можно указать свой path руками. Если посмотреть на пример выше, то у нас path выглядит так:
file_name = 'titanic.csv', но можно задать любой path, для примера вот так: file_name = 'raw/kaggle/2022-04-01/titanic.csv'
и получим в bucket такую структуру:

Прописанный путь руками к titanic.csv

Прописанный путь руками к titanic.csv

Также стоит отметить, что если мы удалим файл по данному 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 можно улучшать при помощи сторонних сервисов:

  1. Apache Hudi

  2. LakeFS

  3. etc

Пишите в комментариях, что ещё хотели бы узнать про S3 и сервисы для дата-инженеров.

Также если вам необходима консультация/менторство/мок-собеседование и другие вопросы по дата-инженерии, то вы можете обращаться ко мне. Все контакты указаны по ссылке.


ссылка на оригинал статьи https://habr.com/ru/articles/827052/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *