Совершенно логично, что если вы наберете aws s3 ls s3://my-bucket для вывода содержимого корзины S3, вы ожидаете, что подключитесь к подлинной корзине и увидите ее содержимое.

Но у вас нет жесткого правила иметь для подключения к настоящему сегменту. Фактически, есть простой параметр, который вы можете передать в приведенную выше команду CLI, чтобы вместо этого легко подключиться к любому URL-адресу по вашему выбору.

Учтите следующее:

$ aws s3 ls s3://my-bucket --endpoint-url http://localhost:5000

Обратите внимание на включение аргумента --endpoint-url, указывающего на localhost на порту 5000? Вместо того, чтобы перечислять содержимое my-bucket на каком-то сервере AWS где-нибудь, мы вместо этого проверим наш собственный компьютер на наличие ресурса, похожего на ведро, который может отвечать на команду ls.

Возникает вопрос: зачем AWS предоставлять такой параметр и зачем нам вообще его использовать?

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

Пример использования №1: локальное тестирование

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

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

Запустив локальный экземпляр сервиса AWS, а затем установив для параметра endpoint_url в коде значение localhost и правильный порт, мы можем эффективно смоделировать сервис безболезненно.

Давайте посмотрим на это в действии.

Пример использования мото

В качестве полноценного примера я укажу на отличную moto docs - пакет, созданный специально для имитации сервисов AWS.

В Moto есть режим автономного сервера, что делает его работу особенно понятной. После установки пакета запустите локальный мото-сервер:

$ moto_server s3
 * Running on http://127.0.0.1:5000/

Затем в фрагменте кода мы можем использовать endpoint_url, чтобы указать на локальный экземпляр moto S3:

mock_s3 = boto3.resource(
    service_name='s3',
    region_name='us-east-1',
    endpoint_url='http://localhost:5000',
)

Теперь мы можем выполнять любые операции с объектом mock_s3, не беспокоясь об изменении содержимого фактического сегмента.

Пример использования # 2: бесшовная интеграция

Учитывая рост облака, неудивительно, что API-интерфейсы для облачных сервисов также стали повсеместными. Хорошо это или плохо, но сейчас AWS S3 API является стандартом де-факто в мире объектных хранилищ. [1]

Когда несколько технологий принимают один и тот же стандарт, уходит боль от интеграции каждой попарной комбинации.

LakeFS, MinIO и Ceph - это примеры технологий, говорящих на языке S3. Или, говоря точнее, они поддерживают совместимость с значимым подмножеством S3 API.

В результате любой инструмент, который ожидает подключения к S3, также может легко интегрироваться с этими инструментами… через URL-адреса конечных точек!

Пример использования Spark и lakeFS

Spark - это пример технологии, которая часто взаимодействует с S3. Чаще всего считывание данных в DataFrame, выполнение некоторого преобразования, а затем их запись обратно в S3.

lakeFS разработана для расширения функциональности озер данных над хранилищем объектов, делая возможными такие операции, как ветвление, слияние и возврат.

Если вы хотели воспользоваться преимуществами как Spark, так и lakeFS, и у вас не было возможности устанавливать пользовательские URL-адреса конечных точек, необходимо было бы разработать индивидуальную интеграцию между ними.

К счастью, с настраиваемыми конечными точками интеграция становится однострочным, указывая конечную точку Spark S3 на установку lakeFS:

spark.sparkContext.hadoopConfiguration.set("fs.s3a.endpoint", "https://s3.lakefs.example.com")

Теперь доступ к данным в lakeFS из Spark точно такой же, как доступ к данным S3 из Spark!

Последние мысли

Хотя это всего лишь введение в эту тему, надеюсь, вы лучше понимаете, что такое URL-адреса конечных точек и когда имеет смысл изменить их значение по умолчанию.

Примечание. Эта статья была впервые опубликована в блоге lakeFS 20.04.21.