Какой объем данных в Redis хранится на одного пользователя
Что проверяют
Умеете ли вы оценить память, а не угадать цифру. Интервьюер хочет услышать, что лежит в Redis на пользователя, сколько это в байтах и как вы это измерили. Следом спросят, сколько памяти нужно всему инстансу и что будет при её нехватке.
Как отвечать
Начните с того, что именно хранится: сессия, корзина, кеш профиля, счётчики лимитов. Дальше цифра из вашего проекта и способ её получить:
MEMORY USAGE key: реальный размер ключа вместе со служебными структурами;INFO memory:used_memoryиmem_fragmentation_ratioдля всего инстанса;redis-cli --bigkeysи--memkeys: поиск тяжёлых ключей черезSCAN, без блокирующегоKEYS *.
Что влияет на размер сильнее, чем кажется:
- накладные расходы на ключ: запись в словаре, объект и заголовок строки дают десятки байт сверху, поэтому миллион ключей по 10 байт занимает кратно больше 10 МБ;
- кодировка: небольшой хеш хранится компактным listpack, пока не превышены
hash-max-listpack-entries(по умолчанию 128) иhash-max-listpack-value(64 байта). Поля пользователя в одном хеше выгоднее десятка отдельных ключей; - сериализация в Java:
RedisTemplateв Spring Data Redis по умолчанию используетJdkSerializationRedisSerializer, который раздувает объект. JSON через Jackson или Protobuf дают заметно меньше; - TTL: без него данные неактивных пользователей копятся бесконечно.
Итог: активные пользователи на средний размер, плюс фрагментация, буферы репликации и запас на копирование страниц при снапшоте. Например, 500 тысяч сессий по 2 КБ дают около гигабайта данных, а инстанс планируют с запасом в полтора-два раза. Задайте maxmemory и выберите maxmemory-policy: по умолчанию стоит noeviction, и при заполнении запись начнёт падать.
Где спотыкаются
Считают только полезные данные по формуле «ключ плюс значения». Реальный расход оказывается кратно больше.
Называют цифру без метода. Первый же вопрос «как мерили» ставит ответ под сомнение.
Кладут весь профиль одной строкой с JDK-сериализацией и потом не могут ни прочитать его из другого сервиса, ни обновить одно поле.