Статьи

SQL-запрос для данных смешанной схемы с использованием Apache Drill

Возможно, вы слышали это заявление раньше:

Apache Drill обнаруживает схемы на лету.

Что это значит, и почему это должно иметь значение для вас?

Возможности SQL для бизнес-аналитики само собой разумеющиеся, но проблема в настройках больших данных состоит в том, что SQL обычно является статическим языком, который предполагает заранее определенную, фиксированную и хорошо известную схему. SQL также нужны плоские структуры данных. Предполагалось, что вам нужна фиксированная схема для производительности. Напротив, работа в области больших данных требует гибкости и динамичности. Вы столкнетесь с широким спектром типов данных, включая неструктурированные и полуструктурированные данные, а также вложенные JSON и Parquet; эти форматы данных не подходят для традиционных подходов.

Усилия, необходимые для преобразования этих классов данных с целью запроса их с помощью SQL в традиционных базах данных (моделирование данных AKA), часто ставят эти источники данных за пределы в прагматическом смысле. Вот тут-то и появился инновационный дизайн Apache Drill с открытым исходным кодом. Используя стандартный синтаксис ANSI SQL, Drill легко и без большого количества дорогостоящей обработки ETL обрабатывает широкий спектр источников и форматов больших данных. Drill исследует и запрашивает данные как они есть, с существующими типами данных, взаимодействуя с использованием модели данных JSON.

В своем выступлении под названием «Оптимизация точно в срок» на конференции Strata + Hadoop World в Сан-Хосе Тед Даннинг, главный разработчик приложений в MapR, рассказал об этой проблеме и о том, как Drill решает ее. Тед пояснил, что Drill «переносит большую часть оптимизации и специфики типов из процессов анализа запросов и статической оптимизации в сам процесс выполнения» и делает это без необходимости заранее много знать о схеме. Кроме того, Drill может оптимизировать запросы к наборам данных с изменением схемы. Обработка данных с несколькими схемами важна для больших данных, потому что даже если данные начинаются с четко определенной схемы в первый день, обычно это происходит незадолго до изменения этой схемы. Результатом являются данные, которые не могут быть обработаны напрямую традиционными механизмами SQL. Тед подчеркнул эту мысль, сказав: «Drill объединяет сложность и знакомство с SQL с гибкостью экосистемы Hadoop».

Пример: SQL-запрос Apache Drill для данных смешанной схемы

Эта способность Drill обнаруживать метаданные схемы на лету имеет практические преимущества. Предположим, в розничной ситуации у вас есть таблица, в которой новая колонка для нового производства была добавлена ​​шесть месяцев назад. Вы хотели бы запросить более старые данные (без столбца) и более новые данные (со столбцом), используя один запрос. Drill может сделать это, потому что мутация схемы является основной особенностью.

Я спросил системного инженера Криса Матту о его опыте работы с клиентами MapR, которые используют Drill для решения аналогичных проблем. Он ответил: «Конечно, это происходит постоянно. Когда Drill перебирает новое поле, с которым он не сталкивался прежде, он включает его во все результаты, устанавливая для полей из данных без этого столбца значение NULL. Это то, что делает Drill таким мощным в реальном использовании и позволяет избежать необходимости поддерживать схему и использовать ETL для подгонки данных ». Далее Крис объяснил, что Drill работает со всеми подключаемыми плагинами хранения (и через них, если вы присоединяетесь).

Это заставило меня подумать, что было бы весело и полезно показать, как вы будете запрашивать два набора данных с разной схемой.

В одном вы знаете имя, компанию и должность человека. Позже вы узнаете, что некоторые из этих людей имеют секретную личность супергероя, поэтому вы добавляете столбец с этим идентификатором для добавляемых новых дел. При традиционных подходах к этим смешанным данным схемы будет трудно обращаться. Но с помощью Drill вы просто указываете свой запрос на старые и новые данные и отправляетесь.

Обратите внимание, что происходит в этих трех ситуациях:

  1. Запросите старые и новые наборы данных вместе: новый столбец был добавлен в новый набор данных, но Drill все еще может запрашивать как старые, так и новые данные, используя один запрос.
    Примечание: теперь, как select* обрабатывается при наличии переменной схемы. Эффект может быть не тем, что вы ищете.
  2. Маскировка: для некоторых людей существует секретная личность, поэтому вы можете захотеть замаскировать их настоящее имя. Это можно сделать с помощью дизайна запросов, все еще работающих со старыми и новыми данными. Пользователь увидит «-секретный» вместо имени, если человек супергерой с секретной идентификацией — это защищает его прикрытие.
  3. Представления Apache Drill для маскировки: представление Drill объединено в подражание. Это не удивительно, если вы работаете со стандартным SQL, но пользователи SQL-подобных инструментов, таких как Hive или Impala, могут удивиться. См. Также главу 3 « Безопасный обмен большими данными».

Вот как это выглядит (спасибо Теду Даннингу и Крису Матте за помощь с примером):

Имейте в виду, что файлы могут рассматриваться как таблицы. Часто мы собираем данные одним способом, а затем собираем больше данных в новом формате. Здесь у нас есть два файла, old.json и new.json . С помощью Drill мы можем запрашивать каждый из них, как если бы они были таблицей. Мы должны использовать источник данных, который обращается к данным, найденным в файловой системе, и мы должны поместить путь в обратные галочки, чтобы Drill не обрабатывал имя пути, как если бы это было какое-то выражение SQL или зарезервированное слово.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
0: jdbc:drill:> select * from maprfs.ted.`json/old.json`;
+---------------+-------------------+-------------------+--------------+
|       name    |       company     |       title       |       city   |
+---------------+-------------------+-------------------+--------------+
| Tony Stark    | Stark Industries  | Engineer; ex-CEO  | Malibu       |
| Pepper Potts  | Stark Industries  | CEO               | Los Angeles  |
| JARVIS        | Stark household   | Assistant         | Malibu       |
+---------------+-------------------+-------------------+--------------+
3 rows selected (0.369 seconds)
0: jdbc:drill:> select * from maprfs.ted.`json/new.json`;
+---------------+------------+--------------------+-----------------+--------------+
|       name    |  identity  |      company       |       title     |    city      |
+---------------+------------+--------------------+-----------------+--------------+
| Clark Kent    | Superman   | Daily Planet       | Reporter        | Metropolis   |
| Lois Lane     | null       | Daily Planet       | Reporter        | Metropolis   |
| Peter Parker  | Spiderman  | Empire State Univ  | Student         | New York     |
| Bruce Wayne   | Batman     | Wayne Enterprises  | Philanthropist  | Gotham City  |
+---------------+------------+--------------------+-----------------+--------------+
4 rows selected (0.344 seconds)

Обратите внимание, что у новых данных есть дополнительный столбец.

Запросить старый и новый наборы данных: несколько файлов в одной таблице

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

01
02
03
04
05
06
07
08
09
10
11
12
13
0: jdbc:drill:> select * from maprfs.ted.`json`;
+---------------+--------------------+-------------------+--------------+
|       name    |     company        |       title       |       city   |
+---------------+--------------------+-------------------+--------------+
| Tony Stark    | Stark Industries   | Engineer; ex-CEO  | Malibu       |
| Pepper Potts  | Stark Industries   | CEO               | Los Angeles  |
| JARVIS        | Stark household    | Assistant         | Malibu       |
| Clark Kent    | Daily Planet       | Reporter          | Metropolis   |
| Lois Lane     | Daily Planet       | Reporter          | Metropolis   |
| Peter Parker  | Empire State Univ  | Student           | New York     |
| Bruce Wayne   | Wayne Enterprises  | Philanthropist    | Gotham City  |
+---------------+--------------------+-------------------+--------------+
7 rows selected (0.368 seconds)

Если мы спросим, ​​мы можем включить столбец идентификаторов, упомянув его явно. Опять же, нам нужны обратные галочки, но на этот раз, потому что идентичность — это зарезервированное слово в SQL, но мы хотим трактовать его как имя поля.

01
02
03
04
05
06
07
08
09
10
11
12
13
0: jdbc:drill:> select name, company, `identity`, title, city from maprfs.ted.`json/*` ;
+---------------+--------------------+------------+-------------------+--------------+
|       name    |     company        |  identity  |          title    |     city     |
+---------------+--------------------+------------+-------------------+--------------+
| Tony Stark    | Stark Industries   | null       | Engineer; ex-CEO  | Malibu       |
| Pepper Potts  | Stark Industries   | null       | CEO               | Los Angeles  |
| JARVIS        | Stark household    | null       | Assistant         | Malibu       |
| Clark Kent    | Daily Planet       | Superman   | Reporter          | Metropolis   |
| Lois Lane     | Daily Planet       | null       | Reporter          | Metropolis   |
| Peter Parker  | Empire State Univ  | Spiderman  | Student           | New York     |
| Bruce Wayne   | Wayne Enterprises  | Batman     | Philanthropist    | Gotham City  |
+---------------+--------------------+------------+-------------------+--------------+
7 rows selected (0.304 seconds)

маскировка

Мы можем даже скрыть личность любого, кто известен как супергерой, используя немного причудливого SQL. Ни у кого из старого файла не будет известной личности супергероя, потому что тогда это не было записано. В новом файле любой, кто известен как супергерой, может скрыть свое имя. У Лоис Лейн нет идентичности супергероев (в этой таблице, то есть, игнорируя сложности альтернативных вселенных DC), поэтому, хотя она упоминается в новых данных, ее имя не маскируется.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
0: jdbc:drill:> select
. . . . . . . >    case
. . . . . . . >    when `identity` is null then name
. . . . . . . >    else ' -- secret --'
. . . . . . . >    end
. . . . . . . >    as name,
. . . . . . . >    company,
. . . . . . . >    `identity`,
. . . . . . . >    title,
. . . . . . . >    city
. . . . . . . > from maprfs.ted.`json`;
+----------------+--------------------+------------+-------------------+--------------+
|       name     |     company        |  identity  |      title        |     city     |
+----------------+--------------------+------------+-------------------+--------------+
| Tony Stark     | Stark Industries   | null       | Engineer; ex-CEO  | Malibu       |
| Pepper Potts   | Stark Industries   | null       | CEO               | Los Angeles  |
| JARVIS         | Stark household    | null       | Assistant         | Malibu       |
|  -- secret --  | Daily Planet       | Superman   | Reporter          | Metropolis   |
| Lois Lane      | Daily Planet       | null       | Reporter          | Metropolis   |
|  -- secret --  | Empire State Univ  | Spiderman  | Student           | New York     |
|  -- secret --  | Wayne Enterprises  | Batman     | Philanthropist    | Gotham City  |
+----------------+--------------------+------------+-------------------+--------------+
7 rows selected (0.374 seconds)

Использование Apache Drill Views для маскировки данных

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

01
02
03
04
05
06
07
08
09
10
11
12
0: jdbc:drill:> create view maprfs.ted.some_columns as select
. . . . . . . >    name,
. . . . . . . >    company,
. . . . . . . >    title,
. . . . . . . >    city
. . . . . . . > from maprfs.ted.`json`;
+-------+------------------------------------------------------------------+
|  ok   |                             summary                              |
+-------+------------------------------------------------------------------+
| true  | View 'some_columns' created successfully in 'maprfs.ted' schema  |
+-------+------------------------------------------------------------------+
1 row selected (0.494 seconds)

Получив представление Drill, вы можете использовать его как обычную таблицу, но не сможете получить доступ к данным в таблице, если они не отображаются в представлении; Выбор идентичности в представлении дает ошибку из-за неизвестного столбца.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
0: jdbc:drill:> select * from maprfs.ted.some_columns;
+---------------+--------------------+-------------------+--------------+
|     name      |     company        |     title         |     city     |
+---------------+--------------------+-------------------+--------------+
| Tony Stark    | Stark Industries   | Engineer; ex-CEO  | Malibu       |
| Pepper Potts  | Stark Industries   | CEO               | Los Angeles  |
| JARVIS        | Stark household    | Assistant         | Malibu       |
| Clark Kent    | Daily Planet       | Reporter          | Metropolis   |
| Lois Lane     | Daily Planet       | Reporter          | Metropolis   |
| Peter Parker  | Empire State Univ  | Student           | New York     |
| Bruce Wayne   | Wayne Enterprises  | Philanthropist    | Gotham City  |
+---------------+--------------------+-------------------+--------------+
7 rows selected (0.519 seconds)
0: jdbc:drill:>

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

1
2
3
4
5
6
7
0: jdbc:drill:> drop view maprfs.ted.some_columns;
+-------+---------------------------------------------------------------------+
|  ok   |                               summary                               |
+-------+---------------------------------------------------------------------+
| true  | View [some_columns] deleted successfully from schema [maprfs.ted].  |
+-------+---------------------------------------------------------------------+
1 row selected (0.489 seconds)

Внутренне представление — это просто еще один файл, который обрабатывается специально. Содержимое файла, который определяет представление, выглядит следующим образом

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[tdunning@se-node10 ~]$ cat some_columns.view.drill
{
  "name" : "some_columns",
  "sql" : "SELECT `name`, `company`, `title`, `city`\nFROM `maprfs`.`ted`.`json`",
  "fields" : [ {
      "name" : "name",
      "type" : "ANY",
      "isNullable" : true
  }, {
      "name" : "company",
      "type" : "ANY",
      "isNullable" : true
  }, {
      "name" : "title",
      "type" : "ANY",
      "isNullable" : true
  }, {
      "name" : "city",
      "type" : "ANY",
      "isNullable" : true
  } ],
  "workspaceSchemaPath" : [ ]
}
[tdunning@se-node10 ~]$

Как вы можете видеть, представление Drill написано в JSON и содержит наш оригинальный запрос и некоторую информацию о типе (которая просто говорит о том, что все имеет тип ANY, который является расширением Drill до SQL). Также возможно встроить путь рабочей области в представление, чтобы вашему пользователю не пришлось беспокоиться о том, где на самом деле расположены таблицы в запросе. Открытие разрешений для представления позволяет вам разрешить другим запрашивать ваше представление и, следовательно, лежащие в основе файлы, даже если они не могут запрашивать исходные файлы напрямую. Этот метод позволяет принудительно маскировать определенные данные для определенных пользователей.

Обратите внимание, что фраза «открытие разрешений» не используется ни в каком смысле базы данных. Это буквально вопрос изменения прав доступа к файлу, который содержит представление. То же самое верно, когда вы запрашиваете файлы — независимо от того, можете ли вы читать их с помощью Drill, определяется разрешениями для файла, как это было бы для любого другого способа чтения файлов.

Вывод

Apache Drill — это механизм запросов с открытым исходным кодом, который объединяет мощь стандартного SQL с гибкостью, необходимой для современных настроек больших данных. Он также предлагает несколько отличных способов поделиться или защитить личность супергероев. Подробнее о работе с Drill см. В следующих ресурсах.

Для начала загрузите песочницу Apache Drill. Чтобы узнать больше о представлениях Drill, см. Главу 3 Безопасного обмена большими данными © 2015 Тед Даннинг и Эллен Фридман (О’Рейли)

Для бесплатного онлайн-обучения с Drill перейдите сюда.