tex4656fndh/тех
2026-09-09 21:15:14 +05:00

128 lines
9.8 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

ТЕХНИЧЕСКОЕ ЗАДАНИЕ
на разработку высокопроизводительной In‑Memory Cache системы (аналог Memcached/Redis)
1. Цель проекта
Разработать высоконагруженное сетевое кэширующее хранилище типа «ключ‑значение» на языке C++ (или Rust). Система предназначена для снижения нагрузки на основную БД путём временного хранения часто запрашиваемых данных в оперативной памяти.
Ключевые целевые показатели:
Пропускная способность ≥ 10 000 операций/сек.
Задержка (p99) < 10 мс.
Поддержка ≥ 1 000 одновременных клиентских соединений.
Потокобезопасность и отказоустойчивость (graceful shutdown).
2. Функциональные требования
2.1. Базовые команды
Реализовать следующий минимальный набор команд (текстовый протокол поверх TCP):
SET key value [EX seconds] – сохранить значение, опционально с временем жизни.
GET key – получить значение по ключу, вернуть ошибку, если ключ отсутствует.
DELETE key – удалить ключ.
EXISTS key – проверить существование ключа.
(опционально) INCR key – инкремент числового значения.
(опционально) STATS – вывести статистику (хиты/промахи, использовано памяти и т.п.).
2.2. Управление памятью и вытеснение
Реализовать политику вытеснения LRU (Least Recently Used) или LFU.
При превышении заданного лимита памяти (задаётся в конфиге) автоматически удалять наименее приоритетные элементы.
Для значений с TTL – ленивое удаление при доступе + фоновый сборщик с заданным интервалом.
2.3. Сетевой протокол
Сервер должен принимать TCP-соединения, поддерживать keep‑alive.
Обрабатывать несколько запросов в рамках одного соединения.
Формат ответов: простой текстовый (например, +OK\r\n, $<len>\r\n<data>\r\n, -ERR ...\r\n).
2.4. Многопоточность
Обработка параллельных запросов должна быть потокобезопасной.
Рекомендуется шардирование данных по нескольким независимым кэш‑инстансам (каждый в своём потоке) для минимизации блокировок.
3. Нефункциональные требования (чёткие метрики)
Параметр Целевое значение
Пропускная способность (GET) ≥ 10 000 RPS (при 1000 клиентах, размер значения ~100 байт)
Задержка (p99) < 10 мс при 80% нагрузке
Количество одновременных соединений ≥ 1 000 (постоянных)
Максимальный размер кэша Конфигурируется (например, 1 ГБ, 4 ГБ)
Graceful shutdown По сигналу SIGTERM сервер завершает текущие запросы и корректно закрывает соединения за < 1 сек
Логирование Асинхронное, с ротацией файлов
4. Архитектурные требования (общие)
Сетевой I/O – использовать мультиплексирование (epoll для Linux, kqueue для macOS, IOCP для Windows) с неблокирующими сокетами.
Модель потоков – реакторный паттерн: один главный поток (акцептор) распределяет соединения по пулу воркеров, либо каждый воркер владеет своим epoll-циклом (рекомендуется для NUMA).
Управление памятью – избегать частых динамических аллокаций (использовать пулы объектов, слейбы или, как минимум, std::pmr). Данные значения хранить как непрерывные блоки байтов.
Конфигурация – параметры (порт, максимальный размер кэша, политика вытеснения, число потоков) должны читаться из конфигурационного файла (например, JSON или TOML).
5. Технологический стек
Для C++:
Язык: C++17 (или C++20, на выбор)
Сеть: системные вызовы (socket, epoll, accept) либо обёртки (например, Boost.Asio – по желанию)
Многопоточность: std::thread, std::jthread, синхронизация через std::mutex/std::shared_mutex или lock‑free структуры
Тестирование: Google Test для модульных тестов, нагрузочные утилиты wrk, hey, vegeta
Сборка: CMake
Для Rust (альтернатива):
Язык: Rust 2021
Runtime: Tokio (многопоточный)
Сеть: tokio::net::TcpListener / TcpStream
Кэш: DashMap для шардирования без блокировок, lru для политики
Тестирование: встроенные тесты, бенчмарки через criterion
Сборка: Cargo
6. План работ на неделю (примерное распределение)
День Задачи
День 1 Изучение предметной области. Проектирование структур данных (классов/модулей). Написание архитектурной схемы. Согласование ТЗ.
День 2 Реализация ядра кэша – хеш‑таблица + двусвязный список (LRU) с защитой мьютексами (или шардирование). Написание юнит‑тестов для этих структур.
День 3 Разработка сетевого уровня: создание TCP‑сервера с epoll, парсер команд, буферизация чтения/записи. Базовое логирование.
День 4 Интеграция кэша и сетевого слоя. Реализация всех команд (SET, GET, DELETE, EXISTS, TTL). Проверка сквозных сценариев.
День 5 Нагрузочное тестирование, профилировка (perf, Valgrind), оптимизация «узких» мест (уменьшение копирований, улучшение локализации).
День 6 Добавление команды STATS, метрик (количество операций, hit ratio, использование памяти). Настройка graceful shutdown.
День 7 Финальное тестирование, написание документации (README, описание протокола, примеры запуска), подготовка демонстрационного выступления.
7. Критерии приёмки (оценка преподавателем)
№ Критерий Вес
1 Корректность реализации всех команд – SET, GET, DELETE, EXISTS (и TTL) работают согласно спецификации 25
2 Производительность – достигнуто не менее 10 000 RPS на GET‑запросах (подтверждено бенчмарком) 25
3 Стабильность и масштабируемость – система выдерживает ≥ 1 000 одновременно открытых соединений без падений и утечек 20
4 Потокобезопасность – отсутствие гонок данных (проверено инструментами, например, ThreadSanitizer) 10
5 Управление памятью – нет утечек (Valgrind / AddressSanitizer), корректно отрабатывает LRU 10
6 Документация – наличие README, инструкции по сборке и примеров использования 5
7 Graceful shutdown – корректное завершение по сигналу, без потери данных (запись завершается) 5
8. Возможные расширения (для дополнительных баллов)
Персистентность – периодическое сохранение дампов кэша на диск и восстановление при старте.
Репликация – синхронизация данных между несколькими экземплярами (master‑slave или кластер).
Шардирование по ключу (consistent hashing) для горизонтального масштабирования.
Экспорт метрик в Prometheus или вывод их через HTTP‑эндпоинт.
Поддержка SSL/TLS для защищённого соединения.
Расширенный протокол (например, поддержка списков или хешей, как у Redis).