Як Redis керує пам'яттю? Як Redis виділяє пам'ять під ключі й значення?
Redis керує пам'яттю на рівні байтів усередині оперативної пам'яті, використовуючи власні структури й стратегію виділення, зав'язану на його in-memory архітектуру. Він не покладається повністю на ОС, а активно контролює, скільки й як пам'яті зайнято, щоб підтримувати максимальну швидкість і передбачувану поведінку.
1. Загальна модель пам'яті
Redis зберігає всі дані в оперативній пам'яті. Кожен елемент у базі - це пара:
ключ → значенняОбидва елементи представлені як об'єкти Redis (redisObject). Ці об'єкти займають пам'ять у купі (heap), керованій Redis через обраний алокатор (за замовчуванням - jemalloc).
2. Виділення пам'яті
Redis використовує jemalloc, тому що він:
- швидший за стандартний
malloc/free; - менше фрагментує пам'ять;
- уміє ефективно працювати з безліччю дрібних об'єктів (що типово для Redis).
Коли Redis створює ключ чи значення, він запитує пам'ять у jemalloc і зберігає посилання на виділену ділянку. Якщо дані ростуть, Redis може розширити буфер (SDS) без повного копіювання, лишаючи запас ("free space") для майбутніх змін.
3. Формат зберігання
Кожен елемент зберігається у вигляді структури redisObject, що містить:
- тип даних (
string,list,hashтощо); - спосіб кодування (наприклад,
int,embstr,raw); - посилання на фактичні дані;
- лічильник посилань і прапорці;
- за потреби - час закінчення (TTL).
Приклад: Якщо значення - короткий рядок, Redis може використати embstr - розміщує сам рядок і метадані в одному блоці пам'яті для пришвидшення доступу. Якщо рядок довгий - використовується raw, де рядок і об'єкт роздільні.
4. Кодування й оптимізація зберігання
Redis адаптивно обирає кодування (encoding) залежно від розміру й типу даних:
| Тип | Можливі кодування | Призначення |
|---|---|---|
| String | int, embstr, raw | зберігання числа, короткого чи довгого рядка |
| List | quicklist | компактний список із zip-блоками |
| Hash | ziplist / hashtable | економія пам'яті за малої кількості полів |
| Set | intset / hashtable | оптимізація для числових значень |
| ZSet | ziplist / skiplist+hash | компактне чи повнорозмірне зберігання |
| Stream | listpack | щільне зберігання подій |
Redis автоматично перекодовує структури при зміні їхнього розміру чи вмісту.
5. Керування пам'яттю (maxmemory і eviction)
Якщо заданий параметр:
maxmemory <bytes>Redis контролює загальний обсяг використовуваної пам'яті. Коли ліміт досягається, запускається eviction-політика (видалення ключів).
Доступні політики:
noeviction- не додавати нові дані (за замовчуванням для persist Redis);volatile-lru- видаляти ключі з TTL, які довше не використовувалися;allkeys-lru- видаляти будь-які старі ключі (найчастіший варіант кешування);volatile-ttl- видаляти найближчі до закінчення;volatile-lfu/allkeys-lfu- на основі частоти використання.
6. Перевірка й звіт використання
Redis відстежує статистику щодо пам'яті:
INFO MEMORYПоказує:
- загальний обсяг,
- фрагментацію,
- overhead на об'єкти,
- використовуваний алокатор,
- і деталі AOF/RDB буферів.
Для аналізу окремих ключів:
MEMORY USAGE key
MEMORY STATS
MEMORY PURGE7. Звільнення й дефрагментація
Redis не завжди негайно повертає звільнену пам'ять ОС. Натомість jemalloc перевикористовує блоки. Redis може примусово дефрагментувати пам'ять командою:
MEMORY DOCTOR
MEMORY PURGEчи асинхронно звільняє непотрібні об'єкти у фоні (lazyfree).
8. Підсумок
Redis керує пам'яттю так:
- Усі дані живуть у RAM.
- Виділення виконується через jemalloc.
- Ключі й значення представлені об'єктами з типом і кодуванням.
- Формат зберігання динамічно підбирається для економії.
- maxmemory обмежує загальний обсяг, з можливим видаленням старих даних.
- Дефрагментація й звітність підтримуються вбудованими механізмами.
Усе це робить Redis максимально швидким, але при цьому контрольованим за пам'яттю навіть за дуже великих наборів даних.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.