Як Redis зберігає тип значення під капотом?
Чудове питання - це якраз те, що робить Redis не просто "ключ-значення", а високопродуктивним об'єктним сховищем у пам'яті. Під капотом Redis зберігає всі дані як об'єкти, кожен з яких має тип, кодування й допоміжну метаінформацію.
Розберемо детально:
1. Кожне значення - це RedisObject
Внутрішньо Redis не просто зберігає "значення", а створює структуру типу:
typedef struct redisObject {
unsigned type:4; // тип (string, list, hash, set, zset тощо)
unsigned encoding:4; // спосіб зберігання (raw, int, ziplist тощо)
void *ptr; // вказівник на реальні дані
int refcount; // лічильник посилань
...
} robj;Підсумок: Redis знає, який це тип даних і як саме він зберігається (у якій структурі пам'яті).
2. type - логічний тип даних
Поле type визначає яка це структура на рівні API Redis:
REDIS_STRINGREDIS_LISTREDIS_SETREDIS_ZSETREDIS_HASH
Команди Redis (GET, HGETALL, ZADD тощо) використовують це поле, щоб розуміти, які операції допустимі.
3. encoding - фізичне представлення
Це спосіб, як саме дані розміщуються в пам'яті. Redis динамічно обирає оптимальне кодування залежно від розміру й структури даних.
Приклади:
| Тип даних | Можливі кодування | Опис |
|---|---|---|
| String | int, embstr, raw | Число, короткий рядок (в об'єкті), довгий рядок (у виділеній пам'яті) |
| List | quicklist | Компресований список вузлів |
| Set | intset, hashtable | Множина чисел чи повноцінна хеш-таблиця |
| Hash | ziplist (до Redis 6) → listpack | Компактне зберігання пар "ключ-значення" |
| Sorted Set | ziplist / skiplist | Ущільнена структура чи збалансований список |
| Stream | listpack | Послідовність записів з ID і полями |
Redis автоматично перемикається між кодуваннями:
наприклад, маленький Hash зберігається як компактний listpack,
а при рості - перетворюється на повноцінну hashtable.
4. Оптимізація пам'яті
Redis застосовує низку технік для зменшення overhead:
- Shared integers: маленькі числа (0-9999) зберігаються як спільні об'єкти.
- SDS (Simple Dynamic String): рядки реалізовані з метаданими (довжина, буфер, місткість).
- Compact structures:
listpack,ziplistіintsetзберігають елементи поспіль в одному блоці пам'яті.
Результат: менше накладних витрат, швидше виділення й звільнення пам'яті.
5. Тип значення відомий миттєво
Redis не робить перевірок "на льоту" - тип і кодування відомі одразу за об'єктом.
Тому команди на кшталт GET чи HGETALL виконуються за O(1), без додаткових перетворень.
6. Приклад у дії
Коли ти виконуєш:
SET age 30Redis:
- створює ключ
age(String), - бачить, що значення - число,
- зберігає його як об'єкт з
type = REDIS_STRING,encoding = int,ptr = 30.
Якщо потім зробити:
SET description "long text about user ..."→ type = REDIS_STRING, але encoding = raw,
оскільки це вже рядок, не число.
Підсумок
Під капотом Redis зберігає кожне значення як об'єкт (RedisObject),
у якому вказано:
- тип даних (string, hash, list …),
- кодування зберігання (int, ziplist, hashtable …),
- вказівник на вміст.
Завдяки цьому Redis уміє автоматично обирати оптимальне представлення й працювати з пам'яттю максимально ефективно - швидко, компактно й передбачувано.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.