IlmHamroh
JavaScript Full-stack/27-qism. Ma'lumotlar bazasi chuqur: Postgres, ORM, Mongo, Redis53/65-dars16 daqiqa
Mundarija (28)

Redis nima va ulanish: xotiradagi kalit-qiymat ombori Node'da

Qisqacha: Redis — ma'lumotni operativ xotirada saqlaydigan kalit-qiymat ombori: kesh, sessiya, navbat va hisoblagichlar uchun. Buyruqlar bitta oqimda, birin-ketin bajariladi — shuning uchun har bitta buyruq atomik. Node'dan ulanish uchun kursda rasmiy redis (node-redis 6.3) paketini olamiz: kanon o'lchovida u parallel so'rovlarni avtomatik quvurlaydi (10 000 SET + 10 000 GET — 119 ms) va noto'g'ri turdagi qiymatni rad etadi.

Bu darsda

  • Redis nima, Postgres'dan nimasi bilan farq qilishini va qachon kerakligini tushuntirasiz.
  • Redis 8 ni Docker'da ishga tushirib, redis-cli bilan birinchi buyruqlarni berasiz.
  • Node'dan node-redis bilan ulanasiz, xato va qayta ulanishni sozlaysiz.
  • node-redis va ioredis farqini o'lchov bilan bilasiz.
  • Redis litsenziyasi tarixi va Valkey nima ekanini bilasiz.

Oldin bilishingiz kerak: Volume va bind mount (Docker), DB turlari xaritasi va SQL vs NoSQL, Connection pooling.

Oldingi darsda MongoDB xavfsizligi va operatsiyasini ko'rib, Mongo bo'limini yakunladik (MongoDB xavfsizligi va operatsiyasi). Endi uchinchi turdagi bazaga o'tamiz — Redis.

1. Nega bu kerak?

vazifalar ilovasida bosh sahifa har ochilganda statistika chiqadi: jami vazifalar, bajarilganlar, teglar soni. Kanonning katta bazasida (500 000 vazifa) bu so'rov Postgres'da 9.5 ms oldi. Bir foydalanuvchi uchun bu sezilmaydi. Lekin sahifani sekundiga 1 000 kishi ochsa — Postgres sekundiga 1 000 marta aynan bir xil hisobni qayta qiladi.

Natija esa bir necha soniya davomida o'zgarmaydi. Uni bir marta hisoblab, tez joyga qo'yib qo'ysak bo'ladi. Xuddi shu statistika Redis'dan 1.5 ms da qaytdi (Caching naqshlari darsida to'liq o'lchaymiz).

O'xshatish: Postgres — omborxona. Hamma narsa tartib bilan, mustahkam, lekin har safar javonlar orasidan yurib topasiz. Redis — sotuvchining peshtaxtasi: eng ko'p so'raladigan narsalar qo'l ostida. Peshtaxta kichik va tunda tozalanishi mumkin, lekin tez.

Redis bundan tashqari yana to'rt joyda ishlatiladi:

  • Sessiya — foydalanuvchi tizimga kirganini eslab qolish (28-qismda).
  • Navbat — "email yuborish" kabi ishlarni fonga topshirish (BullMQ — 29-qismda; u Redis ustida ishlaydi).
  • Hisoblagichlar — ko'rishlar soni, so'rovlar chegarasi (rate limit).
  • Reyting va real vaqt — eng faol foydalanuvchilar, xabarlar oqimi.
flowchart LR
  A[API server] -->|1. avval| R[(Redis: kesh)]
  R -.->|yo'q bo'lsa| A
  A -->|2. keyin| P[(Postgres: asosiy baza)]
  A -->|natijani qo'yadi| R

Bitta so'rov ikki yo'ldan biriga ketadi:

Qadam Redis'da bor (kesh hit) Redis'da yo'q (kesh miss)
1 API Redis'dan so'raydi — javob bor API Redis'dan so'raydi — bo'sh
2 javob darhol qaytadi API Postgres'dan hisoblaydi
3 — natijani Redis'ga qo'yadi va qaytaradi
Kanon vaqti 1.5 ms Postgres 9.5 ms + Redis'ga yozish

Diagrammaga qarang: Postgres — haqiqat manbai, hamma ma'lumot u yerda. Redis — uning yonidagi tez yordamchi. Redis'dagi narsa yo'qolsa, uni Postgres'dan qayta tiklash mumkin bo'lishi kerak.

2. Redis qanday tuzilgan

2.1 Kalit-qiymat ombori

Kalit-qiymat ombori (key-value store) — har ma'lumot bitta nom (kalit) ostida saqlanadigan baza. Jadval, ustun, JOIN yo'q. Xuddi JavaScript'dagi Map ga o'xshaydi: map.set("kalit", qiymat), map.get("kalit").

Farqi — qiymat turlari boyroq. Satr (string) dan tashqari ro'yxat (list), to'plam (set), tartiblangan to'plam (sorted set), hash va boshqalar bor. Ularni keyingi uch darsda ko'ramiz.

2.2 Xotirada (in-memory)

Postgres ma'lumotni diskda saqlaydi, tez-tez kerak bo'lganini xotirada keshlaydi (Postgres arxitekturasi). Redis teskarisi: hamma ma'lumot operativ xotirada (in-memory). Diskka nusxa esa faqat zaxira uchun yoziladi.

Shuning uchun Redis juda tez. Lekin ikki chegarasi bor:

  • Ma'lumot hajmi operativ xotiradan katta bo'la olmaydi.
  • Server keskin o'chsa, oxirgi yozuvlar yo'qolishi mumkin. Qanchasi yo'qolishi sozlamaga bog'liq — Redis persistence va operatsiya darsida o'lchaymiz.

2.3 Bitta oqimda bajarilish

Redis buyruqlarni bitta oqimda (single-threaded) bajaradi: ikkita buyruq hech qachon bir vaqtda ishlamaydi. Minglab mijoz ulangan bo'lsa ham, buyruqlar navbatga turadi va birin-ketin bajariladi.

Bu ikki narsani anglatadi:

  1. Har bitta buyruq atomik. INCR hisob ni 100 mijoz bir vaqtda yuborsa — natija aniq 100. Hech qaysi buyruq boshqasining o'rtasiga tushmaydi.
  2. Bitta sekin buyruq hammani to'xtatadi. Masalan millionlab kalitni ko'radigan KEYS * ishlab turganda boshqa hamma mijoz kutadi. Bu tuzoqni keyingi darsda o'lchaymiz.

Kanon INFO server buyrug'idan kerakli qatorlarni olgan:

text
{"redis_version":"8.10.2","redis_mode":"standalone","os":"Linux 6.6.87.2-microsoft-standard-WSL2 x86_64","arch_bits":"64","multiplexing_api":"epoll","process_id":"1","io_threads_active":"0"}
  • redis_mode standalone — bitta server (klaster emas).
  • multiplexing_api epoll — Linux'ning ulanishlarni kuzatish mexanizmi. Bitta oqim minglab ulanishni shu orqali boshqaradi — Node'dagi g'oya bilan bir xil (libuv thread pool va OS asinxron I/O).
  • io_threads_active 0 — qo'shimcha kiritish-chiqarish oqimlari o'chiq. Redis 6 dan beri tarmoq o'qish-yozish uchun qo'shimcha oqim yoqish mumkin. Lekin buyruqlarning o'zi baribir bitta oqimda bajariladi.

Tekshirib ko'ring: 50 ta API serveri bir vaqtda INCR korishlar yuboradi. Redis bitta oqimli bo'lsa, bu sekin emasmi?

Javob

Yo'q. Bitta INCR xotiradagi sonni oshiradi — mikrosekundlar ishi. Vaqtning asosiy qismi tarmoqda ketadi (so'rov borib-kelishi), u esa parallel. Bitta oqim sekundiga yuz minglab bunday buyruqni bajara oladi. Muammo faqat bitta buyruq o'zi uzoq ishlasa boshlanadi (masalan KEYS * katta bazada).

3. Redis'ni ishga tushirish

3.1 Docker'da

Redis rasmiy ravishda Linux uchun chiqariladi. Windows'da eng oson yo'l — Docker (Image, container va registry):

bash
docker run -d --name redis -p 127.0.0.1:6379:6379 \
  -v redis-data:/data redis:8 \
  redis-server --appendonly yes --save 60 1000
  • -p 127.0.0.1:6379:6379 — port faqat shu kompyuterdan ochiq. Parolsiz Redis'ni hech qachon 0.0.0.0 ga ochmang: internetdagi botlar ochiq Redis'larni doim qidiradi.
  • -v redis-data:/data — ma'lumot konteyner o'chirilganda ham qoladi.
  • --appendonly yes --save 60 1000 — diskka yozish sozlamalari (AOF va RDB). Ma'nosini Redis persistence darsida o'rganamiz.

6379 — Redis'ning standart porti. Kanon o'z konteynerini 6380 da ochgan (6379 band edi), shuning uchun kanon kodida redis://127.0.0.1:6380 uchraydi.

3.2 redis-cli

redis-cli — Redis'ning terminal mijozi, psql'ning Redis'dagi o'xshashi (psql chuqur). U konteyner ichida bor:

bash
docker exec -it redis redis-cli

Kanon birinchi buyruqlarni shunday berdi (kalit nomidagi vz: — ilova prefiksi, keyingi darsda tushuntiramiz):

text
127.0.0.1:6379> SET vz:foydalanuvchi:1:ism Aziz Karimov
OK
127.0.0.1:6379> GET vz:foydalanuvchi:1:ism
Aziz Karimov

127.0.0.1:6379> — taklif qatori (prompt). SET — kalitga qiymat yozish, OK — muvaffaqiyat. GET — o'qish. Buyruqlar katta harf bilan yozilishi an'ana, lekin Redis kichigini ham tushunadi (get …). Chiqish uchun exit.

Qiymatda bo'shliq bor, shuning uchun o'zingiz yozganda uni qo'shtirnoqqa oling: SET vz:foydalanuvchi:1:ism "Aziz Karimov". Qo'shtirnoqsiz Redis Karimov ni SET ning noma'lum parametri deb o'qiydi va sintaksis xatosini qaytaradi.

Maslahat: Interaktiv redis-cli javob turini ham ko'rsatadi: satr qo'shtirnoqda ("Aziz Karimov"), son (integer) 1, bo'sh javob (nil). Kursdagi kanon chiqishlari skriptdan olingan — terminal bo'lmaganda redis-cli turni yozmaydi (Aziz Karimov, 1, bo'sh qator). Ma'nosi bir xil.

3.3 Redis 8, litsenziya va Valkey

Redis tarixida litsenziya ikki marta o'zgargan. Bu kompaniyalar uchun muhim — qaysi versiyani qanday shartlar bilan ishlatish mumkinligi shunga bog'liq.

Versiya Litsenziya Ochiq kodmi
7.2 va oldingilari BSD-3 ha
7.4.x–7.8.x RSALv2 yoki SSPLv1 yo'q
8.0 dan RSALv2, SSPLv1 yoki AGPLv3 (tanlov sizda) ha (AGPLv3)

2024-yilda Redis ochiq kodli litsenziyadan voz kechganda, Linux Foundation 7.2 versiyasidan Valkey nomli fork (ayri nusxa) ochdi. Valkey — BSD-3 litsenziyali, buyruqlari Redis bilan bir xil. 2025-yilda Redis 8 AGPLv3 ni qo'shib, yana ochiq kodga qaytdi (redis.io/legal/licenses, 2026-10-25 da o'qildi).

Amalda: o'z serveringizda ishlatish uchun ikkalasi ham bepul. Farqi Redis 8 ichidagi modullarda — JSON, Bloom filtr, vektorlar. Kanon MODULE LIST buyrug'ini berdi:

text
modullar (Redis 8 ichida): timeseries 81001, vectorset 1, bf 81001, search 81001, ReJSON 81000

Valkey'da bu buyruqlar yo'q (kanon sinadi: JSON.SET → ERR unknown command). Buni Maxsus tuzilmalar va Redis persistence darslarida ko'ramiz.

4. Node'dan ulanish: node-redis

4.1 O'rnatish va birinchi ulanish

Node uchun ikkita mashhur klient bor: rasmiy node-redis (npm'da redis) va ioredis. Kanon ikkalasini o'lchab, node-redis'ni tanladi (sabablari keyingi bo'limda).

bash
npm i redis@6.3.0
js
import { createClient } from "redis";

const redis = createClient({
  url: process.env.REDIS_URL ?? "redis://127.0.0.1:6379",
});
redis.on("error", (e) => console.error("redis:", e.message));
await redis.connect();

console.log("node-redis PING:", await redis.ping());
await redis.quit();

Kanon xuddi shunday ulanib, PING yubordi — bir qatorda ikkala klient uchun (javobdagi PONG — "tirikman"):

text
node-redis PING: PONG | ioredis PING: PONG

Har qatorni ko'ramiz:

  • createClient({ url }) — klient yaratadi, lekin hali ulanmaydi. URL formati: redis://[parol@]host:port[/baza_raqami]. TLS bilan — rediss:// (ikkita s).
  • redis.on("error", …) — majburiy. Ulanish uzilsa klient "error" hodisasini chiqaradi. Tinglovchi bo'lmasa, Node jarayonni yiqitadi — xuddi LISTEN/NOTIFY dagi pg Client kabi.
  • await redis.connect() — ulanish.
  • Har buyruq — klient metodi: ping(), set(), get(). Nomlar Redis buyrug'i bilan bir xil, faqat camelCase: HGETALL → hGetAll, ZADD → zAdd.
  • quit() — navbatdagi buyruqlarni tugatib, ulanishni chiroyli yopadi. destroy() — darhol uzadi.

Diqqat: REDIS_URL ni kodga yozmang, env'dan oling (Environment o'zgaruvchilar va .env). Productionda Redis paroli bo'ladi — u URL ichida keladi va sir hisoblanadi.

4.2 Bitta ulanish yetadi

Postgres'da har so'rovga hovuzdan ulanish olardik — chunki bitta ulanish bir vaqtda bitta so'rovni bajaradi (Connection pooling). Redis'da bunday emas: bitta ulanish orqali minglab buyruqni ketma-ket yuborib, javoblarni tartib bilan olish mumkin. Ilova odatda bitta umumiy klient yaratadi va hamma joyda shuni ishlatadi.

Istisno: blokirovka qiladigan buyruqlar (masalan SUBSCRIBE) va WATCH — ular uchun alohida ulanish kerak. Buni Atomiklik va Pub/Sub va Streams darslarida ko'ramiz.

4.3 Hamma qiymat — satr

Redis qiymatni baytlar ketma-ketligi sifatida saqlaydi. Kanon tajribasi:

js
await redis.set("t53:son", 42);
console.log(
  typeof (await redis.get("t53:son")),
  JSON.stringify(await redis.get("t53:yoq")),
  await redis.incr("t53:son"),
);
text
string null 43
  • 42 sonini yozdik — "42" satr qaytdi. Son kerak bo'lsa — Number(...) bilan o'giring.
  • Yo'q kalit — null (undefined emas).
  • INCR esa satrni son deb o'qib, oshiradi va son qaytaradi (43).

Obyekt saqlash uchun avval JSON.stringify, o'qiganda JSON.parse. Yoki Redis'ning hash turi (Hash, List, Set va Sorted Set).

5. node-redis va ioredis: kanon o'lchovi

5.1 Obyekt qiymat tuzog'i

Kanon ikkala klientga ham obyektni to'g'ridan-to'g'ri berdi:

text
node-redis obyekt qiymat: TypeError: "arguments[2]" must be of type "string | Buffer", got object instead.
ioredis obyekt qiymat: o'tdi → "[object Object]"

node-redis xato bilan to'xtatdi: "argument satr yoki Buffer bo'lishi kerak, obyekt keldi". ioredis esa jim "[object Object]" satrini saqladi. Bu xavfli: kod ishlaydi, test o'tadi, lekin bazada ma'lumot o'rniga axlat. Xato ancha keyin, boshqa joyda chiqadi.

Turni tekshirish yana bir joyda yordam beradi — noto'g'ri tur ustida buyruq:

text
noto'g'ri tur (string ustida LPUSH): WRONGTYPE Operation against a key holding the wrong kind of value

"WRONGTYPE: amal noto'g'ri turdagi qiymat saqlangan kalit ustida". t53:son — satr, LPUSH esa ro'yxat buyrug'i. Bu xatoni Redis o'zi qaytaradi — klientga bog'liq emas.

5.2 Ketma-ket va parallel

Kanon 10 000 SET va 10 000 GET ni ikki usulda yubordi: har buyruqni await bilan kutib (ketma-ket) va hammasini birdan Promise.all bilan (parallel). 3 o'lchov medianasi:

text
node-redis ketma-ket: 28141 ms (711 buyruq/s)
ioredis ketma-ket: 18319 ms (1092 buyruq/s)
node-redis parallel: 119 ms (168251 buyruq/s)
ioredis parallel: 390 ms (51281 buyruq/s)
ioredis enableAutoPipelining parallel: 106 ms
20 000 buyruq: sekundiga nechta
  • node-redis ketma-ket711 buyruq/s
  • ioredis ketma-ket1 092 buyruq/s
  • ioredis parallel51 281 buyruq/s
  • node-redis parallelavtomatik quvurlash sukut168 251 buyruq/s

Manba: IlmHamroh kanon o'lchovi, 2026-10-25: Node 24.21.0, Redis 8.10.2 (Docker, WSL2), i5-12500H, node-redis 6.3.0, ioredis 6.0.0, mediana 3

Grafikka qarang: farq klientlar orasida emas, usullar orasida — yuz baravardan ko'p.

Ketma-ket usulda har buyruq bitta tarmoq aylanishi (round trip) kutadi: so'rov Docker Desktop orqali Linux virtual mashinasiga borib-keladi, ~1 ms. 20 000 × 1 ms ≈ 20–28 s. Redis'ning o'zi bu vaqtning ko'p qismida bo'sh turadi.

Parallel usulda klient buyruqlarni javobni kutmay, ketma-ket bitta oqimga yozib yuboradi. Bu quvurlash (pipelining). G'oya tanish: Postgres'da ham shunday edi (COPY, batch va cursor). node-redis buni sukut bo'yicha qiladi: bir tick ichida berilgan buyruqlar bitta paketda ketadi. ioredis'da bu enableAutoPipelining: true bilan yoqiladi (106 ms).

Xulosa: Redis bilan ishlaganda tezlik kalitining katta qismi — tarmoq aylanishlari sonini kamaytirish. Mustaqil buyruqlarni for … await ichida emas, Promise.all bilan bering. Atomiklik: MULTI, Lua va pipelining darsida buni to'liq o'lchaymiz.

5.3 Server yo'q bo'lsa

Kanon ikkala klientni yopiq portga (6399) ulamoqchi bo'ldi:

text
node-redis connect: 3 urinishdan keyin to'xtadi (653 ms, error hodisalari 4)
ioredis GET (maxRetriesPerRequest 1): Reached the max retries per request limit (which is 1). Refer to "maxRetriesPerRequest" op (215 ms, error hodisalari 2)

Sukut bo'yicha ikkala klient ham cheksiz qayta ulanishga urinadi. Kanon node-redis'ga o'z strategiyasini berdi:

js
const redis = createClient({
  url: "redis://127.0.0.1:6399",
  socket: {
    connectTimeout: 1000,
    reconnectStrategy: (n) =>
      n > 2 ? new Error("3 urinishdan keyin to'xtadi") : 200,
  },
});

reconnectStrategy(n) — n-urinishdan oldin chaqiriladi. Son qaytarsa — shuncha millisekund kutib qayta urinadi. Error qaytarsa — urinishni to'xtatadi va connect() shu xato bilan rad etiladi. false — umuman qayta ulanmaydi.

Server ishlab turgan paytda ulanish uzilsa nima bo'ladi? Klient buyruqlarni xotiradagi navbatga yig'ib, qayta ulanganda yuboradi (offline queue). Kesh uchun bu yomon: so'rov Redis'ni kutib qotib qoladi. Shuning uchun keshda disableOfflineQueue: true qo'yiladi — ulanish yo'q bo'lsa buyruq darhol xato beradi, ilova esa Postgres'dan o'qiydi. vazifalar-api aynan shunday qiladi (Caching naqshlari).

5.4 Tanlov

node-redis 6.3 ioredis 6.0
Kim yozadi Redis kompaniyasi (rasmiy) jamoa
Parallelda quvurlash sukut enableAutoPipelining
Obyekt qiymat TypeError jim "[object Object]"
Import vaqti (sovuq) 936 ms 475 ms
TypeScript turlari ichida ichida

Import vaqti — kanonning oxirgi o'lchovi (alohida jarayon, mediana 7; bo'sh Node 122 ms). Server bir marta ishga tushadi, shuning uchun bu farq odatda muhim emas.

Kanon qarori: node-redis. Rasmiy, sukut sozlamalari xavfsizroq, Redis 8 ning yangi buyruqlari birinchi unda paydo bo'ladi. ioredis ham yaxshi kutubxona — eski loyihalarda ko'p uchraydi, Cluster va Sentinel bilan uzoq tarixi bor. Uni ko'rsangiz qo'rqmang: buyruqlar bir xil, metod nomlari kichik harfda (io.hgetall).

Tekshirib ko'ring: Hamkasbingiz await redis.set("foydalanuvchi:1", foydalanuvchi) yozdi (foydalanuvchi — obyekt). node-redis bilan nima bo'ladi? ioredis bilan-chi?

Javob

node-redis darhol TypeError tashlaydi — xato shu qatorda ko'rinadi va tuzatiladi (JSON.stringify(foydalanuvchi)). ioredis xatosiz "[object Object]" saqlaydi. Keyin JSON.parse qilganda SyntaxError chiqadi — boshqa faylda, boshqa paytda. Ikkinchisini topish ancha qiyin.

6. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
Jarayon ECONNREFUSED bilan yiqiladi redis.on("error") yo'q tinglovchi qo'shing
ClientClosedError: The client is closed connect() chaqirilmagan yoki quit() dan keyin buyruq ishga tushishda bir marta await connect()
Ma'lumot o'rniga [object Object] obyekt JSON.stringify siz yozilgan doim satrga o'giring
"42" + 1 → "421" get() satr qaytaradi Number(await redis.get(k))
10 000 buyruq 28 s ishlaydi har buyruq alohida await Promise.all — quvurlash
Redis o'chganda API qotib qoladi offline queue buyruqlarni kutadi keshda disableOfflineQueue: true
Kimdir Redis'ingizni o'chirib qo'ydi port 0.0.0.0 ga parolsiz ochiq 127.0.0.1, parol, tarmoq cheklovi

7. Mashqlar

Mashqlar kurs/mashqlar/27/53-redis/ da.

1-mashq (oson): bo'shliqlarni to'ldiring

  • Redis ma'lumotni asosan da saqlaydi.
  • Buyruqlar bitta da bajariladi, shuning uchun har bir buyruq atomik.
  • Redis'ning standart porti —
  • Yo'q kalitga GET node-redis'da qaytaradi.
  • Redis 7.2 dan ayrilgan BSD litsenziyali fork —
Yechim
  • xotira — diskka faqat zaxira nusxa yoziladi.
  • oqim — buyruqlar navbat bilan, birin-ketin.
  • 6379 — kanon 6380 ishlatgan, chunki 6379 band edi.
  • null — undefined emas.
  • Valkey — Linux Foundation loyihasi.

2-mashq (o'rta): INFO javobini o'qish

INFO server javobi — kalit:qiymat qatorlari, # bilan boshlanadigan bo'lim sarlavhalari va bo'sh qatorlar (qator oxiri \r\n). infoniOqi(matn, kerakli) funksiyasini yozing: faqat kerakli massividagi kalitlarni obyektga yig'sin. Pastdagi namuna bilan sinang (redis_version, io_threads_active, tcp_port).

Yechim
js
function infoniOqi(matn, kerakli) {
  const natija = {};
  for (const qator of matn.split("\r\n")) {
    if (qator === "" || qator.startsWith("#")) continue;
    const i = qator.indexOf(":");
    const kalit = qator.slice(0, i);
    if (kerakli.includes(kalit)) {
      natija[kalit] = qator.slice(i + 1);
    }
  }
  return natija;
}

const namuna = [
  "# Server",
  "redis_version:8.10.2",
  "redis_mode:standalone",
  "os:Linux 6.6.87.2-microsoft-standard-WSL2 x86_64",
  "io_threads_active:0",
  "tcp_port:6379",
  "",
].join("\r\n");

console.log(infoniOqi(namuna, [
  "redis_version", "io_threads_active", "tcp_port",
]));

Konsolda:

text
{ redis_version: '8.10.2', io_threads_active: '0', tcp_port: '6379' }

split(":") o'rniga birinchi : ning o'rnini oldik (indexOf): qiymatning o'zida ikki nuqta bo'lishi mumkin (masalan executable:/usr/local/bin/redis-server yoki IPv6 manzil). Qiymatlar satr qoldi — Redis javobining o'zi satr.

3-mashq (qiyin): qayta ulanish strategiyasi

qaytaUlanishVaqti(n, maks) funksiyasini yozing (node-redis reconnectStrategy uchun): kutish 100 ms dan boshlanib, har urinishda ikki baravar oshsin, lekin 5 000 ms dan oshmasin. n (urinish raqami, 0 dan) maks dan katta bo'lsa — Error qaytarsin ("Redis'ga ulanib bo'lmadi: N urinish"). n = 0…7 va maks = 6 uchun natijani chiqaring: son bo'lsa son, xato bo'lsa xabari.

Yechim
js
function qaytaUlanishVaqti(n, maks) {
  if (n > maks) {
    return new Error(`Redis'ga ulanib bo'lmadi: ${n} urinish`);
  }
  return Math.min(5000, 100 * 2 ** n);
}

for (let n = 0; n <= 7; n++) {
  const r = qaytaUlanishVaqti(n, 6);
  console.log(n, r instanceof Error ? r.message : r);
}

Konsolda:

text
0 100
1 200
2 400
3 800
4 1600
5 3200
6 5000
7 Redis'ga ulanib bo'lmadi: 7 urinish

Ulashda: createClient({ url, socket: { reconnectStrategy: (n) => qaytaUlanishVaqti(n, 6) } }). Eksponensial kutish (timers va timers/promises chuqur dagi g'oya) — Redis qayta ishga tushayotganda yuzlab server uni har 100 ms da "bombardimon" qilmaydi. Productionda ko'pincha chegara qo'yilmaydi (ilova Redis qaytguncha kutadi), lekin testlarda va CLI skriptlarda chegara kerak — aks holda jarayon abadiy osilib qoladi.

8. Loyiha qadami: kanon tajribasi, loyihaga hali kirmaydi

vazifalar-api ga bu darsda kod qo'shilmaydi. Redis loyihaga Caching naqshlari va invalidatsiya darsida kesh sifatida kiradi. Ungacha o'zingiz sinab ko'ring: Docker'da redis:8 ni ishga tushiring, redis-cli da PING, SET, GET ni bering. Keyin alohida tajriba papkasida (vazifalar-api da emas) npm i redis@6.3.0 va «Node'dan ulanish» bo'limidagi skriptni yurgizing.

9. Real ishda

  • Kesh va sessiya — deyarli har katta veb-loyihada keng tarqalgan arxitektura: Postgres (yoki boshqa asosiy baza) + yonida Redis.
  • Navbatlar — BullMQ, Sidekiq (Ruby), Celery (Python) Redis'ni broker sifatida ishlatadi.
  • Managed Redis — AWS ElastiCache, Upstash, Redis Cloud: serverni o'zingiz yuritmaysiz (Redis persistence va operatsiya).
  • Intervyuda: "Redis nega tez?", "Redis bitta oqimli bo'lsa, qanday qilib ko'p mijozga xizmat qiladi?", "Redis'ni asosiy baza sifatida ishlatsa bo'ladimi?"

Xulosa

  • Redis — xotiradagi kalit-qiymat ombori; Postgres yonida tez yordamchi, haqiqat manbai emas.
  • Buyruqlar bitta oqimda — har buyruq atomik, lekin bitta sekin buyruq hammani kutdiradi.
  • Docker'da redis:8, port faqat 127.0.0.1; redis-cli — terminal mijozi.
  • node-redis (rasmiy): createClient → on("error") → connect(); qiymatlar satr, yo'q kalit null.
  • Tezlik — tarmoq aylanishlarini kamaytirishda: parallel buyruqlar avtomatik quvurlanadi (28 s → 119 ms).
  • Redis 8 — AGPLv3 bilan yana ochiq kod; Valkey — BSD fork, Redis 8 modullarisiz.

Keyingi dars: String, TTL va kalit nomlash — SET … EX NX, kalitning yashash vaqti, INCR hisoblagichlar va nega KEYS productionda taqiqlanadi.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Redis nima va ulanish: xotiradagi kalit-qiymat ombori Node'da — IlmHamroh