Реализация in-memory key-value хранилища на C++ с персистентностью и TCP-сервером - упрощённая версия Redis, написанная с нуля без внешних библиотек.
┌────────────┐
│ Server │ TCP-сервер, по потоку на клиента
└─────┬──────┘
│
┌─────▼──────┐
│ KVEngine │ Потокобезопасная точка входа (shared_mutex)
└─────┬──────┘
│
┌───┴────┐
│ │
┌─▼───┐ ┌──▼──┐
│ LRU │ │ WAL │ Персистентность: лог операций + снапшоты
│Cache│ └─────┘
└─┬───┘
│
┌─▼─────┐
│HashMap│ Open addressing, linear probing, TTL на ячейку
└───────┘
- HashMap — своя хеш-таблица с открытой адресацией (linear probing), tombstone-удалением и автоматическим рехешем при заполнении ≥75%.
- LRUCache — обёртка над HashMap с вытеснением по давности использования (список порядка + O(1) доступ).
- WAL (Write-Ahead Log) — текстовый журнал операций
SET/DEL; при старте восстанавливает состояние черезreplay(). Каждые 100 операций делает снапшот текущего состояния и обрезает лог. - KVEngine — потокобезопасная обёртка над LRUCache + WAL (
std::shared_mutex: параллельные чтения, эксклюзивная запись). - Server — TCP-сервер на сырых сокетах POSIX, на каждое подключение поднимает
std::thread.
SET key value [ttl]— сохранить значение, опционально с TTL в секундахGET key— получить значениеDEL key— удалить ключEXISTS key— проверить наличие ключа- TTL (время жизни ключа) на уровне отдельной записи
- LRU-вытеснение при превышении ёмкости кэша
- Восстановление состояния после рестарта через WAL + снапшоты
Зависимостей, кроме стандартной библиотеки C++17, POSIX-сокетов и thread, нет.
mkdir build
cd build
cmake ..
make./kvserverСоединение обрабатывает ровно одну команду за раз (без multiplexing и без keep-alive): клиент отправляет строку, получает ответ, соединение закрывается.
Пример через netcat / /dev/tcp:
$ echo -n "SET foo bar" | nc 127.0.0.1 6380
OK
$ echo -n "GET foo" | nc 127.0.0.1 6380
bar
$ echo -n "SET session data 60" | nc 127.0.0.1 6380 # TTL = 60 секунд
OK
$ echo -n "EXISTS foo" | nc 127.0.0.1 6380
1
$ echo -n "DEL foo" | nc 127.0.0.1 6380
OKОтвет на несуществующий ключ: (Key not found).