Skip to content

Instantly share code, notes, and snippets.

@alexey-milovidov
Last active October 8, 2022 23:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexey-milovidov/6735d193762cab1ad3b6e6af643e3a43 to your computer and use it in GitHub Desktop.
Save alexey-milovidov/6735d193762cab1ad3b6e6af643e3a43 to your computer and use it in GitHub Desktop.

Дополнительные индексные структуры для пропуска блоков данных в таблицах.

Secondary index structures for data skipping in ClickHouse DBMS.

Done 🚀

  • Эту задачу взял Никита Васильев

В большинстве СУБД есть возможность создавать вторичные индексы. Вторичный индекс обычно представляет собой дерево, которое позволяет найти расположение записей по некоторому ключу. Но в аналитических СУБД вторичные индексы редко применяются в чистом виде.

Причина состоит в том, что для одного запроса требуется, как правило, прочитать большое количество записей - в этом случае мы могли бы найти эти записи по индексу, но прочитать их с диска было бы всё-равно сложно: если данные не расположены более-менее локально, то для их чтения пришлось бы делать много дисковых seek-ов и разжимать много сжатых блоков. Поэтому в ClickHouse (и в других похожих системах) есть только один индекс, по которому данные более-менее упорядочиваются (clustered index), что обеспечивает возможность эффективно читать диапазоны по этому ключу.

Вторая причина состоит в том, что в аналитических БД как правило строчки достаточно мелкие и при этом есть большое количество строк на один сервер. Если уметь адресовать каждую строку, то индекс получается слишком громоздким. Вместо этого используется разреженный индекс - который адресует не каждую строку, а только дипазоны в сортированных данных.

Тем не менее, вместо индекса "в чистом виде", можно реализовать некоторые маленькие структуры, которые позволят пропускать отдельные блоки данных (data skipping). Суть в том, что на каждый блок данных сохраняется ещё небольшая выжимка. Примеры:

  • minmax индекс - минимальное и максимальное значение столбца в блоке;
  • список всех уникальных значений, если столбец имеет мало уникальных значений (например, меньше 10);
  • небольшой bloom filter из всех значений; для строк можно использовать триграмный bloom filter для поиска подстрок.

Методы индексации данных на основе space filling curves.

Data indexing methods with space filling curves in ClickHouse DBMS.

  • Эту задачу взял Андрей Чулков

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

Часто при проектировании базы данных в ClickHouse, трудно выбрать порядок столбцов ключа в кортеже. Для примера, в базе данных рекламной системы, ключевыми столбцами является идентификатор рекламодателя (кто заказывал рекламу) и идентификатор рекламной площадки (на каком сайте размещена реклама). Отчёты надо строить иногда для рекламодателя, а иногда - для рекламной площадки. То есть, первым столбцом в ключе может быть или тот, или другой идентификатор. В этом случае разумным является выбрать такой порядок столцбов, от которого будут выигрывать большинство запросов; а другие запросы будут выполняться медленно. Либо хранить таблицу в двух вариантах (копиях).

Тем не менее возникает вопрос - можно ли упорядочить данные по некоторому отношению порядка, которое будет средним (компромиссным) между несколькими вариантами, и будет работать хорошо в обеих случаях? Ответом на этот вопрос являются space filling curves. https://en.wikipedia.org/wiki/Z-order_curve В результате, если данные упорядочивать по z(attr1, attr2...), то мы получим нечто среднее между упорядочиванием данных по одному атрибуту и по другому атрибуту.

Для реализации предстоит решить несколько проблем.

  1. Если в таблице ключом является выражение z(x, y), то индекс должен работать, если в запросе указано условие на x или на y. Для этого потребуется уметь вычислять обратное отображение диапазонов для некоторых функций.
  2. Равномерному смешиванию локальности расположения данных может мешать неравномерность распределения значений смешиваемых атрибутов. Для того, чтобы это обойти, мы будем вычислять space filling curve с некоторыми хитрыми эвристиками.

Умные алгоритмы обработки строк в ClickHouse.

Algorithms for smart string processing in ClickHouse DBMS.

Done 🚀

  • Эту задачу взял Данила Кутенин

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

Не смотря не это, ClickHouse часто используется в сценариях, предполагающих поиск по тексту. Например, для этого в ClickHouse реализован эффективный (brute-force) поиск подстроки в строке. Но многих алгоритмов не хватает.

  1. Для начала, сделаем эффективную проверку наличия любой из (явно заданного) множества подстрок. Как вы уже знаете, для этого есть такие алгоритмы как Aho-Corasick, Rabin-Karp. Но мы попробуем сделать кое что ещё лучше, и использовать алгоритм multi-Volnitsky, который ещё никто не реализовывал.

  2. Для brute-force поиска подстроки в строке, нужно по крайней мере прочитать те строки (haystack), в которых мы хотим искать. А можно ли сделать какую-нибудь выжимку из haystack, чтобы проверять гипотезу наличия подстроки быстрее? Мы попробуем добавить в ClickHouse функцию, которая построит для строки триграмный bloom filter. Полученную выжимку можно будет записать в отдельный столбец, чтобы быстрее его сканировать, и исключать сканирование исходных строк в большинстве случаев. А может быть, вы сможете придумать трюки с суффиксными массивами.

  3. Для одной из задач нам нужно locality-sensitive хэширование строк. Это такая хэш-функция, которая при небольших изменениях аргумента, как правило, не меняется. Для этого реализуем алгоритм хорошо оптимизированный алгоритм min-hash. https://en.wikipedia.org/wiki/MinHash

Методы машинного обучения (регрессии, классификации) как агрегатные функции.

Machine learning methods (regression, classification) as aggregate functions in ClickHouse DBMS.

Done 🚀

  • Эту задачу взяла команда: Кожихов Александр, Кузнецов Максим, Конькова Мария.

Агрегатные функции - это функции над множеством (потоком) данных. Примеры: сумма, среднее, гистограмма... Одно из преимуществ архитектуры ClickHouse состоит в том, что состояния вычислений агрегатных функций являются "first class citizens". Вы можете получить промежуточное состояние вычисления агрегатной функции как полноценное значение: сохранить его в таблицу, проводить с ним всевозможные манипуляции. Это может использоваться, например, для инкрементальной агрегации потоков данных.

В связи с этим яляется интересной идеей оформить простые методы регрессии и классификации в виде агрегатных функций. Состояния агрегатных функций будут обновляться (обучаться) по потоку данных, который им передаётся. Одновременно с этим, текущее состояние агрегатной функции можно использовать в виде обученной формулы. Таким образом мы получим возможность онлайн обучения в ClickHouse путём создания агрегирующего materialized view над таблицей.

Сначала мы добавим наиболее простые методы - линейную и логистическую регрессию, байесовский классификатор; а затем любые алгоритмы на ваш вкус.

Словари полигонов и geospatial структур.

Polygonal and geospatial dictionaries in ClickHouse DBMS.

Done 🚀

  • Эту задачу взял Максим Сабянин

ClickHouse не является geospatial СУБД. Тем не менее, в ClickHouse есть несколько функций для таких задач. Например, функция pointInPolygon позволяет быстро проверить попадание точек в полигон на плоскости. При этом, полигон задаётся в явном виде и должен быть константным для вызова функции (то есть - проверяется принадлежность многих точек одному полигону). Эта функциональность нужна, например, для рекламного таргетинга мобильных устройств по координатам.

Похожая, но более сложная задача, которую ClickHouse пока не умеет решать - определение полигона среди множества полигонов, в которые попадают точки. Для примера: определение района города по географическим координатам. Для решения этой задачи нужно будет реализовать поддержку словарей с полигонами, в которых данные проиндексированы для быстрого поиска.

TTL (настраиваемое время хранения) данных в таблицах ClickHouse и в отдельных столбцах.

Implementation of TTL for tables and columns in ClickHouse.

Done 🚀

  • Эту задачу взял Антон Попов

Есть потребность настроить время жизни данных в таблице (пример: храним логи 10 дней), а также отдельных столбцов в таблице (пример: храним данные вечно, но IP адрес удаляем через сутки).

Технической сложностью данной задачи является то, что данные в ClickHouse хранятся в виде неизменяемых кусков. Удалить что-то из куска данных невозможно; можно только создать новый кусок данных и заменить им старый, или же просто удалить кусок целиком. Такие операции в ClickHouse уже производятся - это слияния сортированных кусков в фоне. Для решения задачи, потребуется назначать эти слияния с учётом TTL.

Профилирование и трассировка на уровне отдельных запросов.

Fine grained query tracing and profiling in ClickHouse.

Done 🚀

  • Эту задачу взял Никита Лапков

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

Для начала мы встроим в ClickHouse сэмплирующий профайлер уровня запроса. С указанной периодичностью (согласно cpu time или wall clock time), в потоках выполнения запроса будут собираться стек трейсы и записываться в отдельную системную таблицу, что позволит построить профиль (например, в виде flame graph) отдельных запросов.

Далее мы попробуем обобщить счётчики производительности, ограничения на использования ресурсов, и трейспоинты. Трейспоинты позволяют динамически добавлять вызов нужного кода в определённые места в программе. Это может быть логгирование, sleep или fault injection для отладки. Одновременно с этим попробуем воспользоваться функциональностью X-Ray, доступной в LLVM.

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

Модельная реализация интерфейса ZooKeeper для тестирования.

Model ZooKeeper interface implementation for testing and fault injection in ClickHouse.

Done 🚀

  • Эту задачу взял Алексей Левушкин

Для координации реплик в ClickHouse используется ZooKeeper. Многие пользователи ClickHouse хотели бы иметь возможность использовать для координации некоторые другие системы вместо ZooKeeper. Рассматриваемыми вариантами таких систем являются Etcd, Consul, FoundationDB. Это весьма проблематично, так как эти системы существенно отличаются по интерфейсам и возможностям.

Тем не менее, для того, чтобы эта задача стала возможной, в ClickHouse обобщён интерфейс взаимодействия с ZooKeeper, и теперь на его место можно подставлять другие реализации. В первую очередь, это полезно для тестирования. Хотя в ClickHouse есть интеграционные тесты, поднимающие кластер и эмулирующие network partitions, они довольно громоздкие, и для тестирование корректности использования интерфейса, было бы также полезно сделать модельную реализацию интерфейса, подменяющую ZooKeeper.

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

Если с модельной реализацией всё пойдёт хорошо, то это приоткроет путь для поддержки другой системы координации вместо ZooKeeper.

Добавление в ClickHouse поддержки constraints и assumptions.

Implementation of table constraints and assumptions expressions in ClickHouse.

Done 🚀

  • Эту задачу взял Глеб Новиков

Constraint - это выражение, которое проверяется на истинность при вставке данных. Для примера, в таблице есть пара столбцов: URL и URLDomain. URLDomain хранится отдельно, чтобы быстрее обрабатывать запросы, где не нужен весь URL. При вставке мы хотим удостовериться, что URLDomain = domain(URL). Для этой цели, при создании таблицы, мы указываем соответствующий constraint.

Указанные constraints могут использоваться для оптимизации запросов. Например, если в запросе написано domain(URL), и в таблице есть constraint URLDomain = domain(URL), то мы можем оптимизировать запрос, заменив domain(URL) на URLDomain, чтобы избежать лишних вычислений.

Вариантом на тему constraints может быть assumptions. Это - выражение, которое не проверяется при вставке данных, но всё-равно использующееся при оптимизации запроса, как будто оно всегда является истинным.

Продвинутые методы ускорения сортировки в ClickHouse.

Advanced methods of sorting optimization in ClickHouse.

Done 🚀

  • Эту задачу взял Евгений Правда

Хорошим алгоритмом для сортировки массива чисел является radix sort. В ClickHouse есть реализация этого алгоритма. Алгоритм работает как для беззнаковых, так и для знаковых чисел, а также для чисел с плавающей запятой.

Но для сортировки данных в ClickHouse нужно учесть несколько особенностей:

  • нужна не непосредственная сортировка, а получение перестановки индексов;
  • часто данные нужно сортировать не по одному числу, а по кортежу;
  • причём, компонетны кортежа расположены в отдельных массивах (т. н. structure of arrays);
  • структура кортежа известна только в рантайме;
  • часто нужна не полная, а частичная сортировка (получение в нужном порядке первых N элементов);
  • есть сценарии, в которых требуется и в которых не требуется stable sort.

В таком виде оптимальный вариант на тему radix sort ещё никто не исследовал.

Распараллеливание парсинга форматов данных.

Implementation of parallel algorithms for parsing input data in ClickHouse.

Done 🚀

  • Эту задачу взял Олег Ершов

Иногда узким местом при загрузке данных в ClickHouse является разбор формата входных данных (например, CSV). Хотя в ClickHouse уделено большое внимание, чтобы парсинг форматов был максимально эффективным, он всё же, ограничен скоростью одного процессорного ядра.

Предлагается превзойти это путём распараллеливания парсинга. Для этого в парсер форматов добавляется метод для быстрого получения чанка (куска файла для обработки, не пересекающего границы строк), так что чанки можно обрабатывать параллельно. Это будет полезно сделать для форматов CSV, TSV, JSONEachRow.

Форматы данных Template и Regexp. Ускорение batch insert с вычислимыми выражениями путём вывода шаблонов.

Implementation of template and regexp based text formats for input and output data in ClickHouse; performance optimization of batch insert with complex expressions.

Done 🚀

  • Эту задачу взял Александр Токмаков

Многие текстовые форматы данных определяются лишь тем, каким образом в них записаны значения (с каким экранированием) и какие разделители используются между значениями и строками. Предлагается реализовать формат Template, который выводит или считывает данные по указанному шаблону. Шаблон представляет собой строку с подстановками, где подстановка - это имя столбца и способ его записи. Например:

Title is ${Title:JSON}

  • этот шаблон выведет (или прочитает) "Title is", а затем поле Title в двойных кавычках, с экранированием так же, как в JSON.

В качестве бонуса предлагается реализовать также формат Regexp. Этот формат предназначен для чтения входных данных. Над строкой входных данных применяется указанный регексп, а значения столбцов заполняются из соответствующих match-ей. Это позволит использовать программу clickhouse-local так же как awk.

В ClickHouse есть формат данных Values. Он используется, когда пользователь отправил обычный запрос INSERT INTO table ... VALUES ... Пример: INSERT INTO table (num, str) VALUES (123, 'Hello'), (456, 'World').

Для разбора такого формата обычно используется быстрый потоковый парсер. Но проблема в том, что вместо значений, в запросе могут быть указаны произвольные выражения: INSERT INTO table (num, str) VALUES (12 + 3, concat('Hello', 'world')).

Быстрый потоковый парсер не может интерпретировать выражения. Поэтому в ClickHouse реализован fallback на медленный парсер. Но проблема в том, что ClickHouse оптимизирован на вычисления над целыми массивами, тогда как вычисления над отдельными значениями, в нём работают очень неэффективно. То есть, парсер, вычисляющий выражения по отдельности, работает очень медленно.

Тем не менее, можно заметить, что в случае наличия выражений, их структура обычно одинаковая в каждой строке: INSERT INTO table (num, str) VALUES (now(), toDate('2000-01-01'), 123 + 456), (now(), toDate('2001-01-01'), 789 + 100).

Можно попробовать составить шаблон по первой строке: (now(), toDate(?), ? + ?) и оптимистично применять его для парсинга остальных строк.

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

Поддержка преобразования данных непосредственно во время вставки.

Data transformations at insert time in ClickHouse.

Done 🚀

  • Эту задачу взял Максим Серебряков.

Иногда у пользователя есть файл с данными некоторой структуры, и ему нужно загрузить их в таблицу в ClickHouse другой структуры. Это легко решается с помощью временной таблицы:

  • создаётся временная таблица такой же структуры, что и исходные данные; туда загружаются данные из файла; а затем вставляются в результирующую таблицу с одновременным преобразованием, с помощью запроса INSERT SELECT.

Но это - довольно громоздкое решение. Было бы лучше сделать так, чтобы данные преобразовывались прямо во время загрузки. Это можно представить в виде запроса INSERT SELECT из загружаемого потока данных:

INSERT INTO table (a, b) SELECT x, y + z FROM input(x UInt64, y Int32, z Int32)

Также можно рассмотреть ограниченные варианты. Например, игнорирование отдельных столбцов при загрузке из файла:

INSERT INTO table (a, IGNORE String, b)

  • при чтении будет игнорироваться второй столбец из файла (который будет считываться как столбец типа String).

Расширение возможностей внешних словарей в ClickHouse.

Extending external dictionaries support in ClickHouse.

Done 🚀

  • Эту задачу взяла команда: Алексей Басманов, Глеб Третьяков, Олег Фавстов, Жанна Зосимова.

Добавим возможность использовать словари не только для прямого отображения, но и (под опцией) строить обратное отображение в памяти и реализовать функции dictGetChildren, dictGetChild для injective случая. Добавим во внешние словари поддержку Nullable и Array типов.

Для удобства сделаем возможность зарегистрировать некоторые функции под пользовательскими именами. Для примера, сейчас пользователю приходится писать dictGetString('banners', 'name', BannerID), а мы хотели бы объявить это как функцию getBannerName(BannerID).

Попробуем подключить в качестве источников словарей key-value базы: Redis, Couchbase, Cassandra, Aerospike (любые системы на выбор).

Оптимизация стратегии слияний.

Optimization strategies for background data compaction in ClickHouse.

Done 🚀

  • Эту задачу взял Егор Соловьёв

В ClickHouse данные таблицы хранятся в небольшом количестве сортированных кусков. При вставке данных, формируется новый кусок. Фоновый процесс выполняет слияние нескольких сортированных кусков в более крупный сортированный кусок. Такие слияния можно представить в виде дерева (Merge Tree).

Стратегия слияний выбирает, когда и какие куски мержить друг с другом. От реализации этой стратегии зависит:

Общее количество ресурсов, потраченное на слияние. Например, если как можно чаще сливать вместе все имеющиеся куски, то дерево слияний будет несбалансированным и на слияние будет потрачено много работы. При слияниях одни и те же данные заново записываются на диск - это называется write amplification.

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

Реализация ASOF JOIN в ClickHouse

Implementation of "AsOf" (time window) JOIN operations in ClickHouse.

Done 🚀

  • Эту задачу взяла Алёна Есенина

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

Реализация ASOF JOIN отсутствует в подавляющем большинстве известных СУБД. Единственным примером СУБД, в которой реализован ASOF JOIN является kdb+. Также соответствующее преобразование присутствует в Pandas. https://www.postgresql.org/message-id/bc494762-26bd-b100-e1f9-a97901ddad57%40postgrespro.ru

Пример: для каждого значения котировки, присоединить ближайшее по времени назад, значение количества просмотров страниц сайта.

Исследование производительности современных аналитических СУБД.

Performance analysis and comparison of modern OLAP DBMS.

Done 🚀 (задача провалена, но через несколько лет всё-таки сделана нами: https://benchmark.clickhouse.com/)

  • Эту задачу взял Александр Узиков.

Бенчмарки ClickHouse https://clickhouse.yandex/benchmark.html существенно устарели. Сравнение с MonetDB и MemSQL проводилось несколько лет назад и более неактуально. Мы попробуем актуализировать сравнения, а также добавить некоторые современные и экспериментальные системы, о которых мало кто слышал. Например, это - Baidu Palo, LocustDB.

Целью задачи будет:

  • изучение архитектуры и сравнение возможностей систем;
  • детальное описание установки и настройки системы;
  • получение воспроизводимых результатов тестов.

Самым главным будет возможность получения некоторых "инсайтов" об устройстве систем по результатом тестов. При необходимости, мы научимся изучать внутреннее устройство системы даже без наличия исходных кодов.

Если система работает медленнее, чем ClickHouse, то как конкретно можно это объяснить? Если наоборот, на каком-то запросе система работает быстрее ClickHouse, то, в точности, почему? По результатам работы вы будете детально представлять ключевые моменты, определяющие эффективность работы аналитических СУБД.

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

Для работы не требуется знание C++.

Использование первичного ключа при ORDER BY monotonic(PK), GROUP BY injective(subset(PK)).

Optimizations for ORDER BY and GROUP BY with primary key in ClickHouse.

Done 🚀

  • Эту задачу взяла Анастасия Родигина

ClickHouse обрабатывает запрос параллельно, с использованием многих процессорных ядер. Распараллеливание, в большинстве случаев, устроено так: Существует конвейер выполнения запроса, который состоит из операций преобразований потоков данных. Конвейер начинается с операции чтения данных из таблицы. Уже на этом этапе всё распараллеливается: разные потоки читают разные диапазоны нужных для запроса данных, и каждый поток берёт для чтения следующий кусок данных по мере готовности.

Данные в таблицах типа MergeTree в ClickHouse хранятся в виде некоторого небольшого количества кусков, каждый из которых отсортирован по указанному при создании таблицы первичному ключу. Рассмотрим выполнение запроса с условием ORDER BY по первичному ключу, либо по любой монотонной функции от первичного ключа (например, по префиксу первичного ключа).

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

Единственная особенность реализации - чтение данных из кусков надо немного по-другому распараллелить. В обычном случае, потоки отдают данные из почти произвольных мест куска, по мере их готовности - обычно данные читаются более-менее последовательно, но могут отдаваться для обработки в слегка перемешанном порядке. А для данной задачи надо уметь читать данные параллельно, но отдавать их дальше по конвейеру с сохранением порядка.

Также сортированность данных можно использовать для выполнения GROUP BY.

Оптимизация хранения данных в ClickHouse для гетерогенных систем.

Data placement optimization for heterogenous storage arrays in ClickHouse.

Done 🚀

  • Эту задачу взял Игорь Минеев.

Хранение горячих и холодных данных на разных разделах. Хранение данных на нескольких независимых дисках (JBOD). Пережатие старых данных в фоне.

Для первого, каким-то образом настраиваются tablespaces - возможные пути к данным. В настройках таблицы прописывается, с какого порога размера использовать какой tablespace. При мерже или мутации, данные записываются на нужный tablespace. В свойствах куска в оперативке добавляется информация, где он находится. Для второго, куски начиная с какого-то размера, симметрично делим по дискам (каждая N-ая группа строк на N-ый диск). Получается RAID-0 в userspace. Для третьего - надо уметь делать низкоприоритетные задачи, который используют много CPU, и уметь хранить в ZooKeeper несколько допустимых чексумм сжатых данных.

Реализация MySQL wire протокола в ClickHouse

Implementation of MySQL wire protocol in ClickHouse

Done 🚀

  • Эту задачу взял Юрий Баранов

Аналитика исходного кода ClickHouse с помощью ClickHouse.

Using ClickHouse DBMS for analysis of ClickHouse source code.

Done 🚀

  • Эту задачу взял Никита Ширин

Для тестирования ClickHouse и аналитики, предлагается загрузить репозиторий исходных кодов ClickHouse в ClickHouse в максимально денормализованном виде. Для примера, у нас есть 200 000 строк кода и 20 000 коммитов. Мы загрузим в ClickHouse каждую строчку кода в каждой ревизии (получится таблица на несколько млрд. строк).

На полученных данных мы попробуем провести необычную аналитику. Попробуем ответить на вопросы:

  • если разработчик прекращает разрабатывать ClickHouse, как быстро его код переписывается;
  • какой период полураспада у одной строчки кода;
  • какие файлы больше сопротивляются их переписыванию;
  • какие люди больше любят удалять чужой код, а какие - писать новый; ...

Бонусом будет возможность разработать некоторый веб-интерфейс (систему для визуализации) над этой базой данных. Целью задачи будет продемонстрировать возможности представления репозитория с кодом в денормализованном виде в аналитической СУБД.

Для работы не требуется знание C++.

Аналитика децентрализованной сети Ethereum с использованием столбцовой СУБД ClickHouse и семантического анализа.

Analysis of Ethereum decentralized network with column-oriented ClickHouse DBMS and semantic methods.

Done 🚀

  • Эту задачу взял Денис Шаклеин.

Параметризованные запросы в ClickHouse

Done 🚀

Часто имеет смысл иметь заранее заданный запрос с параметрами и предоставить пользователю лишь возможность менять параметры. Это называется prepared statements. Обычно используется синтаксис, в котором подстановки обозначаются с помощью знака ? в тексте запроса.

Пример: SELECT * FROM table WHERE user = ?

С этим есть две проблемы:

  1. В ClickHouse строгая типизация, и мы должны знать тип подставляемых данных.
  2. Знак вопроса уже используется для тернарного оператора ?: (альтернативный синтаксис для функции if).

Поэтому будем делать подстановки, в которых указывается тип и имя подстановки: SELECT * FROM table WHERE user = {user_id:UInt32}

Необходимо будет добавить возможность отправки параметризованных запросов с подстановками в HTTP интерфейсе и в клиенте командной строки. В этом случае, значения подстановок передаются в виде параметров URL и параметров командной строки.

Ещё одна маленькая деталь - частый сценарий, когда пользователь хочет передать в качестве подставляемого значения множество: SELECT * FROM table WHERE user_id IN (здесь миллион элементов). Тоже как-то решим. Либо это будет передаваться в виде массива и мы сделаем, чтобы можно было в правой части IN указывать массив. Либо сделаем, что это будет записано в виде типа данных Set.

  • Эту задачу взял Александр Третьяков.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment