AWS Glue - Как настроить Crawler для создания таблицы с именами файлов S3 внутри - PullRequest
0 голосов
/ 06 марта 2019

Что мне нужно сделать: полнотекстовый поиск по ключам S3 (не по содержимому файлов)

Итак, моя корзина S3 имеет такую ​​структуру:

bucket_name/
  user1@gmail.com/
    folder1/
      notthatimportantfile
      ** any folders or files here

  user2@gmail.com/
    folderN/** any folders or files here
    folderN+1/notimportantfile
    folderX/mysuperimportantfile

И в моем приложении JS,Я хочу поставить поле поиска, в котором, если я наберу слово «важный», я получу обратно все файлы с этим словом в их именах

. Меня не интересуетсодержимое этих файлов.Поэтому я искал в Интернете, как это сделать, и ничего не нашел.

Последнее, что я попытался, - это использовать Amazon Glue и Athena, но когда я создаю Crawler и запускаю его внутри Glue, он создаетодна таблица на файл, и я хочу создать одну таблицу на папку первого уровня с файлами .Например, приведенная выше структура создаст в базе данных 2 таблицы: - user1@gmail.com - user2@gmail.com

И в этих таблицах их строки будут файлами внутри этих папок в S3:

  TABLE "user1@gmail.com"
     _id    filename                      size
     01234  folder1/notthatimportantfile  1024
     56789  folder1/anotherfile_here.txt  768

Имея это, я бы легко использовал AWS Athena для запроса данных:

SELECT * from 'user1@gmail.com' WHERE filename LIKE %important%

Итак, есть ли способ сделать это?я сумасшедший?Есть ли более простой способ?Может быть, AWS CloudSearch?

ПРИМЕЧАНИЕ для непрограммистов: не говорите: «Просто перейдите на консоль AWS и введите ключевое слово в поле поиска».Мне надоели эти ответы

1 Ответ

3 голосов
/ 08 марта 2019

Есть способ сделать это с Афиной, но я не могу рекомендовать это. Я включил это ниже.

В зависимости от вашего приложения есть разные способы сделать это. Если файлы меняются не часто, и вы не возражаете возвращать результаты, которым несколько часов, я бы предложил использовать S3 Inventory , он периодически записывает список всех объектов в корзине. Для поиска файла вы просматриваете последний манифест инвентаря, находите списки инвентаря и просматриваете их (вы даже можете использовать Athena для запроса инвентаря, для этого есть руководство в документации ).

Если вам нужно быть более свежим, S3 Inventory не будет работать, поскольку он будет создавать новый листинг не чаще одного раза в день.

Если это так, вы можете либо просто перечислить все файлы в вашем корзине для каждого поиска, в зависимости от числа файлов, о которых мы говорим, это может быть очень медленным или очень быстрым - будет менее 1000 файлов. очень быстро, но после этого вам придется выполнять несколько запросов, разбирающих страницы по 1000 объектов за раз, или придумывать способ выполнить несколько параллельных операций подкачки, перечисляя все объекты, начиная с a, в одном все операции начинаются с b в другом и т. д.

Наиболее экономичное решение, если вы хотите быть в курсе и иметь быстрые ответы, - это хранить отдельный индекс объектов в вашей корзине. Обновите индекс, прослушивая S3 Уведомления о событиях . Прослушайте как создания, так и удаления и обновите индекс соответствующим образом Вы можете использовать ElasticSearch, Algolia или Postgres или любой другой сервис или базу данных с приличными полнотекстовыми возможностями для индекса - но это будет гораздо больше инфраструктуры для настройки, чем просто S3, конечно.


Если вы абсолютно хотите сделать это с Athena, это может быть сделано, но это не будет самым эффективным решением, и если у вас много файлов и они содержат много данных, это может в конечном итоге стоить вам немного, так что будьте осторожны.

Во всех таблицах Athena есть скрытый столбец с именем $path, который содержит полный URI объекта S3, из которого была прочитана строка. Может использоваться и для фильтрации.

Если вы создадите такую ​​таблицу:

CREATE EXTERNAL TABLE `listing` (`ignored` string)
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://bucket_name/'
TBLPROPERTIES ('has_encrypted_data'='false')

это просто таблица с фиктивным столбцом, она может называться как угодно, она просто есть, потому что невозможно создать таблицу без столбцов. Просто убедитесь, что LOCATION правильно.

Для поиска объектов это то, что вы делаете:

SELECT DISTINCT "$path"
FROM listing
WHERE "$path" LIKE '%foo%'

Хотя это может выглядеть аккуратно и решить вашу проблему, это ужасно неэффективный и дорогой способ сделать это. Афина перечислит все файлы в вашем ведре, затем прочитает их все, и вам придется заплатить как за операции S3, так и за отсканированные данные. Даже если Афина в конце концов только смотрит на клавиши S3, она не имеет никакой оптимизации, которая мешает ей читать их все.

...