libfpta — обгоняя SQLite и Tarantool / Леонид Юрьев (Positive Technologies)

Preview:

Citation preview

libfpta - обгоняяSQLite и TarantoolЛеонид ЮрьевAdvanced Research @ Positive Technologies

Алексей КопытовЭксперт @ Голос Разума

Обогнали!Увидимся на «Хабре»

https://github.com/PositiveTechnologies/libfptahttps://github.com/PositiveTechnologies/libfptuhttps://github.com/leo-yuriev/libmdbx

libfpta

libfpta:– в памяти– с персистентностью– быстрее хайпа

Леонид ЮрьевAdvanced Research @ Positive Technologies

Алексей КопытовЭксперт @ Голос Разума

Потребовалосьоперативное хранилище

– очень быстрое

– для локальных процессов

– без излишеств, но развиваемое…

Взяли и сделали.

libfpta: Постановка задачиЛокально, DATA < RAM

– один нагруженный сервер– несколько читателей и 2-3 процесса-писателя

Быстро– если медленно, то не нужно

Долговечность иногда не важна– при аварии питания данные устаревают

Высокая готовность– минимальное время восстановления– падение не должно ломать или прятать данные

Позитивные таблицы1. Обзор

2. Варианты использования: Целевой и Неправильный

3. Плюсы

4. Минусы

5. Планы

6. Чем не устроили: Ignite, Tarantool, SQLite, RocksDB…

libfpta – Движок хранения

Компактная библиотека с лицензией LGPL

libfpta = libmdbx (key-value) + libfptu (tuples) + t1ha (hash)

Таблицы с «утиной» схемой, всяческие индексы

Экстремально быстрый, но без WAL (пока)

Похожий, но Иной

libfpta: 80% как у всех

1. Набор таблиц с колонкам и индексами

2. Машинные типы, дата-время, строки, NULL…

3. Курсоры

4. BREAD

5. Рой процессов

6. Пока отсутствуют: FOREIGN KEYs, JOINs

Внутри транзакцийчтения/записи

libfpta: ВнутриДанные отображены в RAM

– B+Tree, не LSM– ACID* поверх MVCC– MVCC посредством COW на уровне страниц

Key-value, кортежи, список таблиц, список колонок…– нет имен, только дайджесты t1ha

Предельно эффективно для машины– считаем кэш-линии и такты– ничего лишнего или неэффективного

libfpta: Не подойдет

Много «апдейтов» и– нельзя потерять при аварии питания– допустим простой при восстановлении= показан WAL

READ < WRITE && RAM < DATA= показан LSM

libfpta: ИдеальноТребуется предельная производительность

– ACID для локальной группы процессов– с выборкой диапазонов и курсорами

Не нужен WAL– требуется минимальное время простоя– допустимо потерять «хвост» при аварии( при kill -9 ничего не потеряется )– диск терпит WAF от апдейтов

READ > WRITE || RAM > DATA– иначе LSM даст больше

libfpta: СкоростьREAD / GET

𝑂 log(𝑁) = поиск в B+tree

Как std::map или чуть быстрее (за счет локальности)

На каждом CPUбез блокировок в БД

Подкачка если DATA > RAM

WRITE / UPSERT

𝑂 log(𝑁) = Изменение B+tree

Копирование страниц по высоте дерева

Транзакции строго последовательны

Фиксация на диске

MDBX

RocksDB

READ4threads SYNC LAZY

libfpta: Попугаи

MDBX

RocksDB

I/O SPACECPU

Производительность

Стоимость

libfpta: «Утиная» схема

Записи являются кортежами

Схема задает минимальный набор

Полей может быть больше…

Для «лишних» полей– машинный тип

– числовой тэг (до 1000)

– будет: справочник схемы

Дополнительныеполу-структурированные данные

libfpta: КортежиРеализованы в libfptu:

– похожи на BSON и MessagePack

– без сжатия

– поддерживаются коллекции (repeated в ProtoBuf)

– в заголовке есть «индекс»

– предельно удобны для машины

– подключаемый словарь схемы (будет, вместе с JSON)

– могут быть вложенным

– предусмотрены массивы

libfpta: Дубликаты

Дубликаты – это multi-value– во вложенных деревьях

– ключи не дублируются

– значения отсортированы

– курсоры могут ходить по «дубликатам»

– быстрый поиск и позиционирование

libfpta: КонкуренцияОдин писатель

– Один разделяемый мьютекс (1)– Изменения всегда последовательны

Много читателей– Подключение/отключение под вторым мьютексом (2)– Выполнение без блокировок внутри БД

Временно– Изменение схемы под мьютексом внутри процесса (3)

libfpta: ИндексыСоставные

– по совокупному значению колонок

Неупорядоченные– хэши t1ha вместо значений, требуют меньше места

Реверсивные– ключи сравниваются с конца, хорошо для доменов

Функциональные / Пользовательские (обдумываем)– как генераторы ключей, не компараторы– collate/uppercase

libfpta: Немного деталейПервичный индекс есть всегда

Нет RowID– есть последовательности– будет auto (эмуляция RowID)

Вторичные индекс через PK– как в MySQL, НЕ как в PostgreSQL– требуют уникальности PK

libfpta: Не как у людей…

Контроль уникальности– это атрибут индекса

NULL в индексах– заменяется на Designated NIL

– проверяется на уникальность

Триггеры– пока не хотим, нет «сервера»

Пока отсутствуют

– Collate и Case Insensitive

– FOREIGN KEYs

– JOINs

– OPTIMIZER / REWRITER

Пока не требовалось,но будет…

libfpta: Недостатки

Отсутствие WAL– требует смены формата

Проблема долгих чтений– требует большого рефакторинга

Наследство от LMDB

Были причины не трогать

Будем устранять

libfpta: WAL или NO-WAL?Без WAL

– Большой WAF

– Медленно на HDD

+ Моментальная готовность

Тем не менее+ OOM и kill = не проблема

+ есть LIFO для BBWC

Нам было достаточно,но WAL скоро будет

+ Небольшой WAF

+ Быстрее на HDD

± sync/flush (всё-таки нужен…)

– Replay после аварии

libfpta: Планы и хотелки

libmdbx (key-value):– Новое API

– Рефакторинг…

– Асинхронная фиксация

– Merkle Tree

– WAL

– Другая «сборка мусора»

– Вынос span-pages и поддержка RAW-устройств(Nexenta Edge)

libfptu (кортежи):– поддержка справочника схемы

– (де)сериализация в JSON

– (де)сериализация в MsgPack

libfpta (всё вместе):– поддержка python…

– «оптимизатор» запросов

– FK, JOIN, GIN…

libfpta: Трудности

KISS– взвешенный аскетизм, не переинженерить, меньше ребусов

Тесты– комбинаторная сложность

– оркестр процессов

– поведенческие паттерны

Люди– ищем в команду

Apache Ignite?

Java = неустранимые накладные расходы– не для предельной производительности

libfpta:1) Не нужна распределённость2) Не делает лишнего3) В несколько раз быстрее

Tarantool, Aerospike, etc…?

Сеть = неустранимые накладные расходы– системные вызовы, маршалинг, event loop

libfpta:1) Чтение линейно масштабируется по CPU2) Чтение без блокировок, непосредственно из RAM3) Интегрально в несколько раз быстрее*

SQLite, RocksDB…?

Одна БД = Один процесс

libfpta:1) Рой локальных процессов2) Два разделяемых мьютекса3) В несколько раз быстрее

Спасибо!Увидимся на «Хабре»

https://github.com/PositiveTechnologies/libfptahttps://github.com/PositiveTechnologies/libfptuhttps://github.com/leo-yuriev/libmdbx

libfpta

Recommended