Перейти к основному содержимому
Перейти к основному содержимому

Движки таблиц Executable и ExecutablePool

Движки таблиц Executable и ExecutablePool позволяют вам определить таблицу, строки которой генерируются из скрипта, который вы определяете (путем записи строк в stdout). Исполняемый скрипт хранится в директории users_scripts и может читать данные из любого источника.

  • Таблицы Executable: скрипт выполняется при каждом запросе
  • Таблицы ExecutablePool: поддерживают пул постоянных процессов и используют процессы из пула для чтения

Вы можете дополнительно включить один или несколько входных запросов, которые передают свои результаты в stdin для чтения скриптом.

Создание таблицы Executable

Движок таблицы Executable требует два параметра: имя скрипта и формат входящих данных. Вы можете дополнять один или несколько входных запросов:

Вот соответствующие настройки для таблицы Executable:

  • send_chunk_header
    • Описание: Отправлять количество строк в каждом чанке перед отправкой чанка на обработку. Эта настройка может помочь вам более эффективно написать ваш скрипт для предварительного выделения некоторых ресурсов
    • Значение по умолчанию: false
  • command_termination_timeout
    • Описание: Время ожидания завершения команды в секундах
    • Значение по умолчанию: 10
  • command_read_timeout
    • Описание: Время ожидания для чтения данных из stdout команды в миллисекундах
    • Значение по умолчанию: 10000
  • command_write_timeout
    • Описание: Время ожидания для записи данных в stdin команды в миллисекундах
    • Значение по умолчанию: 10000

Посмотрим на пример. Следующий скрипт на Python называется my_script.py и сохранен в папке user_scripts. Он считывает число i и выводит i случайных строк, каждая строка предваряется номером, отделенным табуляцией:

Следующая таблица my_executable_table строится на основе вывода my_script.py, который будет генерировать 10 случайных строк каждый раз, когда вы выполняете SELECT из my_executable_table:

Создание таблицы возвращает результат сразу и не вызывает скрипт. Запрос к my_executable_table вызывает выполнение скрипта:

Передача результатов запросов в скрипт

Пользователи сайта Hacker News оставляют комментарии. Python содержит набор инструментов обработки естественного языка (nltk) с SentimentIntensityAnalyzer для определения, являются ли комментарии положительными, отрицательными или нейтральными - включая выставление значения между -1 (очень отрицательный комментарий) и 1 (очень положительный комментарий). Давайте создадим таблицу Executable, которая рассчитывает настроение комментариев Hacker News с использованием nltk.

Этот пример использует таблицу hackernews, описанную здесь. Таблица hackernews включает в себя столбец id типа UInt64 и столбец String с именем comment. Начнем с определения таблицы Executable:

Некоторые комментарии по поводу таблицы sentiment:

  • Файл sentiment.py сохранен в папке user_scripts (стандартная папка настройки user_scripts_path)
  • Формат TabSeparated означает, что наш скрипт на Python должен генерировать строки необработанных данных, содержащие табуляции
  • Запрос выбирает два столбца из hackernews. Скрипт на Python должен будет разобрать эти значения столбцов из входящих строк

Вот определение sentiment.py:

Некоторые комментарии по поводу нашего скрипта на Python:

  • Для этого вам нужно будет выполнить nltk.downloader.download('vader_lexicon'). Это можно было бы разместить в скрипте, но тогда он скачивался бы каждый раз, когда выполнялся запрос к таблице sentiment - что неэффективно
  • Каждое значение row будет строкой в результирующем наборе данных SELECT id, comment FROM hackernews WHERE id > 0 AND comment != '' LIMIT 20
  • Входная строка разделяется табуляцией, поэтому мы разбираем id и comment с помощью функции split Python
  • Результат polarity_scores - это объект JSON с несколькими значениями. Мы решили просто взять значение compound этого объекта JSON
  • Напоминаем, что таблица sentiment в ClickHouse использует формат TabSeparated и содержит два столбца, поэтому наша функция print разделяет эти столбцы табуляцией

Каждый раз, когда вы выполняете запрос, который выбирает строки из таблицы sentiment, выполняется запрос SELECT id, comment FROM hackernews WHERE id > 0 AND comment != '' LIMIT 20, и результат передается в sentiment.py. Давайте протестируем это:

Ответ выглядит так:

Создание таблицы ExecutablePool

Синтаксис для ExecutablePool схож с Executable, но есть несколько соответствующих настроек, уникальных для таблицы ExecutablePool:

  • pool_size
    • Описание: Размер пула процессов. Если размер 0, то ограничения по размеру отсутствуют
    • Значение по умолчанию: 16
  • max_command_execution_time
    • Описание: Максимальное время выполнения команды в секундах
    • Значение по умолчанию: 10

Мы можем легко преобразовать таблицу sentiment выше, чтобы использовать ExecutablePool вместо Executable:

ClickHouse будет поддерживать 4 процесса по мере необходимости, когда ваш клиент запрашивает таблицу sentiment_pooled.