Към съдържанието
wannacode

Key-value и кешът

Накратко: Key-value базата, като Redis, е речник в паметта, който по ключ връща стойност много бързо и затова служи за кеш, сесии и броячи.

Проблем

Страницата, която пита същото хиляди пъти

Началната страница на магазина показва трите най-продавани продукта. Заявката е тази:

SQLбаза: магазин

Тя свързва три таблици и събира всички редове на поръчките. При 2000 отваряния в минута базата я пуска 2000 пъти, а отговорът се сменя веднъж на няколко часа. Количката и входът в профила също питат базата на всяка страница за едно и също. Трябва място, където готовият отговор се взима за части от милисекундата.

Идеята

Ключ и стойност

Key-value базата е речник: всяка стойност има ключ, и по ключа я взимаш. Няма таблици, колони и заявки по стойност. Затова е толкова бърза: Redis държи всичко в паметта и отговаря за микросекунди.

Полето е симулатор с командите на Redis. Ключовете обикновено се пишат с двоеточие, за да се знае какво има в тях:

key-value (като Redis)симулатор

GET на ключ, който го няма, дава (nil). Стойността е текст, дори когато е число: базата не знае, че 7.90 е цена.

Пробвай

Брояч на разглежданията

INCR увеличава число в ключа с 1 и връща новото. Ако ключът го няма, започва от 0. Две страници, които броят едновременно, не си пречат: всяка команда в Redis се изпълнява цялата, преди следващата.

Продукт 7 е разгледан три пъти, а продукт 9 веднъж. Преброй разглежданията в ключовете views:product:7 и views:product:9.

key-value (като Redis)симулатор

Идеята

Кеш с изтичане

Кешът е копие на отговор, който е скъпо да се сметне. Програмата първо гледа в кеша. Ако там няма нищо, пита базата и слага отговора в кеша за определено време (EX в секунди). Това време е TTL (time to live), а TTL показва колко остава:

key-value (като Redis)симулатор

След 60 секунди ключът изчезва сам, и следващото отваряне пак пита базата. Така кешът никога не остарява с повече от минута, а базата пуска заявката веднъж в минута, не 2000 пъти.

По-точно, за любопитните

SLEEP е команда само на симулатора: придвижва часовника му, за да не чакаш наистина. В истинския Redis времето си тече. Симулаторът подрежда отговора на SMEMBERS и KEYS по азбучен ред, а Redis не обещава никакъв ред. И KEYS не се пуска на истински сървър с милиони ключове: обхожда всичките и спира всички останали команди. Там се ползва SCAN.

Виж го

Остарялото копие

Цената на кафето пада от 14,90 € на 12,90 €. Базата е обновена, а кешът още пази старата страница за още 10 минути:

key-value (като Redis)симулатор

Това е най-честата грешка с кеш: копието се разминава с истината. Затова програмата, която променя продукта в базата, веднага трие копието му в кеша (DEL). Следващото отваряне не намира нищо, пита базата и слага новата цена. TTL остава като предпазна мрежа, ако някой път забравиш.

Пробвай

Нова цена на сиренето

В кеша са страниците на сиренето (продукт 7) и маслото (продукт 9). Цената на сиренето току-що се смени в базата. Направи така, че следващото отваряне на сиренето да вземе новата цена, без да пипаш маслото.

key-value (като Redis)симулатор

Идеята

Не само текст

Стойността в Redis може да е и структура. Всяка има свои команди:

  • хеш (HSET, HGET, HINCRBY, HGETALL): полета под един ключ, като количка с продукт и количество;
  • списък (LPUSH, LRANGE, LTRIM): подредени стойности, като последно разгледаните;
  • подредено множество (ZADD, ZINCRBY, ZREVRANGE): членове с резултат, подредени по него, като класация.

Количката на клиент 42 (продукт 9, масло, две бройки, и продукт 5, мляко, една), която изтича след седмица без активност:

key-value (като Redis)симулатор

Последните три разгледани продукта. LPUSH слага отпред, а LTRIM реже всичко след третия:

key-value (като Redis)симулатор

Продадените бройки за октомври, класирани:

key-value (като Redis)симулатор

При равни резултати Redis подрежда членовете по азбучен ред (тук обратен, защото класацията е отгоре надолу).

Упражнение

Сесия, количка и класация

1. Клиент 42 влиза в профила си. Сайтът му дава номер на сесия 9f2c и пази в Redis кой е той.

Запиши в ключа session:9f2c номера на клиента (42) така, че сесията да изтече сама след 30 минути.

key-value (като Redis)симулатор

2. Количката на клиент 7 е в хеша cart:7: полето е номерът на продукта, а стойността е количеството.

Клиент 7 слага в количката 2 пакета масло (продукт 9) и 1 мляко (продукт 5). После добавя още едно масло и маха млякото.

key-value (като Redis)симулатор

3. В ключа rating е средната оценка на всеки продукт.

Покажи трите продукта с най-висока оценка, заедно с оценките, от най-високата надолу.

key-value (като Redis)симулатор

Идеята

Кога key-value, кога не

Key-value базата е добра, когато винаги знаеш ключа: кеш, сесии, колички, броячи, ограничение на заявките („най-много 5 опита за вход в минута“), опашки от задачи. Тя не е добра, когато питаш по стойност („всички продукти под 5 €“), когато данните са свързани („поръчките на клиента с продуктите им“) и когато загубата им е недопустима. Затова обикновено стои до SQL базата, а не вместо нея: базата е истината, а Redis е бързото ѝ копие.

По-точно, за любопитните

Освен Redis (и съвместимия с него Valkey) key-value бази са Memcached (само кеш, без структури), DynamoDB в AWS (с ключ и сортиращ ключ, на диск, разпределена) и etcd (за настройки на клъстери, с акцент върху консистентността). Redis пази данните на диск по два начина: снимка през няколко минути (RDB) или дневник на всяка команда (AOF).

Тест

Провери се

1. Кое НЕ може да се направи в key-value база, без да прочетеш всички ключове?
2. Списъкът с най-продаваните се пази в кеша за 60 секунди. Какво е цената на това?
3. Цената на кафето се смени в базата. Кое е най-сигурното за кеша?
4. Redis пази данните в паметта. Какво става при рестарт?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·