Что может быть лучше технического поста? Технический пост, за которым стоит бэкграунд трёх дней мучений!
Появилась у меня необычная потребность — ускорить выполнение одного метода. Изучив его работу, я понял: можно добиться ускорения через внедрение кэша. Простая задачка! (Эх, наивный…)
Дано:
У нас от 1 до 20 тысяч записей. Каждая запись выполняет от 1 до 20 тысяч вычислений — которые, к счастью, часто повторяются. А значит, могут быть закэшированы.
Сложность: O(n²). Ну что ж, впихнём кэш.
Первая реализация была на MapDB, ведь он уже использовался в другом методе этого проекта.
Результат? Запрос 324 млн ключей через MapDB — идея плохая.
Время выполнения: 8 часов.
Окей, нужен вариант, готовый к хайлоаду.
Выбор пал на RocksDB. Переписал всё под него.
Результат: 2 часа выполнения (~21 000 операций/сек). Уже лучше, но всё ещё не то.
Думаю — может, твикнем параметры Rocks? Что может пойти не так?
Итог: нагрузка на диск — 1200 МБ/с, 0 операций в секунду. Красота…
Начинаю твикать осознанно, читая доку. Что я сделал:
- Отключил внутренний кэш RocksDB
- Уменьшил размер блоков до 8 МБ
- Отключил кэширование индексов
- Включил кэширование страниц на уровне ОС
- Увеличил размер страниц до 128 КБ
- Снял лимит на число дескрипторов
И ещё один важный шаг — переписал get-запросы на batched multiGet. Почему?
- Меньше JNI-переключений между Java и C++
- Оптимизация I/O при чтении смежных ключей
- Внутренний параллелизм RocksDB при multiGet
И… да! Ускорение до 1.5 часа.
Что дальше? Подключил GPT, начали вместе думать.
Появилась идея: батч в 18 000 ключей — перебор.
Сократил до 1000 — и получил прирост!
Результат: ~41 210 операций в секунду. Много? Да. Достаточно? Пока — нет.
Продолжение следует…
#tech
Post #635
3.33K
- ❤🔥 36
- ❤ 11
- 🔥 5
- 🤯 2
- 🤝 1
- 😎 1