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

Табличный движок EmbeddedRocksDB

Not supported in ClickHouse Cloud

Этот движок позволяет интегрировать ClickHouse с RocksDB.

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

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
    ...
) ENGINE = EmbeddedRocksDB([ttl, rocksdb_dir, read_only]) PRIMARY KEY(primary_key_name)
[ SETTINGS name=value, ... ]

Параметры движка:

  • ttl — время жизни значений. TTL задаётся в секундах. Если TTL равен 0, используется обычный экземпляр RocksDB (без TTL).
  • rocksdb_dir — путь к каталогу существующей базы RocksDB или целевой путь для создаваемой базы RocksDB. Таблица открывается с указанным rocksdb_dir.
  • read_only — если read_only установлен в true, используется режим только для чтения. Для хранилища с TTL компакция (compaction) не будет запускаться (ни вручную, ни автоматически), поэтому просроченные записи не удаляются.
  • primary_key_name — имя любого столбца из списка столбцов.
  • primary key должен быть указан; в состав первичного ключа может входить только один столбец. Первичный ключ будет сериализован в бинарном виде как rocksdb key.
  • столбцы, отличные от первичного ключа, будут сериализованы в бинарном виде как rocksdb value в соответствующем порядке.
  • запросы с фильтрацией по ключу с использованием equals или in будут оптимизированы до поиска по нескольким ключам в rocksdb.

Настройки движка:

  • optimize_for_bulk_insert — таблица оптимизирована для пакетных вставок (конвейер вставки будет создавать SST-файлы и импортировать их в базу данных RocksDB вместо записи в memtable); значение по умолчанию: 1.
  • bulk_insert_block_size — минимальный размер SST-файлов (в терминах числа строк), создаваемых пакетной вставкой; значение по умолчанию: 1048449.

Пример:

CREATE TABLE test
(
    `key` String,
    `v1` UInt32,
    `v2` String,
    `v3` Float32
)
ENGINE = EmbeddedRocksDB
PRIMARY KEY key

Метрики

Кроме того, есть таблица system.rocksdb, содержащая статистику RocksDB:

SELECT
    name,
    value
FROM system.rocksdb

┌─name──────────────────────┬─value─┐
│ no.file.opens             │     1 │
│ number.block.decompressed │     1 │
└───────────────────────────┴───────┘

Конфигурация

Вы также можете изменить любые параметры RocksDB с помощью конфигурации:

<rocksdb>
    <options>
        <max_background_jobs>8</max_background_jobs>
    </options>
    <column_family_options>
        <num_levels>2</num_levels>
    </column_family_options>
    <tables>
        <table>
            <name>TABLE</name>
            <options>
                <max_background_jobs>8</max_background_jobs>
            </options>
            <column_family_options>
                <num_levels>2</num_levels>
            </column_family_options>
        </table>
    </tables>
</rocksdb>

По умолчанию тривиальная оптимизация приблизительного подсчёта отключена, что может снизить производительность запросов count(). Чтобы включить эту оптимизацию, установите optimize_trivial_approximate_count_query = 1. Также этот параметр влияет на system.tables для движка EmbeddedRocksDB — включите его, чтобы увидеть приблизительные значения для total_rows и total_bytes.

Поддерживаемые операции

Вставки

При вставке новых строк в EmbeddedRocksDB, если ключ уже существует, его значение обновляется, иначе создаётся новый ключ.

Пример:

INSERT INTO test VALUES ('некоторый ключ', 1, 'значение', 3.2);

Удаление

Строки можно удалять с помощью запросов DELETE или TRUNCATE.

DELETE FROM test WHERE key LIKE 'some%' AND v1 > 1;
ALTER TABLE test DELETE WHERE key LIKE 'some%' AND v1 > 1;
TRUNCATE TABLE test;

Обновления

Значения можно обновлять с помощью запроса ALTER TABLE. Первичный ключ нельзя изменять.

ALTER TABLE test UPDATE v1 = v1 * 10 + 2 WHERE key LIKE 'some%' AND v3 > 3.1;

Соединения

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

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

Чтобы включить прямые соединения:

SET join_algorithm = 'direct, hash'
Совет

Когда параметр join_algorithm установлен в значение direct, hash, по возможности будут использоваться прямые соединения, а в остальных случаях — хеш-соединения.

Пример

Создание и заполнение таблицы EmbeddedRocksDB
CREATE TABLE rdb
(
    `key` UInt32,
    `value` Array(UInt32),
    `value2` String
)
ENGINE = EmbeddedRocksDB
PRIMARY KEY key
INSERT INTO rdb
    SELECT
        toUInt32(sipHash64(number) % 10) AS key,
        [key, key+1] AS value,
        ('val2' || toString(key)) AS value2
    FROM numbers_mt(10);
Создайте и заполните таблицу для объединения с таблицей rdb
CREATE TABLE t2
(
    `k` UInt16
)
ENGINE = TinyLog
INSERT INTO t2 SELECT number AS k
FROM numbers_mt(10)
Установите алгоритм соединения в значение direct
SET join_algorithm = 'direct'
Внутреннее соединение (INNER JOIN)
SELECT *
FROM
(
    SELECT k AS key
    FROM t2
) AS t2
INNER JOIN rdb ON rdb.key = t2.key
ORDER BY key ASC
┌─key─┬─rdb.key─┬─value──┬─value2─┐
│   0 │       0 │ [0,1]  │ val20  │
│   2 │       2 │ [2,3]  │ val22  │
│   3 │       3 │ [3,4]  │ val23  │
│   6 │       6 │ [6,7]  │ val26  │
│   7 │       7 │ [7,8]  │ val27  │
│   8 │       8 │ [8,9]  │ val28  │
│   9 │       9 │ [9,10] │ val29  │
└─────┴─────────┴────────┴────────┘

Подробнее о соединениях