Начало работы со столбцовой базой данных ClickHouse

база данных

Введение

ClickHouse — это столбчатая база данных для онлайн-анализа (OLAP), разработанная и размещенная в открытом доступе российской поисковой компанией.

Ключевые особенности сценариев OLAP

  • В основном прочитанные запросы
  • Запись данных большими партиями (> 1000 строк)
  • Не изменять добавленные данные
  • Каждый запрос считывает большое количество строк из базы данных, но только небольшое количество столбцов.
  • Широкие таблицы, каждая с большим количеством столбцов
  • Меньше запросов
  • Нужно много дел
  • Низкие требования к согласованности данных
  • но высокая пропускная способность запросов (до миллиардов строк в секунду на сервер)
  • Каждый запрос небольшой, за исключением одной большой таблицы
  • Результат запроса значительно меньше исходных данных

Архитектура

Основные особенности

Полная функция СУБД

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

Столбчатое хранилище и сжатие данных

Чтобы запросы выполнялись быстрее, вы можете уменьшить диапазон сканирования данных и объем передаваемых данных.
ClickHouse использует столбчатую структуру хранения,
Для пользовательской таблицы будет много автоматики, но когда запрашиваются только 2 поляselect id,name from user, MySQL сканирует всю таблицу, в то время как для столбцового хранилища считываются только эти два столбца данных, что эффективно уменьшает диапазон сканирования данных и повышает эффективность ввода-вывода.
Суть алгоритма сжатия заключается в кодировании и преобразовании повторяющихся данных для уменьшения длины данных, ClickHouse по умолчанию использует алгоритм сжатия LZ4.

Векторизованный исполнительный движок

Векторизованное выполнение требует использования инструкции ЦП SIMD (Single Instruction Multiple Data).Одна инструкция работает с несколькими фрагментами данных.Одним из способов повышения производительности за счет параллелизма данных является реализация параллельных операций с данными на уровне регистров ЦП.

Разнообразные настольные двигатели

объединить дерево журнал интегрированный очень
MergeTree Tinylog Kafka Distributed
SummingMergeTree StripeLog Mysql Dictionary
AggregatingMergeTree Log JDBC Merge
CollapsingMergeTree ODBC File
VersionCollapsingMergeTree HDFS Set
GragphieMergeTree Join
URL
View
MaterializedView
Memory
Buffer

Распределенный и многопоточный

向量化执行通过数据级并行的方式提升性能
多线程处理通过线程级并行的方式提升性能
Поддержка разделов — масштабируйте, используйте преимущества многопоточности
Поддержка сегментирования — горизонтального расширения с использованием распределенных принципов.

Многоуровневая архитектура

Multi-Master multi-master архитектура, роли каждого узла в кластере равны, и клиент может получить одинаковый эффект при доступе к любому узлу.

Механизм таблицы журналов

Лог используется для быстрого чтения и записи небольших таблиц (1 млн строк), а затем чтения их всех

  • Разделение и индексация не поддерживаются
  • Удаление и обновление не поддерживаются
  • последовательность данных добавить диск
  • Атомарная запись не поддерживается
  • вставка заблокирует выбор

Сортировать по производительности:

  • tinylog: самая низкая производительность, не поддерживает параллельное чтение, плохая производительность запросов, подходит для временного хранения промежуточных данных
  • Striplog: поддерживает одновременное чтение, все столбцы хранятся в одном файле
  • log: поддерживает одновременное чтение, каждый столбец хранит отдельный файл

специальный настольный двигатель

memory

С типом таблицы памяти mysql данные сохраняются в памяти, и данные будут потеряны после перезапуска.

buffer

Если указанные условия соблюдены, он будет сброшен на диск
Buffer(database, table, num_layers, min_time, max_time, min_rows, max_rows, min_bytes, max_bytes)

create table test.buffer_to_memory_1 as test.memory_1 engine = Buffer(test, memory_1, 16, 10 ,100, 1000, 1000000, 10000000, 100000000);Данные, вставленные в буферную таблицу, могут быть записаны в целевую таблицу в другом порядке и в разных блоках.
Удовлетворить все min_, или любой max_ сбросит данные в таблицу memory_1

file

прямо в файле

движок таблицы дерева слияния

MergeTree

  • Раздел поддержки
  • Хранится в порядке
  • индекс первичного ключа
  • данные ttl
  • разреженный индекс

主键数据可以重复

create table test_1( id UInt16, create_time Date )ENGINE=MergeTree() PARTITION BY toYYYYMMDD(create_time) ORDER BY (id,create_time) PRIMARY KEY (id,create_time) TTL create_time + INTERVAL 1 MONTH

PRIMARY KEYЕсли не определено, используйте поле ORDER BY в качестве первичного ключа.
toYYYYMMDD(create_time)Разделить данные по дням
TTL create_time + INTERVAL 1 MONTHДанные хранятся в течение одного месяца

ReplacingMergeTree

чтобы решитьMergeTreeПроблема в том, что один и тот же первичный ключ не может быть дедуплицирован, вводится ReplacingMergeTree
но и принуждениеoptimize
optimize table test_re
существующие проблемы

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

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

CollapingMergeTree

Дальнейшее улучшение ReplacingMergeTree, добавление поля Sign
create table test_2( id UInt16, ViewNum UInt16, create_time Date, Sign Int8 )ENGINE=CollapingMergeTree(Sign) GROUP BY ID;
Данные Sign=1 действительны, данные Sign=-1 удалены

Новые данные: ВСТАВИТЬ В ТЕСТ_2(...,1)
Удалить данные: INSERT INTO TEST_2(...,-1)

В случае многопоточной записи запись -1 записывается первой, что вызовет нормальное сворачивание

нужно переписатьsql
SELECT id,sum(ViewNum * Sign) FROM test_2 GROUP BY id HAVING sum(Sign)>0;

VersionedCollapsingMergeTree

Чтобы решить проблему, заключающуюся в том, что запись CollapingMergeTree не по порядку не может быть правильно свернута
Добавить новый столбец номера версии
Строки с одним и тем же первичным ключом, одной и той же версией и противоположным знаком будут удалены во время сжатия.
create table test_3( id UInt16, ViewNum UInt16, create_time Date, Sign Int8, Version UInt8 )ENGINE=VersionedCollapsingMergeTree(Sign,Version) GROUP BY ID;

тоже надо переписатьsql
SELECT id,sum(ViewNum * Sign) FROM test_3 GROUP BY id HAVING sum(Sign)>0;

SummingMergeTree

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

  • Данные будут агрегироваться только при объединении в фоновом режиме, поэтому для запроса sql по-прежнему требуется GROUP BY
  • Во время предварительной агрегации сумма будет выполняться по столбцам, кроме первичного ключа. Если столбец не является числовым, значение в строке будет выбрано случайным образом.

AggregatingMergeTree

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

Использование с материализованными представлениями

-- 创建明细表
CREATE TABLE test.visits(
    UserID UInt64,
    CounterID UInt8,
    StartDate Date,
    Sign Int8
)ENGINE CollapsingMergeTree(Sign)
ORDER BY UserID;

-- 创建物化视图
CREATE MATERIALIZED VIEW test.basic
ENGINE = AggregatingMergeTree()
PARTITION BY toYYYYMM(StartDate)
ORDER BY (CounterID, StartDate)
AS SELECT
   CounterID,
   StartDate,
   sumState(Sign) AS Visits,
   uniqState(UserID) AS Users
FROM test.visits GROUP BY CounterID, StartDate;

-- 插入数据到明显表中
INSERT INTO test.visits VALUES (1, 1, '2020-08-11', 1), (2, 11, '2020-08-11', 1), (3, 12, '2020-08-11', 1);

-- 查询物化视图
SELECT
   StartDate,
   sumMerge(Visits) as Visits,
   uniqMerge(Users) as Users
FROM test.basic
GROUP BY StartDate
ORDER BY StartDate;