Блог Amazon Web Services

SQL-запросы к данным без серверов и СУБД с помощью Amazon S3 Select

Оригинал статьи: ссылка (David Green, Principal Serverless Solutions Architect и Mustafa Rahimi, Enterprise Solutions Architect)

Как AWS Solution Architect, мы ежедневно сталкиваемся с разными заказчиками и сценариями использования облачных технологий. Однако у многих из них похожие запросы: клиенты хотят уменьшить издержки на управление серверами, а также снизить сложность развертывания и поддержки инфраструктуры. И это понятно, они сфокусированы на эффективности своего бизнеса.

У большинства заказчиков рано или поздно встает задача поиска среди большого объема данных, и это требуется сделать простым решением, без систем влекущих за собой высокие издержки. В этой статье мы рассмотрим использование SQL-запросов для работы с данными в CSV, JSON или Apache Parquet форматах, загруженными на Amazon Simple Storage Service (Amazon S3). Раньше, для того чтобы делать запросы к данным, необходимо было сначала загрузить их в какую-либо базу данных (СУБД). Мы же обойдемся без этого и, вместо развертывания баз данных и сопутствующих приложений, воспользуемся возможностью S3 под названием S3 Select. Мы продемонстрируем такой подход на примере поиска по телефонной книге, хранящийся в CSV файле. Полный код примера доступен на GitHub.

Amazon S3 используется для хранения любого объема данных без необходимости резервирования серверов и управления инфраструктурой. Amazon S3 Select и Amazon S3 Glacier Select позволяют напрямую выполнять SQL-запросы к CSV, JSON и Apache Parquet файлам, лежащим на S3 и Amazon S3 Glacier. При использовании S3 Select вы просто загружаете данные на S3, и выполняете SQL-запросы для фильтрации содержимого S3 объектов, получая на выходе нужные вам результаты. Запрашивая только необходимое подмножество хранящейся информации, вы уменьшаете объем передаваемых от Amazon S3 данных, что также уменьшает время и стоимость передачи. А уменьшение сложности, достигаемое благодаря такому решению, положительно влияет на скорость разработки.

S3 Select поддерживает сжатие CSV и JSON объектов с помощью GZIP и BZIP2, а также шифрование на стороне сервера. Вы можете выполнять SQL-запросы с помощью AWS SDK для поддерживаемых языков программирования, SELECT Object Content REST API, инструментов командной строки AWS Command Line Interface (AWS CLI), а также с помощью web консоли AWS Management Console.

Используемые AWS сервисы

Пример приложения для поиска в телефонной книге использует следующие сервисы:

  • Amazon S3 – объектное хранилище, обеспечивающее высокую доступность и производительность, фактически неограниченное масштабирование и, конечно, высокий уровень безопасности.
  • S3 Select – сервис, позволяющий получать подмножество данных из S3-объектов (файлов), выполняя простые SQL-запросы.

Кроме S3 и S3 Select наш пример приложения поиска в телефонной книге использует и другие сервисы:

  • Amazon API Gateway – полностью управляемый (managed) сервис, позволяющий легко создавать, управлять, поддерживать и производить мониторинг защищенных API. Amazon API Gateway часто используют в serverless приложениях, и в нашем примере он используется для взаимодействия с AWS Lambda.
  • AWS Lambda позволяет запускать код без развертывания и управления серверами. В нашем примере S3 Select запросы выполняются в AWS Lambda.
  • AWS CloudFormation предоставляет язык для декларативного моделирования и развертывания AWS (а также сторонних) ресурсов, в облаке. CloudFormation используется в нашем примере для организации развертывания ресурсов, необходимых для примера.

Код проекта

Полный код примера приложения для поиска в телефонной книге доступен в GitHub репозитории AWS-Samples. Работа Amazon S3 Select, используемого в примере, описывается далее.

Начало работы, загрузка данных

Так как S3 Select работает напрямую с данными, хранящимися на S3, все, что вам нужно для начала работы — это AWS аккаунт и S3 бакет.

Войдите в существующий аккаунт или создайте новый. После того, как вы вошли в аккаунт, создайте S3 бакет, который будет использоваться для тестирования работы S3 Select.

Данные, которые мы будем использовать, представляют собой простой CSV файл, содержащий Имя, Номер Телефона, Город и Должность тестовых пользователей. Файл доступен в GitHub репозитории. Содержимое файла представлено далее, вы можете его дополнять и редактировать.

Name,PhoneNumber,City,Occupation
Sam,(949) 555-6701,Irvine,Solutions Architect
Vinod,(949) 555-6702,Los Angeles,Solutions Architect
Jeff,(949) 555-6703,Seattle,AWS Evangelist
Jane,(949) 555-6704,Chicago,Developer
Sean,(949) 555-6705,Chicago,Developer
Mary,(949) 555-6706,Chicago,Developer
Kate,(949) 555-6707,Chicago,Developer

Загрузите файл sample_data.csv в ваш новый S3 бакет, созданный на предыдущем шаге.

Протестируем выполнение S3 Select запросов к файлу sample_data.csv с помощью Python скрипта. В примере используется имя бакета “s3select-demo”, вам необходимо заменить его на имя созданного вами бакета, куда был загружен файл.

Для быстрого тестирования скрипта мы развернем t3.micro EC2 инстанс с Amazon Linux 2 и установим на него boto3 – AWS SDK для Python. Проверьте, что IAM роль, назначенная EC2 инстансу, имеет доступ к созданному вами S3 бакету.

Выполняем S3 Select запросы из EC2 инстанса

После того, как вы создали и запустили EC2 инстанс, войдите на него по SSH как пользователь ec2-user, и запустите следующие команды для установки зависимостей и загрузки скриптов.

sudo yum update -y
sudo yum install python3 -y
python3 -m venv ~/s3select_example/env
source ~/s3select_example/env/bin/activate
pip install pip --upgrade
pip install boto3
wget https://raw.githubusercontent.com/aws-samples/s3-select-phonebook-search/master/src/samples/jane.py
wget https://raw.githubusercontent.com/aws-samples/s3-select-phonebook-search/master/src/samples/jane-gzip.py

Команды создают Python 3 environment и скачивают скрипт jane.py, содержимое которого представлено далее. Скрипт позволяет искать пользователей с именем Jane. Замените имя S3 бакета из скрипта, на имя созданного вами S3 бакета.

import boto3

s3 = boto3.client('s3')

resp = s3.select_object_content(
    Bucket='s3select-demo',
    Key='sample_data.csv',
    ExpressionType='SQL',
    Expression="SELECT * FROM s3object s where s.\"Name\" = 'Jane'",
    InputSerialization = {'CSV': {"FileHeaderInfo": "Use"}, 'CompressionType': 'NONE'},
    OutputSerialization = {'CSV': {}},
)

for event in resp['Payload']:
    if 'Records' in event:
        records = event['Records']['Payload'].decode('utf-8')
        print(records)
    elif 'Stats' in event:
        statsDetails = event['Stats']['Details']
        print("Stats details bytesScanned: ")
        print(statsDetails['BytesScanned'])
        print("Stats details bytesProcessed: ")
        print(statsDetails['BytesProcessed'])
        print("Stats details bytesReturned: ")
        print(statsDetails['BytesReturned'])

Параметр OutputSerialization имеет значение CSV, поэтому результат будет возвращен в CSV формате. Также можно получать результат в формате JSON.

После изменения имени S3 бакета в файле jane.py, запустите скрипт, используя следующую команду

python jane.py 

Результат выполнения скрипта показан далее:

Jane,(949) 555-6704,Chicago,Developer

Stats details bytesScanned:
326
Stats details bytesProcessed:
326
Stats details BytesReturned:
38

Найдена одна запись для пользователя с именем Jane. Также скрипт выводит объем просканированных, обработанных и возвращенных S3 Select данных. В нашем случае размер фала sample_data.csv – 326 байт, S3 Select сканирует весь файл и возвращает одну строку размером 38 байт.

S3 Select и сжатые данные

Давайте запустим тот же самый тест ещё раз, но теперь со сжатыми данными. Сожмите CSV файл адресной книги с помощью gzip, назовите файл sample_data.csv.gz, и загрузите его на S3. Предварительно сжатый файл можно скачать с GitHub.

Для работы с новым файлом нам потребуется модифицировать Python скрипт. В качестве значения параметра Key мы укажем имя сжатого файла, а также изменим InputSerialization CompressionType c None на GZIP. Новая версия скрипта, jane-gzip.py, доступна в репозитории, а также была скачена нами при настройке EC2 инстанса.

Мы поменяли имя S3 ключа (имя файла) на имя сжатого файла sample_data.csv.gz:

Key='sample_data.csv.gz',

Кроме того, мы поменяли строку с параметром InputSerialization чтобы указать значение GZIP для CompressionType.

InputSerialization = {'CSV': {"FileHeaderInfo": "Use"}, 'CompressionType': 'GZIP'},

Полный код файла jane-gzip.py представлен далее. Обратите внимание, что вам требуется заменить имя S3 бакета в скрипте на имя созданного вами бакета.

import boto3

s3 = boto3.client('s3')

resp = s3.select_object_content(
    Bucket='s3select-demo',
    Key='sample_data.csv.gz',
    ExpressionType='SQL',
    Expression="SELECT * FROM s3object s where s.\"Name\" = 'Jane'",
    InputSerialization = {'CSV': {"FileHeaderInfo": "Use"}, 'CompressionType': 'GZIP'},
    OutputSerialization = {'CSV': {}},
)

for event in resp['Payload']:
    if 'Records' in event:
        records = event['Records']['Payload'].decode('utf-8')
        print(records)
    elif 'Stats' in event:
        statsDetails = event['Stats']['Details']
        print("Stats details bytesScanned: ")
        print(statsDetails['BytesScanned'])
        print("Stats details bytesProcessed: ")
        print(statsDetails['BytesProcessed'])
        print("Stats details bytesReturned: ")
        print(statsDetails['BytesReturned'])

Выполните скрипт следующей командой. Будет осуществлен S3 Select SQL-запрос к сжатым данным.

python jane-gzip.py

Результат выполнения скрипта представлен ниже.

Jane,(949) 555-6704,Chicago,Developer

Stats details bytesScanned:
199
Stats details bytesProcessed:
326
Stats details bytesReturned:
38

Сравнение результатов запроса к сжатым и не сжатым данным

Использование сжатия позволяет сократить объем данных, хранящихся на S3. В случае нашего маленького CSV файла для теста, сжатие позволило сократить размер файла на 39%.

Таблица далее показывает разницу между запросами к не сжатому файлу sample_data.csv и сжатому sample_data.csv.gz.

Размер файла (байт) Просканировано байт Обработано байт Возвращено байт Разница
Не сжатые данные 326 326 326 38 N/A
Сжатые данные 199 199 326 38 ~39% меньше

Преимущества сжатия данных становятся более существенны в случае больших файлов. Например, CSV файл размером 133,975,755 байт (~128 MB), состоящий из примерно миллиона строк, может быть уменьшен на ~ 60% до 50,308,104 байт (~50.3 MB) при использовании GZIP сжатия.

Размер файла (байт) Просканировано байт Обработано байт Возвращено байт Разница
Не сжатые данные 133,975,755 133,975,755 133,975,755 6 N/A
Сжатые данные 50,308,104 50,308,104 133,975,755 6 ~60% меньше

Запросы к архивам с S3 Glacier Select

Когда вы создаете SQL-запросы к архивным объектам, хранящимся в S3 Glacier, S3 Glacier Select выполняет запрос прямо в архиве, и возвращает результат в Amazon S3. С S3 Glacier Select вы можете запускать запросы к данным, находящимся в S3 Glacier, без необходимости восстанавливать эти данные на более “горячий” уровень, такой как S3 Standard.

Для выполнения SELECT запросов, S3 Glacier предлагает на выбор три уровня доступа к данным: expedited, standard, и bulk. Каждый из этих уровней имеет разное время доступа и цену, и вы можете выбрать один из них, в зависимости от того, как быстро вам нужно получить данные. Для архивов менее 250 мегабайт при использовании expedited уровня доступа, данные из S3 Glacier обычно доступны в течение 1-5 минут. В случае стандартного уровня это время увеличивается до 3-5 часов, для bulk оно составляет 5-12 часов.

Заключение

Мы показали, как S3 Select позволяет простым образом выполнять SQL-запросы напрямую к данным, хранящимся в Amazon S3 и Amazon S3 Glacier. S3 Select часто используется когда нужно обработать данные, которые были загружены на S3 програмно, или с помощью таких сервисов как AWS Transfer for SFTP (AWS SFTP). Например, вы можете загрузить данные на S3 c помощью AWS SFTP, а потом сделать выборку данных с помощью S3 Select. S3 Select запрос может быть выполнен из AWS Lambda функции, которая будет автоматически вызываться по событию загрузки нового файла на S3. Фильтрация данных с помощью S3 Select потенциально позволяет вам сэкономить вам время и деньги, по сравнению с другими способами фильтрации, когда данные сначала загружаются в базу.

Для того чтобы лучше освоить работу с S3 Select и другими сервисами рекомендуем вам изучить GitHub репозиторий AWS Samples. Там вы можете найти полный пример приложения поиска в телефонной книге. Этот пример выполняет S3 Select запросы из AWS Lambda функции, выставленной наружу с помощью Amazon API Gateway.

Очистка аккаунта

В нашем примере мы создали S3 бакет и загрузили туда файлы sample_data.csv и sample_data.csv.gz. Мы осуществляли запросы из t3.micro EC2 инстанса. Для того чтобы избежать лишних трат, выключите EC2 инстанс и удалите его, выбрав terminate. А также удалите файлы из S3 бакета. Вы можете удалить и сам S3 бакет.

Дополнительные ресурсы