Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Kesh nima va nega
- 2.2. Redis nima
- 2.3. Asosiy amallar (get/set/incr)
- 2.4. TTL (yashash muddati)
- 2.5. Kesh-aside namunasi
- 2.6. Kesh invalidatsiya
- 2.7. Tuzilmalar (hash, list)
- 2.8. Kesh xavflari
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Redis asosiy amallar
- Misol 2 — TTL (yashash muddati)
- Misol 3 — Kesh-aside namunasi (hit/miss)
- Misol 4 — Amaliy: kesh qatlami (invalidatsiya + tuzilma)
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
23.10-dars: Redis va kesh
23-QISM — BAZALAR VA ORM · 10-dars
1. Kirish va motivatsiya
23.9 da N+1'ni yechdik — so'rovlar sonini kamaytirdik. Lekin ba'zi ma'lumot juda tez-tez so'raladi: bosh sahifa kurslari, foydalanuvchi profili, valyuta kursi. Har so'rovda bazaga borish — hatto optimallashtirilgan so'rov ham — keraksiz yuk. Agar ma'lumot kam o'zgarsa, uni xotirada saqlash (kesh) mumkin: birinchi marta bazadan, keyingi martalar xotiradan (mikrosoniya).
Kesh (cache) — tez-tez so'ralgan ma'lumotni tez xotirada vaqtincha saqlash. Redis — eng mashhur kesh (xotirada ishlaydigan kalit-qiymat baza): juda tez (RAM), TTL (yashash muddati), turli tuzilma (string, hash, list, set). Kesh-aside namunasi: bazaga borishdan oldin keshni tekshir — bor bo'lsa keshdan (tez), yo'q bo'lsa bazadan + keshga yoz.
Real vaziyat. Bosh sahifa har ochilganda 20 ta so'rov bazaga borardi — 300ms. Ma'lumot soatda bir marta o'zgarardi, lekin har foydalanuvchi uchun qayta hisoblanardi. Redis kesh qo'shildi: birinchi so'rov bazadan (300ms) + keshga yozildi (TTL 300s). Keyingi 5 daqiqada barcha so'rov keshdan — 2ms. Baza yuki 95% kamaydi, sahifa 150 barobar tez. Bir kesh qatlami katta farq qildi.
Bu darsda Redis va keshni — xotira baza, TTL, kesh-aside namunasini o'rganamiz.
Bu darsda:
- Kesh nima va nega
- Redis nima
- Asosiy amallar (get/set/incr)
- TTL (yashash muddati)
- Kesh-aside namunasi
- Kesh invalidatsiya
- Tuzilmalar (hash, list)
- Amaliy: kesh qatlami
ℹ Misollarda
fakeredis(haqiqiy Redis API, xotirada) bilan sinaladi.
2. Nazariya — chuqur tushuntirish
2.1. Kesh nima va nega
Kesh — tez-tez kerak ma'lumotni tez joyda saqlash:
So'rov → keshda bormi?
ha → keshdan qaytar (tez, ~1ms)
yo'q → bazadan o'qi (sekin, ~50ms) + keshga yozKesh — tez-tez so'ralgan, kam o'zgaradigan ma'lumotni tez xotirada vaqtincha saqlash. Maqsad: bazaga murojaatni kamaytirish (baza sekin — disk, tarmoq). Kesh tez (RAM), lekin vaqtincha (o'chib ketishi mumkin) va eskirishi mumkin (ma'lumot o'zgarsa). "Tez, lekin ishonchsiz nusxa".
2.2. Redis nima
Redis — xotirada ishlaydigan kalit-qiymat baza:
import redis
r = redis.Redis(host="localhost", port=6379, decode_responses=True)
r.set("kurs:1", "Python")
r.get("kurs:1") # "Python" Redis (REmote DIctionary Server) — xotirada (RAM) ishlaydigan kalit-qiymat baza. Juda tez (mikrosoniya), turli tuzilma (string, hash, list, set, sorted set), TTL (avtomatik o'chirish). Asosiy ishlatilishi: kesh, sessiya, navbat (queue), hisoblagich, real-vaqt reyting. redis.Redis() — Python mijozi.
2.3. Asosiy amallar (get/set/incr)
Redis asosiy buyruqlari:
r.set("kalit", "qiymat") # yoz
r.get("kalit") # o'qi
r.delete("kalit") # o'chir
r.exists("kalit") # bormi (1/0)
r.incr("hisoblagich") # +1 (atomik)
r.set("k", "v", nx=True) # faqat yo'q bo'lsa Asosiy amallar: set/get (yoz/o'qi), delete (o'chir), exists (bormi), incr/decr (atomik +1/-1 — hisoblagich uchun), nx=True (faqat mavjud bo'lmasa). incr atomik — ko'p mijoz bir vaqtda ishlatsa ham to'g'ri (23.4 tranzaksiya kabi). Kalit odatda tur:id (kurs:1).
2.4. TTL (yashash muddati)
TTL — kalitning avtomatik o'chish muddati:
r.setex("sessiya:abc", 300, "user42") # 300 soniya, keyin o'chadi
r.expire("kalit", 60) # mavjud kalitga TTL
r.ttl("kalit") # qolgan soniya
r.persist("kalit") # TTL'ni olib tashla TTL (Time To Live) — kalit necha soniyadan keyin avtomatik o'chish. setex(kalit, soniya, qiymat) (TTL bilan yoz), expire (mavjudga TTL), ttl (qolgan vaqt), persist (TTL olib tashla). Kesh uchun muhim: eski ma'lumot avtomatik o'chadi (TTL tugasa qayta bazadan). Sessiya, vaqtincha ma'lumot uchun ideal.
2.5. Kesh-aside namunasi
Eng keng tarqalgan kesh namunasi:
def kurs_ol(id):
kesh = r.get(f"kurs:{id}")
if kesh is not None: # kesh hit
return kesh
qiymat = bazadan_ol(id) # kesh miss → baza
r.setex(f"kurs:{id}", 300, qiymat) # keshga yoz
return qiymatKesh-aside (cache-aside / lazy loading): 1) keshni tekshir, 2) bor bo'lsa qaytar (hit — tez), 3) yo'q bo'lsa bazadan o'qi (miss), keshga yoz (TTL bilan), qaytar. Bu eng keng tarqalgan namuna. "Hit nisbati" (hit rate) — necha % kesh'dan keldi (yuqori = yaxshi). Birinchi so'rov sekin (miss), keyingilar tez (hit).
2.6. Kesh invalidatsiya
Ma'lumot o'zgarsa — keshni yangila:
def kurs_yangila(id, yangi):
bazada_yangila(id, yangi) # bazani yangila
r.delete(f"kurs:{id}") # keshni o'chir (invalidatsiya)
# keyingi o'qishda yangi qiymat keshga Kesh invalidatsiya — ma'lumot o'zgarganda keshni o'chirish yoki yangilash (aks holda eski ma'lumot qaytadi). Ikki usul: o'chir (delete — keyingi o'qishda qayta yuklanadi) yoki yangila (set — darrov yangi). "Keshda faqat ikki qiyin narsa bor: kesh invalidatsiya va nomlash" (mashhur ibora) — invalidatsiya qiyin (qachan, qaysini).
2.7. Tuzilmalar (hash, list)
Redis turli tuzilma:
| Tuzilma | Buyruq | Ishlatilish |
|---|---|---|
| String | set/get |
oddiy qiymat, JSON |
| Hash | hset/hgetall |
obyekt (maydonlar) |
| List | rpush/lrange |
navbat, oxirgi N |
| Set | sadd/smembers |
noyob to'plam |
| Sorted set | zadd/zrange |
reyting (ball bilan) |
Redis — nafaqat string: hash (hset — obyekt maydonlari), list (rpush/lpush — navbat, oxirgi hodisalar), set (sadd — noyob to'plam, 4.x), sorted set (zadd — reyting, ball bo'yicha). Bu Redis'ni kuchli qiladi: kesh + navbat + reyting + sessiya — bir vositada.
2.8. Kesh xavflari
| Xavf | Yechim |
|---|---|
| Eski ma'lumot | TTL + invalidatsiya |
| Kesh o'chib ketdi | Bazadan qayta (kesh ixtiyoriy) |
| Kesh bo'roni (miss to'lqini) | TTL tarqatish, qulf |
| Xotira to'ldi | LRU siyosat (eskini chiqar) |
Kesh xavflari: eski ma'lumot (stale — TTL va invalidatsiya bilan), kesh o'chishi (Redis vaqtincha — ilova bazadan ishlash davom etishi kerak, kesh ixtiyoriy bo'lsin), kesh bo'roni (bir vaqtda ko'p miss — bazaga zarba), xotira chegarasi (LRU — eng kam ishlatilganni chiqar). Kesh — yordamchi, asosiy manba emas.
3. Tez ma'lumotnoma
import redis
r = redis.Redis(host="localhost", port=6379, decode_responses=True)
# asosiy:
r.set("kurs:1", "Python"); r.get("kurs:1")
r.delete("kurs:1"); r.exists("kurs:1"); r.incr("koradi")
# TTL:
r.setex("sessiya:abc", 300, "user42") # 300s
r.expire("k", 60); r.ttl("k"); r.persist("k")
# kesh-aside:
def ol(id):
v = r.get(f"kurs:{id}")
if v is not None: return v # hit
v = bazadan_ol(id) # miss
r.setex(f"kurs:{id}", 300, v); return v
# invalidatsiya:
bazada_yangila(id); r.delete(f"kurs:{id}")
# tuzilmalar:
r.hset("user:1", mapping={"nom": "Ali"}); r.hgetall("user:1")
r.rpush("navbat", "a"); r.lrange("navbat", 0, -1)Kesh xulosasi
Kesh: tez xotira (Redis) · kesh-aside: tekshir → hit/miss → yoz
TTL: avtomatik o'chish · invalidatsiya: o'zgarsa o'chir
Kesh ixtiyoriy: o'chsa bazadan4. Batafsil misollar
Misollarda
fakeredis(haqiqiy Redis API, xotirada — server kerak emas) bilan sinaladi. Real ilovadaredis.Redis(host=...)ishlatiladi, API bir xil.
Misol 1 — Redis asosiy amallar
"""set/get (yoz/o'qi); delete/exists; incr (atomik hisoblagich); nx (faqat yo'q bo'lsa)."""
import warnings
warnings.filterwarnings("ignore")
import fakeredis
def main() -> None:
r = fakeredis.FakeStrictRedis(decode_responses=True)
print("=== 1. set / get ===")
r.set("kurs:1", "Python")
r.set("kurs:2", "Go")
print(f" kurs:1 = {r.get('kurs:1')}")
print(f" kurs:2 = {r.get('kurs:2')}")
print(f" yo'q kalit = {r.get('kurs:99')}")
print("\n=== 2. exists / delete ===")
print(f" kurs:1 bormi: {r.exists('kurs:1')}")
r.delete("kurs:1")
print(f" o'chirgandan keyin: {r.exists('kurs:1')}")
print("\n=== 3. incr (atomik hisoblagich) ===")
r.set("korishlar", 0)
for _ in range(5):
r.incr("korishlar")
print(f" ko'rishlar: {r.get('korishlar')}")
print("\n=== 4. nx (faqat mavjud bo'lmasa) ===")
r.set("bir_martalik", "birinchi", nx=True)
r.set("bir_martalik", "ikkinchi", nx=True) # o'zgarmaydi
print(f" qiymat: {r.get('bir_martalik')}")
print(" ⭐ set/get/incr — Redis asosi (tez, atomik)")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. set / get ===
kurs:1 = Python
kurs:2 = Go
yo'q kalit = None
=== 2. exists / delete ===
kurs:1 bormi: 1
o'chirgandan keyin: 0
=== 3. incr (atomik hisoblagich) ===
ko'rishlar: 5
=== 4. nx (faqat mavjud bo'lmasa) ===
qiymat: birinchi
⭐ set/get/incr — Redis asosi (tez, atomik)Nima ko'rsatdi: 2.2, 2.3-bo'limlar.
Misol 2 — TTL (yashash muddati)
"""setex (TTL bilan yoz); expire (mavjudga TTL); ttl (qolgan); persist (TTL olib tashla)."""
import warnings
warnings.filterwarnings("ignore")
import fakeredis
def main() -> None:
r = fakeredis.FakeStrictRedis(decode_responses=True)
print("=== 1. setex (TTL bilan) ===")
r.setex("sessiya:abc", 300, "user42")
print(f" qiymat: {r.get('sessiya:abc')}")
print(f" TTL bormi (0 dan katta): {r.ttl('sessiya:abc') > 0}")
print("\n=== 2. expire (mavjud kalitga TTL) ===")
r.set("kesh:kurslar", "Python,Go,Rust")
print(f" TTL oldin: {r.ttl('kesh:kurslar')}") # -1 (TTL yo'q)
r.expire("kesh:kurslar", 60)
print(f" TTL keyin (0 dan katta): {r.ttl('kesh:kurslar') > 0}")
print("\n=== 3. persist (TTL olib tashla) ===")
r.persist("kesh:kurslar")
print(f" TTL persist keyin: {r.ttl('kesh:kurslar')}") # -1
print("\n=== 4. TTL holatlari ===")
print(f" TTL yo'q kalit (-1): {r.ttl('kesh:kurslar')}")
print(f" mavjud emas kalit (-2): {r.ttl('yoq:kalit')}")
print(" ⭐ TTL — kalit avtomatik o'chadi (kesh, sessiya)")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. setex (TTL bilan) ===
qiymat: user42
TTL bormi (0 dan katta): True
=== 2. expire (mavjud kalitga TTL) ===
TTL oldin: -1
TTL keyin (0 dan katta): True
=== 3. persist (TTL olib tashla) ===
TTL persist keyin: -1
=== 4. TTL holatlari ===
TTL yo'q kalit (-1): -1
mavjud emas kalit (-2): -2
⭐ TTL — kalit avtomatik o'chadi (kesh, sessiya)Nima ko'rsatdi: 2.4-bo'lim.
Misol 3 — Kesh-aside namunasi (hit/miss)
"""kesh-aside: keshni tekshir → hit (tez) yoki miss (bazadan + keshga yoz); so'rov sanash."""
import warnings
warnings.filterwarnings("ignore")
import fakeredis
def main() -> None:
r = fakeredis.FakeStrictRedis(decode_responses=True)
# soxta baza (sekin manba)
BAZA = {1: "Python", 2: "Go", 3: "Rust"}
baza_sanoq = [0]
def bazadan_ol(kurs_id: int) -> str:
baza_sanoq[0] += 1
return BAZA[kurs_id]
def kurs_ol(kurs_id: int) -> str:
kesh = r.get(f"kurs:{kurs_id}")
if kesh is not None:
return kesh # kesh hit
qiymat = bazadan_ol(kurs_id) # kesh miss
r.setex(f"kurs:{kurs_id}", 300, qiymat)
return qiymat
print("=== 1. Birinchi so'rov (miss → baza) ===")
print(f" kurs 1: {kurs_ol(1)} (baza so'rovlari: {baza_sanoq[0]})")
print("\n=== 2. Ikkinchi so'rov (hit → kesh) ===")
print(f" kurs 1: {kurs_ol(1)} (baza so'rovlari: {baza_sanoq[0]})")
print("\n=== 3. Ko'p so'rov (bir necha kurs) ===")
for _ in range(3):
for kid in (1, 2, 3):
kurs_ol(kid)
print(f" 9 takror so'rov, baza so'rovlari: {baza_sanoq[0]}")
print("\n=== 4. Xulosa ===")
print(f" jami baza so'rovi: {baza_sanoq[0]} (3 noyob kurs)")
print(" qolgan hammasi keshdan (hit)")
print(" ⭐ kesh-aside — birinchi miss, keyingilar hit (tez)")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Birinchi so'rov (miss → baza) ===
kurs 1: Python (baza so'rovlari: 1)
=== 2. Ikkinchi so'rov (hit → kesh) ===
kurs 1: Python (baza so'rovlari: 1)
=== 3. Ko'p so'rov (bir necha kurs) ===
9 takror so'rov, baza so'rovlari: 3
=== 4. Xulosa ===
jami baza so'rovi: 3 (3 noyob kurs)
qolgan hammasi keshdan (hit)
⭐ kesh-aside — birinchi miss, keyingilar hit (tez)Nima ko'rsatdi: 2.1, 2.5-bo'limlar.
Misol 4 — Amaliy: kesh qatlami (invalidatsiya + tuzilma)
Real kesh qatlami: kesh-aside o'qish, o'zgarishda invalidatsiya, hash bilan obyekt saqlash. Bu — production kesh mantiqining namunasi.
"""to'liq kesh qatlami: hash (obyekt kesh), kesh-aside, invalidatsiya (o'zgarsa o'chir)."""
import warnings
warnings.filterwarnings("ignore")
import fakeredis
def main() -> None:
r = fakeredis.FakeStrictRedis(decode_responses=True)
BAZA = {1: {"nom": "Python", "narx": "100"}}
baza_sanoq = [0]
def bazadan_ol(kid: int) -> dict:
baza_sanoq[0] += 1
return dict(BAZA[kid])
def kurs_ol(kid: int) -> dict:
kalit = f"kurs:{kid}"
if r.exists(kalit):
return r.hgetall(kalit) # hit (hash)
obyekt = bazadan_ol(kid) # miss
r.hset(kalit, mapping=obyekt)
r.expire(kalit, 300)
return obyekt
def kurs_yangila(kid: int, yangi_narx: str) -> None:
BAZA[kid]["narx"] = yangi_narx # baza
r.delete(f"kurs:{kid}") # invalidatsiya
print("=== 1. Birinchi o'qish (miss → hash kesh) ===")
print(f" {kurs_ol(1)} (baza: {baza_sanoq[0]})")
print("\n=== 2. Ikkinchi o'qish (hit) ===")
print(f" {kurs_ol(1)} (baza: {baza_sanoq[0]})")
print("\n=== 3. Yangilash (invalidatsiya) ===")
kurs_yangila(1, "150")
print(f" kesh o'chdi, keshda bormi: {r.exists('kurs:1')}")
print("\n=== 4. Qayta o'qish (miss → yangi qiymat) ===")
print(f" {kurs_ol(1)} (baza: {baza_sanoq[0]})")
print(" ⭐ kesh qatlami — hit/miss, invalidatsiya, hash (obyekt)")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Birinchi o'qish (miss → hash kesh) ===
{'nom': 'Python', 'narx': '100'} (baza: 1)
=== 2. Ikkinchi o'qish (hit) ===
{'nom': 'Python', 'narx': '100'} (baza: 1)
=== 3. Yangilash (invalidatsiya) ===
kesh o'chdi, keshda bormi: 0
=== 4. Qayta o'qish (miss → yangi qiymat) ===
{'nom': 'Python', 'narx': '150'} (baza: 2)
⭐ kesh qatlami — hit/miss, invalidatsiya, hash (obyekt)Nima ko'rsatdi: 2.1–2.8-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Kesh — asosiy manba" | Yordamchi (o'chsa bazadan) |
| "Redis doim to'g'ri" | Eskirishi mumkin (invalidatsiya) |
| "Hammani keshla" | Tez-tez, kam o'zgaradigan |
| "TTL keraksiz" | Eski ma'lumotni oldini oladi |
| "Redis faqat string" | Hash, list, set, sorted set |
| "Kesh o'zi yangilanadi" | Invalidatsiya qo'lda |
| "Redis = baza o'rnida" | Kesh (asosiy baza — PostgreSQL) |
| "incr xavfli (poyga)" | Atomik (xavfsiz) |
6. Keng tarqalgan xatolar va yechimlari
1. Kesh invalidatsiyasini unutish
bazada_yangila(id) # ⚠️ kesh eski qoladi
bazada_yangila(id); r.delete(f"kurs:{id}") # ✅2. TTL'siz keshlash
r.set("kesh:x", qiymat) # ⚠️ abadiy (eskiradi)
r.setex("kesh:x", 300, qiymat) # ✅3. Keshni majburiy (o'chsa ilova buziladi)
qiymat = r.get(kalit) # ⚠️ Redis o'chsa?
# try: kesh; except: bazadan # ✅ (kesh ixtiyoriy)4. Hammani keshlash
# har so'rovni keshla # ⚠️ xotira, murakkablik
# faqat tez-tez, kam o'zgaradiganni # ✅5. Katta obyektni string sifatida
r.set("user:1", katta_json) # ⚠️ har o'qishda to'liq
r.hset("user:1", mapping=...) # ✅ (maydon bo'yicha)6. Kalit nomi tartibsiz
r.set("kurs1") r.set("k_2") # ⚠️ tartibsiz
r.set("kurs:1") r.set("kurs:2") # ✅ (tur:id)7. Sessiyani faqat xotirada (ko'p server)
sessiyalar = {} # ⚠️ bir server (masshtab yo'q)
r.setex(f"sessiya:{id}", 3600, ...) # ✅ (umumiy Redis)7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 23.9-dars (o'tilgan): N+1 — kesh so'rovni kamaytiradi
- 23.5-dars (o'tilgan): PostgreSQL — asosiy baza (kesh ustida)
- 20.10-dars (o'tilgan): Fon vazifalari — kesh yangilash
- 20.7-dars (o'tilgan): Auth — sessiya Redis'da
- 31-qism: Deploy — Redis konteyner
8. Eng yaxshi amaliyotlar
Faqat tez-tez, kam o'zgaradigan ma'lumot keshla.
Har keshda TTL (avtomatik eskirish).
O'zgarishda invalidatsiya (
delete).Kesh ixtiyoriy (o'chsa bazadan).
Kalit nomi tizimli (
tur:id).Obyekt uchun hash (string emas).
Sessiya/hisoblagich Redis'da (masshtab).
Hit nisbatini kuzat (kesh samarasi).
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # Kesh nima?
2. # Redis nima?
3. # set/get nima?
4. # incr nima (atomik)?
5. # TTL nima?
6. # setex nima?
7. # kesh-aside nima?
8. # kesh hit/miss nima?
9. # invalidatsiya nima?
10. # hash nima?
11. # kesh ixtiyoriymi?
12. # nima keshlash kerak?Javoblar
- Tez-tez kerak ma'lumotni tez xotirada saqlash
- Xotira kalit-qiymat baza (kesh)
- Yoz / o'qi
- Atomik +1 (hisoblagich)
- Kalit avtomatik o'chish muddati
- TTL bilan yoz
- Tekshir → hit yoki miss (baza + keshga)
- Hit — keshda bor, miss — yo'q
- O'zgarsa keshni o'chir/yangila
- Obyekt (maydon bilan)
- Ha (o'chsa bazadan)
- Tez-tez, kam o'zgaradigan
Vazifa 2: Xatolarni tuzating
1. bazada_yangila(id) # invalidatsiya
2. r.set("kesh:x", qiymat) # setex (TTL)
3. qiymat = r.get(kalit) # kesh ixtiyoriy
4. r.set("kurs1") # kurs:1
5. sessiyalar = {} # RedisJavoblar
1. bazada_yangila(id); r.delete(f"kurs:{id}")
2. r.setex("kesh:x", 300, qiymat)
3. # try: kesh; except: bazadan
4. r.set("kurs:1", ...)
5. r.setex(f"sessiya:{id}", 3600, ...)Vazifa 3: Kesh-aside
To'liq namuna:
- Soxta baza (sanoq)
get→ hit/miss- Miss → baza +
setex - So'rov sonini ko'r
Vazifa 4: TTL
Muddat:
setex(TTL bilan)expire(mavjudga)ttl(qolgan)persist
Vazifa 5: Invalidatsiya
O'zgarish:
- Kesh + baza
- Bazani yangila
- Keshni o'chir
- Qayta o'qi (yangi)
Vazifa 6: Tuzilmalar
Redis tuzilma:
- Hash (obyekt)
- List (navbat)
- Incr (hisoblagich)
- Har birini sina
Vazifa 7: O'ylash
Kesh tez-tez so'ralgan ma'lumotni tez xotirada saqlaydi — bazaga murojaatni kamaytiradi (tez). Lekin kesh eskirishi mumkin (ma'lumot bazada o'zgarsa, kesh eski) — bu "kesh invalidatsiya" muammosi. "Tezlik vs to'g'rilik (freshness)" tanlovi — kesh tezlik beradi, lekin to'g'rilikni (eng yangi ma'lumot) qurbon qilishi mumkin. Nima uchun "kesh invalidatsiya qiyin", va yaxshi muhandis bu tanlovni (TTL, invalidatsiya) qanday boshqaradi?
Javob
Qisqa javob: Kesh tezlik (xotiradan o'qish) va to'g'rilik (eng yangi ma'lumot) orasidagi tanlov. Kesh tez, lekin ma'lumot bazada o'zgarsa kesh eskiradi (stale). "Kesh invalidatsiya qiyin" (mashhur ibora), chunki: qachan o'chirish (har o'zgarishda? — ko'p joyda?), qaysini o'chirish (bog'langan kesh — kurs o'zgarsa, ro'yxat keshi ham?), poyga (o'zgarish va o'qish bir vaqtda). Yaxshi muhandis: TTL (avtomatik eskirish — eng ko'p N soniya eski), invalidatsiya (o'zgarishda o'chir — muhim ma'lumot uchun), tanlov (qancha eskilik qabul qilsa bo'ladi? — bank balansi yo'q, bosh sahifa — ha). "Barchaga mos yechim yo'q" — ma'lumotga qarab tanla.
1. Tezlik vs to'g'rilik
| Tezlik (kesh) | To'g'rilik (baza) |
|---|---|
| Xotiradan (~1ms) | Diskdan (~50ms) |
| Eski bo'lishi mumkin | Doim yangi |
| Yuk kam | Har so'rov baza |
2. Nega invalidatsiya qiyin
- Qachan: har o'zgarishda? (o'zgarish ko'p joyda)
- Qaysini: bog'langan kesh (kurs → ro'yxat keshi?)
- Poyga: o'zgarish va keshga yozish bir vaqtda (eski yozilib qolishi)
3. Yaxshi muhandis qanday boshqaradi
| Usul | Qachan |
|---|---|
| TTL | Ozroq eskilik qabul (bosh sahifa) |
| Invalidatsiya | Muhim (narx o'zgarishi) |
| Keshlamaslik | Kritik (bank balansi) |
4. Ma'lumotga qarab tanlov
- Kam o'zgaradi, eskilik zararsiz → kesh + uzun TTL
- Tez-tez o'zgaradi, muhim → kesh + invalidatsiya yoki keshlama
- Kritik (pul, xavfsizlik) → keshlama (doim baza)
5. Muhandislik saboqlari
- Kesh — tezlik/to'g'rilik tanlovi
- TTL — avtomatik eskirish (oddiy)
- Invalidatsiya — aniq, lekin qiyin
- Ma'lumotga qarab tanla (barchaga bir yechim yo'q)
6. Xulosa
- Kesh tezlik beradi, to'g'rilikni qurbon qilishi mumkin
- Invalidatsiya qiyin (qachan, qaysini, poyga)
- TTL — oddiy, invalidatsiya — aniq
- Ma'lumot muhimligiga qarab tanla
Nimani mustahkamlaydi: 2.1–2.8-bo'limlar.
Xulosa
Bu darsda Redis va keshni o'rgandik.
Eng muhim uch fikr:
Kesh — tez-tez kerak ma'lumotni tez xotirada. Kesh — tez-tez so'ralgan, kam o'zgaradigan ma'lumotni tez xotirada vaqtincha saqlash (bazaga murojaatni kamaytirish). Redis — xotirada (RAM) ishlaydigan kalit-qiymat baza: juda tez, TTL (avtomatik o'chirish), turli tuzilma (string, hash, list, set, sorted set). Asosiy amallar:
set/get(yoz/o'qi),incr(atomik hisoblagich),setex(TTL bilan),expire/ttl/persist. Kalit odatdatur:id(kurs:1).Kesh-aside va invalidatsiya. Kesh-aside (eng keng tarqalgan namuna): 1) keshni tekshir, 2) bor bo'lsa qaytar (hit — tez), 3) yo'q bo'lsa bazadan o'qi (miss), keshga yoz (TTL bilan). Birinchi so'rov sekin (miss), keyingilar tez (hit) — "hit nisbati" yuqori = yaxshi. Kesh invalidatsiya — ma'lumot o'zgarganda keshni o'chirish (
delete) yoki yangilash (aks holda eski qaytadi). Invalidatsiya qiyin (qachan, qaysini) — mashhur muammo.Kesh — yordamchi, asosiy manba emas. Kesh xavflari: eski ma'lumot (TTL + invalidatsiya), kesh o'chishi (ilova bazadan ishlash davom etsin — kesh ixtiyoriy), kesh bo'roni (ko'p miss — bazaga zarba), xotira chegarasi (LRU). Kesh tezlik vs to'g'rilik tanlovi — tez, lekin eskirishi mumkin. Ma'lumotga qarab tanla: kam o'zgaradi → uzun TTL; muhim → invalidatsiya; kritik (pul, xavfsizlik) → keshlama. Redis tuzilmalari (hash — obyekt, list — navbat, sorted set — reyting) uni kesh'dan kengroq qiladi.
Keyingi darsda NoSQL: MongoDB ni o'rganamiz: jadval-sxema o'rniga hujjat (JSON kabi) saqlash — moslashuvchan sxema, boshqacha ma'lumot modeli.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!