Обновить
4

Механизатор профиля

-0,3
Рейтинг
2
Подписчики
Отправить сообщение

В предыдущих сериях был реализован простейший движок на основе HashMap, в которой сохраняются данные key -> value, и в принципе была открыта дорога для написания сервера и клиента для тестов. Но я решил добавить в Space работу с распределенными (XA) транзакциями.

Наличие такого механизма обязательно приведет к деградации производительности. Закономерно возникает вопрос: для чего это было сделано? Memifydb - это распределенная БД и она должна обеспечивать конкурентный доступ к данным обеспечивая их целостность. Что проку если она будет работать быстро, но её содержимое будет - хаос? Ведь деже при создании простого приложения для обработки данных в нескольких потоках используется synchronized в java (и пр. механизмы синхронизации).

Второй момент состоит в том что я всегда работал с транзакциями на стороне клиента, т.е. работал с менеджером транзакции (TransactionManager). Теперь же я писал сервис и пришлось иметь место с менеджером ресурсов (XAResource), что тоже интересно (не забываем что проект модельный и исследовательский).

Итак, транзакционность добавил, пока что на уровне RAM без сохранения данных в долговременную помять для отката/восстановления. Следующий шаг это написание самого сервера, который будет управлять Space’ами и обработкой клиентских запросов.

👉 Telegram: https://t.me/memifydb 👉 GitHub: https://github.com/yourname/memifydb

Теги:
-2
Комментарии0

В предыдущих постах Разбираемся в in-memory базах и Выбираем базу и думаем о данных.

Взлетаем, создал репозиторий под проект https://github.com/mathter/memifydb.git

План

План общий такой:

  • Изначально строю некоторый каркас, который буду достраивать и наполнять содержанием. Это будет удобно для прототипирования.

  • Для работы с данными создам некоторый дополнительный уровнь абстракции, что бы не привязываться к конкретному формату данных/библиотеке и менять его налету для сравнения.

Сделано

  • Данные клиента будут храниться в space’ах - это будет аналог таблиц в БД. Для начала будет только key-value space что бы можно было подумать уже сейчас о WAL клиенской библиотеке для java и сетевом уровне в целом и конечно же о транзакциях.

  • Тестовая реализация WAL, которая в проекте будет называться Log.

Run.

Теги:
Рейтинг0
Комментарии0

🔌Форматы обмена и хранения данных

В предыдущих постах Разбираемся в in-memory базах и Выбираем базу я написал, что собираюсь сделать исследовательский проект по in-memory базам данных  и имя ему MemifyDB. Так же выбрал направление движения: это key-value хранилище, которое потом доработаю до документо-ориентированной системы.

Теперь ключевой вопрос: как клиенты будут с ней общаться?

Протокол обмена — это мост между сервером и клиентом. От его дизайна зависит скорость, удобство и даже то, какие фичи мы сможем реализовать.

Human readable (JSON, XML and etc.)

В современных системах активно используется как для транспорта так и для хранения текстовый формат данных, а точнее json и его вариации. У этого подхода есть несколько несомненных плюсов, например:

  • Простота реализации: не нужно поддерживать разные типы на уровне протокола, всё передаётся как строки, а клиент сам разбирается.

  • Гибкость: строкой можно закодировать что угодно — число, JSON, бинарные данные.

Но у этого подхода есть обратная сторона:

  • Нет нативной поддержки типов: Клиент сам должен сериализовать/десериализовать.

  • Оверхед на парсинг: Каждый раз нужно преобразовывать “42” в число и обратно.

  • Неэффективное использование памяти: Число 123456 занимает 6 байт как строка, хотя в бинарном виде — 4 или 8.

  • Невозможность частичного обновления сложных структур: Чтобы изменить одно поле в JSON-объекте, приходится переписывать весь объект (можно конечно поспорить).

## 🎯 Наш подход: типизированные данные с рождения В MemifyDB мы пойдём другим путём.
Мы будем хранить данные в памяти в типизированном виде: строки, числа, списки, хеши, документы — каждый тип со своим внутренним представлением.

И протокол обмена с клиентом должен это отражать.
Мы не хотим, чтобы клиент упаковывал число в строку только потому, что так проще.
Мы хотим передавать по сети те же бинарные структуры, которые лежат в памяти.

Это даст:

  1. Типизированность Формат должен явно различать типы данных: строки, числа (разной разрядности), булевы значения, null, массивы, объекты (документы).
    Это позволит серверу правильно интерпретировать данные без дополнительных метаданных.

  2. Компактность Формат не должен раздувать данные. Число 42 должно занимать 8 байт (или 4, если это int32), а не 2 символа ASCII.

  3. Быстрая навигация Мы должны иметь возможность быстро «прыгнуть» к определённому полю документа без полного парсинга.
    Это важно для частичных обновлений и запросов.

  4. Потоковость Формат должен допускать частичную отправку/приём, чтобы можно было обрабатывать большие документы по частям.

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

🔍 Что дальше?

Существуют несколько бинарных: CBOR, BSON, FlatBuffer и пр. Если у вас есть опыт работы с этим форматами, пишите в комментариях какие у них есть плюсы, минусы и подводные камни.

Теги:
Рейтинг0
Комментарии0

🧠 MemifyDB: прежде всего — видение (vision).

Прежде чем погружаться в код, нужно чётко ответить на вопрос: а что именно мы строим?
Этот пост — не про хардкорный кодинг, а про так называемое видение системы (system vision).
Мы разберём, какие вообще бывают in-memory базы данных, чем они отличаются и почему наш путь будет таким: key-value → документная БД.

Поехали!

📚 Типы in-memory баз данных

1. Key-Value хранилища

Самый простой и быстрый вид. Данные хранятся как пары «ключ — значение», где значение — обычно строка, число или бинарный объект.

  • Примеры: Redis, Memcached, DragonflyDB.

  • Сценарии: кэширование, сессии пользователей, счётчики, очереди задач.

  • Плюсы: максимальная скорость, минимальный оверхед, простота масштабирования (шардирование по ключу).

  • Минусы: ограниченная модель данных — нет сложных запросов, только операции по ключу.

2. Документо-ориентированные БД

Значение — структурированный документ (JSON, BSON, XML). Внутри документа можно индексировать поля и выполнять запросы по содержимому.

  • Примеры: MongoDB (in-memory storage engine), Couchbase.

  • Сценарии: хранение сложных объектов (профили, каталоги), где важна гибкость схемы.

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

  • Минусы: чуть более высокий оверхед по сравнению с key-value (парсинг, индексация).

3. Колоночные (Columnar) in-memory БД

Данные хранятся не по строкам, а по колонкам. Это даёт огромное преимущество при аналитических запросах (суммы, средние, группировки).

  • Примеры: SAP HANA, MemSQL (SingleStore) в колоночном режиме, Apache Arrow (формат, но не БД).

  • Сценарии: аналитика реального времени, отчёты, BI.

  • Плюсы: сверхбыстрая агрегация, высокая степень сжатия.

  • Минусы: медленные точечные обновления (OLTP-нагрузка), сложность реализации.

4. Графовые БД

Хранят сущности (узлы) и связи между ними (рёбра). Оптимизированы для обходов графа.

  • Примеры: RedisGraph (модуль Redis), Neo4j (с in-memory режимом).

  • Сценарии: социальные сети, рекомендательные системы, сети связей.

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

  • Минусы: узкая ниша, сложность шардирования.

5. Time-series БД

Специализированы для временных рядов — метрик, логов, событий. Оптимизированы для записи и запросов по временным интервалам.

  • Примеры: InfluxDB, TimescaleDB (in-memory части).

  • Сценарии: мониторинг, IoT, финансовые тикеры.

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

  • Минусы: слабо подходят для произвольных данных.

…## 🧭 Наш курс: от Key-Value к документам

Для MemifyDB я выбрал путь, который кажется самым прагматичным:

  1. Создаём ядро Key-Value
    Это фундамент. Мы реализуем:

    • потокобезопасное in-memory хранилище;

    • поддержку разных типов значений (строки, списки, хеши, числа);

    • механизмы TTL и эвикшена (LRU);

    • бинарный протокол, близкий к внутреннему представлению.

    Key-value движок даст нам максимальную скорость и стабильность, а также позволит отточить все низкоуровневые механизмы (аллокаторы, сериализацию, сетевое взаимодействие).

  2. Надстраиваем документный слой
    Поверх key-value ядра мы добавляем возможность интерпретировать значение как JSON-подобный документ:

    • индексация по полям;

    • поддержка частичного обновления;

    • запросы с фильтрацией по содержимому.

При этом сами документы будут храниться в key-value хранилище как обычные значения, а индексы — как дополнительные структуры (хеш-таблицы, B-деревья) в памяти.

Такая двухслойная архитектура даёт:

  • гибкость — можно работать и как с обычным кэшем, и как с документной БД;

  • производительность — key-value ядро остаётся быстрым, а документные операции добавляются без потери эффективности;

  • расширяемость — позже можно добавить другие модели (например, колоночные агрегаты) как отдельные слои.

Теги:
Всего голосов 4: ↑0 и ↓4-4
Комментарии2

🧠 Разбираемся, как устроены in-memory БД: пишем MemifyDB с нуля.

Redis быстр, но не всегда удобен. SAP HANA — мощь, но ценник…
А что, если заглянуть под капот и создать свою enterprise in-memory СУБД?
Не чёрный ящик, а полностью прозрачную, современную, open-source — и при этом готовую к высоким нагрузкам. Разбираемся как это работает!

Знакомьтесь — MemifyDB.

📌 Что это будет?
Настоящая in-memory система уровня enterprise, в которой мы разберёмся до винтика:

  • живёт в RAM, отвечает за микросекунды;

  • сохраняет данные на диск (RDB + WAL) — никакой потери после ребута;

  • реплицируется и шардируется «из коробки»;

  • поддерживает транзакции (не хуже MULTI/EXEC, но с возможным rollback);

  • и при этом не просит продать почку за лицензию.

Весь код — open source, все решения — с объяснениями.

🛠 Технический фундамент (выбираем стек вместе)
Платформа — JVM. Я сейчас выбираю между Java 21 (Loom) и Scala 3 (ZIO / Akka).

  • Сеть: Netty или виртуальные потоки — посмотрим на бенчмарках.

  • Память: off-heap + собственный slab-аллокатор на ByteBuffer. GC не мешает, фрагментация под контролем.

  • Конкурентность: Lock-Free структуры данных, чтобы не блокировать потоки.

  • Протокол: RESP-совместимость — redis-cli сможет общаться с нами.

🗺 Дорожная карта: что и когда разберём

  1. Ядро: потокобезопасное KV-хранилище в памяти. Как работают LRU и TTL?

  2. Persistence: снапшоты и WAL. Как не потерять данные при краше?

  3. Сеть: пишем TCP-сервер. Netty vs Loom — кто быстрее?

  4. Транзакции: реализуем MULTI/EXEC, WATCH. Нужен ли MVCC?

  5. Репликация и Raft: как достичь консенсуса в распределённой системе?

Каждый этап — открытый код, пост с разбором, грабли и профит.

🤔 Зачем я это делаю публично?
Во‑первых, разобраться самому и дать шанс разобраться другим.
Во‑вторых, фидбек сообщества ловит ошибки на берегу.
В‑третьих, хочется сделать реально полезный инструмент, а не очередной pet‑project.

💬 Вопрос к залу:
Какой стек предпочтительнее для enterprise in‑memory БД — Java 21 + Loom или Scala + ZIO/Akka?
Какие фичи вы бы добавили в дорожную карту?
Пишите в комментариях — лучшие идеи уйдут в реализацию!

👉 Подписывайтесь, чтобы не пропустить:

  • глубокий разбор off‑heap аллокатора;

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

  • историю о том, как одна строка unsafe кода валила прод три дня.

Теги:
Всего голосов 13: ↑3 и ↓10-7
Комментарии22

Информация

В рейтинге
Не участвует
Откуда
Россия
Зарегистрирован
Активность

Специализация

Бэкенд разработчик, Разработчик мобильных приложений
Ведущий