Redis چیست؟ آموزش کامل Cache، Queue، Session و Redis در Python

Redis یک دیتاستور سریع In-memory برای Cache، Session، Queue و پردازش رویداد است. در این آموزش، مفاهیم اصلی Redis و ساخت یک API خلاصه‌سازی مجهز به Cache با Python، FastAPI و درواره را یاد می‌گیرید.

Share
Redis چیست؟ آموزش کامل Cache، Queue، Session و Redis در Python

هنگامی که تعداد کاربران و درخواست‌های یک نرم‌افزار افزایش پیدا می‌کند، مراجعه مداوم به Database یا سرویس‌های بیرونی می‌تواند سرعت برنامه را کاهش دهد و هزینه زیرساخت را افزایش دهد.

فرض کنید یک API هوش مصنوعی ساخته‌اید که کاربران متن‌های مشابهی را برای خلاصه‌سازی ارسال می‌کنند. اگر برای هر درخواست تکراری دوباره مدل هوش مصنوعی فراخوانی شود، زمان پاسخ و هزینه مصرف API افزایش پیدا می‌کند.

یک راهکار این است که نتیجه درخواست قبلی را برای مدت مشخصی نگه داریم. اگر همان ورودی دوباره دریافت شد، پاسخ مستقیماً از Cache برگردانده شود.

Redis یکی از ابزارهای شناخته‌شده برای پیاده‌سازی چنین معماری‌هایی است. با این حال، کاربرد Redis فقط به Cache محدود نمی‌شود. از Redis می‌توان برای Session، Counter، Rate Limit، Queue، Pub/Sub، Streams، Leaderboard و ذخیره داده‌های موقت استفاده کرد.

در این مقاله یاد می‌گیرید:

  • Redis یا ردیس چیست
  • چرا Redis سرعت بالایی دارد
  • Redis چه تفاوتی با Database معمولی دارد
  • مهم‌ترین Data Typeهای Redis چه هستند
  • TTL و Expiration چگونه کار می‌کنند
  • الگوهای مختلف Cache کدام‌اند
  • Redis چگونه برای Session و Rate Limit استفاده می‌شود
  • تفاوت List، Pub/Sub و Redis Streams چیست
  • چگونه Redis را با Docker نصب کنیم
  • چگونه با Python و FastAPI به Redis متصل شویم
  • چگونه یک API هوش مصنوعی مجهز به Cache بسازیم
  • برای استفاده از Redis در Production چه نکاتی مهم‌اند

Redis چیست؟

Redis یک Data Store سریع است که بخش اصلی داده‌های فعال خود را در Memory نگه می‌دارد. Redis از ساختارهای داده مختلف، عملیات Atomic، Replication، Expiration و چند روش Persistence پشتیبانی می‌کند.

نام Redis در ابتدا از عبارت Remote Dictionary Server گرفته شده است.

در ساده‌ترین حالت، Redis اطلاعات را به شکل Key و Value نگه می‌دارد:

Key: user:42:name
Value: Amir

ذخیره یک مقدار:

SET user:42:name "Amir"

دریافت آن:

GET user:42:name

اما Redis فقط یک Key-Value Store ساده نیست. Value می‌تواند ساختارهای مختلفی داشته باشد:

  • String
  • Hash
  • List
  • Set
  • Sorted Set
  • Stream
  • Bitmap
  • HyperLogLog
  • Geospatial Index
  • JSON در پیاده‌سازی‌های پشتیبانی‌شده
  • ساختارهای پیشرفته‌تر متناسب با نسخه و قابلیت‌های نصب‌شده

Redis چگونه تلفظ می‌شود؟

در فارسی معمولاً Redis را «ردیس» می‌نویسند. هر دو شکل زیر در جست‌وجوها و متن‌های برنامه‌نویسی استفاده می‌شوند:

Redis
ردیس

در این مقاله بیشتر از شکل اصلی Redis استفاده می‌کنیم و در بخش‌های فارسی نیز اصطلاح «ردیس» را به‌طور طبیعی به کار می‌بریم.

چرا Redis سریع است؟

یکی از مهم‌ترین دلایل سرعت Redis این است که داده‌های فعال را در RAM نگه می‌دارد. دسترسی به Memory معمولاً بسیار سریع‌تر از خواندن مکرر اطلاعات از Disk است.

عوامل دیگری نیز در کارایی Redis نقش دارند:

  • ساختارهای داده بهینه
  • عملیات ساده و هدفمند
  • کاهش رفت‌وبرگشت شبکه با Pipeline
  • پشتیبانی از Connectionهای پایدار
  • اجرای Atomic بسیاری از Commandها
  • نبود سربار Queryهای پیچیده Relational
  • Serialization محدود در سطح Server

با این حال، Redis همیشه سریع‌ترین بخش سیستم نیست. Latency شبکه، اندازه Payload، عملکرد Client، تنظیمات Persistence و معماری Deployment نیز روی نتیجه اثر می‌گذارند.

آیا Redis یک Database است؟

Redis می‌تواند به‌عنوان Database، Cache، Message Broker، Streaming Engine یا Data Structure Store استفاده شود. اما معمولاً نباید آن را جایگزین مستقیم PostgreSQL، MySQL یا سایر Databaseهای اصلی در تمام پروژه‌ها دانست.

Redis برای این نوع داده‌ها مناسب است:

  • داده‌های موقت
  • Cache پاسخ‌ها
  • Session
  • Counter
  • Rate Limit
  • صف پردازش
  • وضعیت کوتاه‌مدت Job
  • داده‌های پرتکرار
  • Leaderboard
  • Event Stream

Database رابطه‌ای برای این نوع نیازها مناسب‌تر است:

  • داده‌های دائمی Business
  • روابط پیچیده
  • Queryهای تحلیلی
  • Constraintهای رابطه‌ای
  • گزارش‌گیری ساختاریافته
  • تراکنش‌های چندمرحله‌ای پیچیده
  • نگهداری بلندمدت داده اصلی

در بسیاری از معماری‌ها Redis در کنار Database اصلی استفاده می‌شود:

Client
   ↓
Application
   ↓
Redis Cache
   ↓ Cache Miss
PostgreSQL یا MySQL

در پروژه هوش مصنوعی:

Client
   ↓
Backend
   ↓
Redis Cache
   ↓ Cache Miss
API درواره
   ↓
مدل هوش مصنوعی

Redis چه کاربردهایی دارد؟

Cache

نتایج پرتکرار برای مدت محدود ذخیره می‌شوند:

خلاصه متن
نتیجه Query
اطلاعات محصول
تنظیمات عمومی
پاسخ یک API

Session

اطلاعات Session کاربر با TTL نگهداری می‌شود:

session:8f71c2

Rate Limiting

تعداد درخواست هر کاربر در یک بازه زمانی شمارش می‌شود:

rate:user_42:2026-08-06T10:30

Queue

Jobها در یک List یا Stream قرار می‌گیرند و Worker آن‌ها را پردازش می‌کند.

Pub/Sub

یک Publisher پیام را روی Channel منتشر می‌کند و Subscriberهای فعال آن را دریافت می‌کنند.

Counter

عملیات INCR شمارنده را به شکل Atomic افزایش می‌دهد:

INCR article:120:views

Leaderboard

Sorted Set برای رتبه‌بندی کاربران بر اساس Score مناسب است.

قفل کوتاه‌مدت

برای هماهنگی محدود میان چند Process می‌توان از الگوهای Lock استفاده کرد، اما پیاده‌سازی آن باید با دقت و متناسب با سطح اطمینان موردنیاز انجام شود.

ذخیره وضعیت Job

وضعیت پردازش‌های غیرهم‌زمان می‌تواند در Redis ذخیره شود:

job:981:status = processing

مهم‌ترین Data Typeهای Redis

انتخاب Data Type مناسب روی سادگی و عملکرد برنامه تأثیر مستقیم دارد.

String

String ساده‌ترین Data Type در Redis است. این نوع می‌تواند متن، عدد، JSON Serialize‌شده یا داده باینری را نگه دارد.

SET greeting "سلام"
GET greeting

ذخیره با Expiration:

SET cache:article:101 "cached-content" EX 300

این Key پس از ۳۰۰ ثانیه منقضی می‌شود.

افزایش Counter:

INCR api:request:count

کاربردها:

  • Cache
  • Token موقت
  • Counter
  • Feature Flag
  • JSON Serialize‌شده
  • وضعیت ساده Job

Hash

Hash مجموعه‌ای از Field و Value را زیر یک Key نگه می‌دارد.

HSET user:42 name "Amir" plan "pro" status "active"

دریافت یک Field:

HGET user:42 name

دریافت تمام Fieldها:

HGETALL user:42

کاربردها:

  • پروفایل کاربر
  • تنظیمات
  • Metadata
  • وضعیت Job
  • Objectهای کوچک

نمونه:

user:42
  name   → Amir
  plan   → pro
  status → active

List

List مجموعه‌ای مرتب از Stringهاست و عملیات درج و حذف از ابتدا یا انتهای فهرست را ارائه می‌دهد.

افزودن Job:

LPUSH jobs:summary "job_101"

دریافت Job توسط Worker:

BRPOP jobs:summary 0

کاربردها:

  • Queue ساده
  • Stack
  • فهرست آخرین Eventها
  • پردازش Producer و Consumer

برای Queueهایی که به Consumer Group، ثبت تحویل یا بازیابی پیام پردازش‌نشده نیاز دارند، Redis Streams معمولاً قابلیت‌های کامل‌تری ارائه می‌کند.

Set

Set مجموعه‌ای بدون ترتیب از اعضای یکتا است.

SADD article:101:tags "redis" "python" "api"

بررسی عضویت:

SISMEMBER article:101:tags "redis"

کاربردها:

  • اعضای یکتا
  • Tag
  • Permission
  • کاربران Online
  • حذف Duplicate
  • اشتراک و اجتماع مجموعه‌ها

Sorted Set

Sorted Set اعضای یکتا را همراه Score نگه می‌دارد.

ZADD leaderboard 1500 "user_42"
ZADD leaderboard 2100 "user_81"

دریافت رتبه‌بندی نزولی:

ZREVRANGE leaderboard 0 9 WITHSCORES

کاربردها:

  • Leaderboard
  • رتبه‌بندی
  • صف اولویت‌دار
  • زمان‌بندی
  • داده مرتب بر اساس Timestamp یا Score

Stream

Redis Stream یک ساختار Append-only برای نگهداری Eventهاست.

افزودن Event:

XADD events:orders * type "order.created" order_id "ord_101"

خواندن Eventها:

XREAD COUNT 10 STREAMS events:orders 0

Streams از قابلیت‌هایی مانند موارد زیر پشتیبانی می‌کند:

  • Consumer Group
  • Pending Entries
  • Acknowledgement
  • بازخوانی پیام
  • چند Consumer
  • نگهداری Eventها
  • شناسه ترتیبی

کاربردها:

  • Event Processing
  • Queue پایدارتر
  • اتصال Producer و Worker
  • پردازش Telemetry
  • Workflowهای غیرهم‌زمان

TTL چیست؟

TTL مخفف Time To Live است و نشان می‌دهد یک Key چه مدت دیگر در Redis باقی می‌ماند.

تنظیم Expiration:

SET verification:email:user_42 "739201" EX 120

این Key پس از ۱۲۰ ثانیه حذف می‌شود.

مشاهده TTL:

TTL verification:email:user_42

خروجی ممکن است چنین باشد:

85

یعنی ۸۵ ثانیه تا حذف Key باقی مانده است.

خروجی‌های خاص:

-1

یعنی Key وجود دارد اما Expiration ندارد.

-2

یعنی Key وجود ندارد.

تنظیم TTL جداگانه:

EXPIRE session:abc123 3600

حذف Expiration:

PERSIST session:abc123

چرا TTL مهم است؟

بدون TTL، Cacheهای قدیمی ممکن است برای همیشه باقی بمانند و Memory را اشغال کنند.

TTL برای این موارد مهم است:

  • Cache
  • Session
  • کد تأیید
  • Token موقت
  • Rate Limit
  • Lock
  • نتیجه موقت Job
  • Deduplication کوتاه‌مدت

TTL باید بر اساس ماهیت داده انتخاب شود. یک مقدار ثابت برای تمام Cacheها معمولاً مناسب نیست.

انتخاب TTL مناسب

TTL بسیار کوتاه باعث Cache Miss زیاد می‌شود. TTL بسیار بلند ممکن است داده قدیمی به کاربر نشان دهد.

نوع دادهTTL نمونه
تنظیمات نسبتاً ثابتچند دقیقه تا چند ساعت
نتیجه Query پرتکرارچند ثانیه تا چند دقیقه
Sessionمتناسب با سیاست Session
OTPمعمولاً چند دقیقه
Rate Limitبرابر پنجره محدودیت
پاسخ هوش مصنوعی تکراریمتناسب با کاربرد و احتمال تغییر
قیمت یا موجودیکوتاه و همراه Invalidation

این مقادیر نسخه عمومی و قطعی نیستند. TTL باید بر اساس نرخ تغییر داده، هزینه تولید مجدد و میزان تحمل Stale Data تعیین شود.

Cache چیست؟

Cache یک لایه ذخیره‌سازی سریع برای داده‌هایی است که تولید یا دریافت مجدد آن‌ها هزینه دارد.

مثلاً خلاصه‌سازی یک متن با مدل هوش مصنوعی ممکن است چند ثانیه زمان و مقداری هزینه مصرف داشته باشد. اگر ورودی، مدل و تنظیمات دقیقاً یکسان باشند، می‌توان نتیجه قبلی را برای مدتی از Redis برگرداند.

چرخه Cache:

Request
   ↓
ساخت Cache Key
   ↓
بررسی Redis
   ↓
Cache Hit؟ بله → بازگرداندن پاسخ
   ↓ خیر
فراخوانی سرویس اصلی
   ↓
ذخیره نتیجه در Redis
   ↓
بازگرداندن پاسخ

Cache Hit و Cache Miss

Cache Hit

داده موردنظر در Cache پیدا می‌شود:

Redis → Response

Cache Miss

داده در Cache نیست و باید از منبع اصلی تولید یا دریافت شود:

Redis Miss → Database یا API → Redis → Response

نرخ Cache Hit یکی از Metricهای مهم سیستم است:

Cache Hit Rate = Cache Hits / Total Cache Lookups

برای مثال:

۸۰۰ Cache Hit از ۱۰۰۰ Lookup
Cache Hit Rate = 80%

برای سازگاری ساده با Ghost می‌توان فرمول را به همین صورت متنی نمایش داد.

مهم‌ترین الگوهای Cache

Cache-aside

رایج‌ترین الگو است:

  1. برنامه Redis را بررسی می‌کند.
  2. اگر داده موجود بود، آن را برمی‌گرداند.
  3. اگر موجود نبود، منبع اصلی را فراخوانی می‌کند.
  4. نتیجه را در Redis ذخیره می‌کند.

مزایا:

  • ساده و قابل‌کنترل
  • فقط داده‌های واقعاً مصرف‌شده Cache می‌شوند
  • وابستگی محدود به Redis

معایب:

  • Request اول کندتر است
  • احتمال Stale Data وجود دارد
  • Cache Invalidation باید مدیریت شود

Write-through

داده هنگام نوشتن هم‌زمان در Database و Cache ثبت می‌شود.

مزیت:

  • Cache معمولاً به‌روز است

محدودیت:

  • عملیات Write پیچیده‌تر و کندتر می‌شود
  • مدیریت شکست یکی از دو ذخیره‌سازی اهمیت پیدا می‌کند

Write-behind

ابتدا داده در Cache نوشته می‌شود و بعداً به Database منتقل می‌شود.

این روش می‌تواند سرعت Write را افزایش دهد، اما ریسک از دست رفتن داده و پیچیدگی هماهنگی بیشتری دارد. برای داده‌های مهم بدون طراحی دقیق مناسب نیست.

Refresh-ahead

پیش از منقضی شدن یک Key پرمصرف، سیستم آن را در پس‌زمینه Refresh می‌کند.

این روش برای داده‌هایی که باید سریع پاسخ داده شوند و تولیدشان زمان‌بر است مفید است.

Cache Key چگونه طراحی می‌شود؟

Cache Key باید:

  • یکتا باشد
  • قابل پیش‌بینی باشد
  • نسخه داشته باشد
  • تمام ورودی‌های مؤثر را در نظر بگیرد
  • بیش از حد طولانی نباشد
  • اطلاعات محرمانه را مستقیماً نمایش ندهد

نمونه:

ai:summary:v1:model_123:hash_of_input

برای متن‌های طولانی بهتر است از Hash استفاده شود:

import hashlib

digest = hashlib.sha256(text.encode("utf-8")).hexdigest()

cache_key = f"ai:summary:v1:{model_id}:{digest}"

اگر پارامتر max_sentences روی نتیجه اثر دارد، باید در Cache Key لحاظ شود:

cache_key = (
    f"ai:summary:v1:"
    f"{model_id}:"
    f"{max_sentences}:"
    f"{digest}"
)

در غیر این صورت، دو Request متفاوت ممکن است اشتباهاً یک پاسخ مشترک دریافت کنند.

Cache Invalidation

یکی از مهم‌ترین چالش‌های Cache حذف یا Refresh کردن داده قدیمی است.

روش‌ها:

Expiration

Key پس از TTL حذف می‌شود.

حذف هنگام Update

بعد از تغییر منبع اصلی، Cache مربوط حذف می‌شود:

DEL product:42

Versioned Key

نسخه قرارداد یا داده در Key قرار می‌گیرد:

product:v2:42

Event-based Invalidation

وقتی داده تغییر می‌کند، Event منتشر می‌شود و Cacheهای مرتبط حذف می‌شوند.

انتخاب روش به میزان تغییر داده و حساسیت Stale Data بستگی دارد.

Cache Stampede چیست؟

فرض کنید یک Key پرترافیک منقضی شود و هم‌زمان ۱۰۰ Request آن را بخواهند. تمام Requestها Cache Miss می‌گیرند و به Database یا API اصلی می‌روند.

این وضعیت Cache Stampede یا Thundering Herd نامیده می‌شود.

راهکارها:

  • Lock کوتاه‌مدت برای تولیدکننده اول
  • نگهداری Stale Data برای مدت محدود
  • Refresh-ahead
  • TTL Jitter
  • Single-flight در سطح برنامه
  • محدود کردن Concurrency
  • Queue کردن محاسبات سنگین

TTL Jitter یعنی به TTL مقدار کمی تصادفی اضافه شود تا تعداد زیادی Key هم‌زمان منقضی نشوند:

TTL پایه: ۳۶۰۰ ثانیه
Jitter: بین صفر تا ۳۰۰ ثانیه
TTL نهایی: بین ۳۶۰۰ تا ۳۹۰۰ ثانیه

تفاوت Redis List، Pub/Sub و Streams

این سه قابلیت گاهی با یکدیگر اشتباه گرفته می‌شوند.

قابلیتListPub/SubStreams
نگهداری پیامبلهمعمولاً خیربله
Consumer Groupمحدودخیربله
Acknowledgementبه‌صورت داخلی کامل نیستخیربله
دریافت توسط چند Subscriberنیازمند طراحیبلهبله
بازیابی پیام ازدست‌رفتهمحدودخیربله
مناسب Queue سادهبلهخیربله
مناسب اعلان زندهمحدودبلهبله
پیچیدگیکمکمبیشتر

List

برای Queue ساده با Producer و Worker مناسب است.

Pub/Sub

برای پیام‌های زنده‌ای مناسب است که فقط Subscriberهای فعال باید آن‌ها را دریافت کنند. اگر Subscriber هنگام انتشار متصل نباشد، پیام را دریافت نمی‌کند.

Streams

برای Eventهایی مناسب است که باید نگهداری شوند و Consumer بتواند آن‌ها را پردازش و Acknowledge کند.

Redis Pub/Sub چیست؟

Publisher پیام را روی یک Channel منتشر می‌کند:

PUBLISH notifications "new_message"

Subscriber به Channel گوش می‌دهد:

SUBSCRIBE notifications

Pub/Sub برای این موارد مناسب است:

  • اعلان زنده
  • Refresh تنظیمات
  • اطلاع‌رسانی داخلی
  • انتشار Eventهای غیرحساس و قابل‌چشم‌پوشی

Pub/Sub برای Jobهایی که نباید از دست بروند مناسب نیست؛ زیرا پیام‌های معمول Pub/Sub برای Subscriber غیرفعال ذخیره نمی‌شوند.

Redis Streams چیست؟

Streams یک Log افزایشی از Eventها ایجاد می‌کند.

افزودن پیام:

XADD ai:jobs * job_id "job_101" status "queued"

ایجاد Consumer Group:

XGROUP CREATE ai:jobs workers 0 MKSTREAM

خواندن پیام با Consumer:

XREADGROUP GROUP workers worker_1 COUNT 10 BLOCK 5000 STREAMS ai:jobs >

تأیید پردازش:

XACK ai:jobs workers MESSAGE_ID

اگر Worker بعد از دریافت پیام متوقف شود، Event می‌تواند در Pending Entries باقی بماند و با سیاست مناسب بازیابی شود.

Session با Redis

اطلاعات Session می‌تواند در Hash ذخیره شود:

HSET session:abc123 user_id "42" plan "pro"
EXPIRE session:abc123 3600

در Request بعدی، Backend Session ID را دریافت و اطلاعات را از Redis می‌خواند:

HGETALL session:abc123

بهتر است Session ID:

  • تصادفی و غیرقابل حدس باشد
  • TTL مشخص داشته باشد
  • بعد از خروج حذف شود
  • در Log عمومی ثبت نشود
  • اطلاعات ضروری و محدود نگه دارد

ساخت Rate Limit ساده با Redis

یکی از ساده‌ترین الگوریتم‌ها Fixed Window است.

برای هر کاربر و هر دقیقه یک Key می‌سازیم:

rate:user_42:202608061030

افزایش شمارنده:

INCR rate:user_42:202608061030

اگر اولین Request است، Expiration تنظیم می‌شود:

EXPIRE rate:user_42:202608061030 60

نمونه Python:

from datetime import datetime, timezone

async def check_rate_limit(redis_client, user_id: str):
    current_minute = datetime.now(
        timezone.utc
    ).strftime("%Y%m%d%H%M")

    key = f"rate:{user_id}:{current_minute}"

    async with redis_client.pipeline(
        transaction=True
    ) as pipe:
        pipe.incr(key)
        pipe.expire(key, 60)
        count, _ = await pipe.execute()

    return count <= 60

این مثال برای آموزش مناسب است. در Production باید الگوریتم، محدودیت Burst، رفتار چند Region و Atomic بودن عملیات متناسب با نیاز پروژه بررسی شود.

Pipeline در Redis

اگر چند Command جداگانه ارسال کنید، برای هرکدام یک رفت‌وبرگشت شبکه انجام می‌شود.

بدون Pipeline:

Client → SET → Redis
Client ← OK  ← Redis

Client → EXPIRE → Redis
Client ← 1      ← Redis

با Pipeline چند Command در یک Batch ارسال می‌شوند:

async with redis_client.pipeline() as pipe:
    pipe.set("key:1", "value:1")
    pipe.set("key:2", "value:2")
    pipe.expire("key:1", 300)
    results = await pipe.execute()

Pipeline می‌تواند تعداد Round Tripها را کاهش دهد، اما به معنی Transaction بودن تمام عملیات در تمام تنظیمات Client نیست. رفتار Client و گزینه transaction را بررسی کنید.

Transaction در Redis

Transactionهای Redis حول Commandهای زیر ساخته می‌شوند:

MULTI
EXEC
DISCARD
WATCH

نمونه CLI:

MULTI
INCR wallet:user_42
EXPIRE wallet:user_42 3600
EXEC

Redis Transaction با Transactionهای Database رابطه‌ای دقیقاً یکسان نیست. برای مثال، مدل Rollback و مدیریت خطاها تفاوت‌هایی دارد.

از WATCH می‌توان برای Optimistic Locking استفاده کرد؛ یعنی اگر Key پیش از اجرای Transaction تغییر کرده باشد، عملیات لغو و دوباره ارزیابی شود.

Persistence در Redis

با اینکه Redis داده‌های فعال را در Memory نگه می‌دارد، می‌تواند داده‌ها را روی Disk نیز ثبت کند.

روش‌های اصلی:

RDB

Snapshotهایی از Dataset در فاصله‌های زمانی مشخص ساخته می‌شوند.

مزایا:

  • فایل فشرده
  • مناسب Backup
  • Restart معمولاً سریع
  • سربار کمتر در برخی Workloadها

محدودیت:

  • ممکن است تغییرات بعد از آخرین Snapshot از دست بروند

AOF

Commandهای Write در Append Only File ثبت می‌شوند.

مزایا:

  • امکان کاهش فاصله از دست رفتن داده
  • بازسازی Dataset از Log عملیات

محدودیت:

  • فایل بزرگ‌تر
  • سربار Write بیشتر
  • نیاز به Rewrite دوره‌ای

ترکیب RDB و AOF

بسته به اهمیت داده می‌توان از ترکیب قابلیت‌ها استفاده کرد.

اگر Redis فقط Cache است، از دست رفتن داده معمولاً با تولید دوباره قابل جبران است. اگر Redis نقش Queue یا Data Store اصلی دارد، سیاست Persistence و Recovery اهمیت بیشتری پیدا می‌کند.

Eviction Policy چیست؟

وقتی Memory به maxmemory برسد، Redis بر اساس Eviction Policy تصمیم می‌گیرد چه کاری انجام دهد.

نمونه Policyها:

  • noeviction
  • allkeys-lru
  • allkeys-lfu
  • allkeys-random
  • volatile-lru
  • volatile-lfu
  • volatile-ttl

انتخاب Policy به کاربرد بستگی دارد.

برای Cache عمومی، Policyهایی مانند LRU یا LFU می‌توانند مناسب باشند. برای داده‌ای که نباید خودکار حذف شود، رفتار متفاوتی لازم است.

Redis را بدون محدودیت Memory رها نکنید. رشد کنترل‌نشده داده می‌تواند عملکرد سیستم را تحت تأثیر قرار دهد.

نصب Redis با Docker

برای محیط توسعه می‌توانید Redis را با Docker اجرا کنید.

فایل docker-compose.yml:

services:
  redis:
    image: redis:8-alpine
    container_name: redis-local
    restart: unless-stopped
    command:
      - redis-server
      - --appendonly
      - "yes"
      - --maxmemory
      - 512mb
      - --maxmemory-policy
      - allkeys-lru
    ports:
      - "127.0.0.1:6379:6379"
    volumes:
      - redis_data:/data

volumes:
  redis_data:

اجرا:

docker compose up -d

بررسی وضعیت:

docker compose ps

آزمایش اتصال:

docker compose exec redis redis-cli PING

پاسخ:

PONG

این تنظیم برای محیط توسعه Local است. در Production نباید Port Redis بدون کنترل در شبکه عمومی منتشر شود. نسخه Image را نیز پیش از Deployment بر اساس نسخه Stable مورد استفاده پروژه انتخاب و ثابت کنید.

اتصال Python به Redis

کتابخانه رسمی رایج Python برای Redis، پکیج redis است.

نصب:

pip install redis

نمونه هم‌زمان:

import redis

client = redis.Redis(
    host="localhost",
    port=6379,
    decode_responses=True,
)

client.set(
    "greeting",
    "سلام از Redis",
    ex=300,
)

value = client.get("greeting")

print(value)

نمونه Async:

import asyncio
import redis.asyncio as redis


async def main():
    client = redis.from_url(
        "redis://localhost:6379/0",
        decode_responses=True,
    )

    await client.set(
        "greeting",
        "سلام از Redis Async",
        ex=300,
    )

    value = await client.get("greeting")

    print(value)

    await client.aclose()


asyncio.run(main())

پروژه عملی: Cache پاسخ API هوش مصنوعی با Redis

در این پروژه یک API خلاصه‌سازی با FastAPI می‌سازیم.

فرایند:

  1. کاربر متن را ارسال می‌کند.
  2. Backend از ورودی و تنظیمات یک Cache Key می‌سازد.
  3. Redis بررسی می‌شود.
  4. اگر پاسخ موجود باشد، همان نتیجه برگردانده می‌شود.
  5. اگر پاسخ موجود نباشد، API درواره فراخوانی می‌شود.
  6. نتیجه با TTL در Redis ذخیره می‌شود.
  7. پاسخ به کاربر برگردانده می‌شود.

ساختار پروژه:

redis-ai-cache/
├── app.py
├── requirements.txt
├── docker-compose.yml
└── .env

نصب وابستگی‌های پروژه

فایل requirements.txt:

fastapi
uvicorn[standard]
httpx
redis
python-dotenv

نصب:

pip install -r requirements.txt

تنظیم Environment Variableها

فایل .env:

REDIS_URL=redis://localhost:6379/0
DARVAREH_API_KEY=YOUR_DARVAREH_API_KEY
DARVAREH_MODEL_ID=YOUR_MODEL_ID
CACHE_TTL_SECONDS=3600

فایل .gitignore:

.env
.venv/
__pycache__/

کد کامل FastAPI

فایل app.py:

import hashlib
import json
import os
import random
from contextlib import asynccontextmanager

import httpx
import redis.asyncio as redis
from dotenv import load_dotenv
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from redis.exceptions import RedisError

load_dotenv()

REDIS_URL = os.getenv(
    "REDIS_URL",
    "redis://localhost:6379/0",
)
DARVAREH_API_KEY = os.getenv("DARVAREH_API_KEY")
DARVAREH_MODEL_ID = os.getenv("DARVAREH_MODEL_ID")
CACHE_TTL_SECONDS = int(
    os.getenv("CACHE_TTL_SECONDS", "3600")
)

DARVAREH_URL = (
    "https://api.darvareh.ir/v1/chat/completions"
)

if not DARVAREH_API_KEY:
    raise RuntimeError(
        "متغیر DARVAREH_API_KEY تنظیم نشده است."
    )

if not DARVAREH_MODEL_ID:
    raise RuntimeError(
        "متغیر DARVAREH_MODEL_ID تنظیم نشده است."
    )


class SummaryRequest(BaseModel):
    text: str = Field(
        min_length=20,
        max_length=20_000,
    )
    max_sentences: int = Field(
        default=3,
        ge=1,
        le=10,
    )


class SummaryResponse(BaseModel):
    summary: str
    model: str
    cached: bool


def create_cache_key(
    text: str,
    max_sentences: int,
) -> str:
    normalized_text = " ".join(
        text.strip().split()
    )

    cache_input = json.dumps(
        {
            "version": "v1",
            "model": DARVAREH_MODEL_ID,
            "text": normalized_text,
            "max_sentences": max_sentences,
        },
        ensure_ascii=False,
        sort_keys=True,
        separators=(",", ":"),
    )

    digest = hashlib.sha256(
        cache_input.encode("utf-8")
    ).hexdigest()

    return f"ai:summary:v1:{digest}"


@asynccontextmanager
async def lifespan(app: FastAPI):
    redis_client = redis.from_url(
        REDIS_URL,
        decode_responses=True,
        socket_connect_timeout=3,
        socket_timeout=3,
        health_check_interval=30,
    )

    app.state.redis = redis_client

    try:
        await redis_client.ping()
        print("Connected to Redis")
    except RedisError:
        print(
            "Redis is unavailable; "
            "the API will continue without cache."
        )

    yield

    await redis_client.aclose()


app = FastAPI(
    title="AI Summary API with Redis Cache",
    version="1.0.0",
    lifespan=lifespan,
)


@app.get("/health")
async def health_check():
    redis_status = "unavailable"

    try:
        await app.state.redis.ping()
        redis_status = "ok"
    except RedisError:
        pass

    return {
        "status": "ok",
        "redis": redis_status,
    }


@app.post(
    "/v1/summaries",
    response_model=SummaryResponse,
)
async def create_summary(
    payload: SummaryRequest,
):
    cache_key = create_cache_key(
        payload.text,
        payload.max_sentences,
    )

    try:
        cached_value = await app.state.redis.get(
            cache_key
        )
    except RedisError:
        cached_value = None

    if cached_value:
        try:
            cached_data = json.loads(cached_value)

            return SummaryResponse(
                summary=cached_data["summary"],
                model=cached_data["model"],
                cached=True,
            )
        except (
            json.JSONDecodeError,
            KeyError,
            TypeError,
        ):
            try:
                await app.state.redis.delete(
                    cache_key
                )
            except RedisError:
                pass

    request_body = {
        "model": DARVAREH_MODEL_ID,
        "messages": [
            {
                "role": "system",
                "content": (
                    "تو یک ویراستار فارسی هستی. "
                    "متن را دقیق و بدون اضافه کردن "
                    "اطلاعات جدید خلاصه کن."
                ),
            },
            {
                "role": "user",
                "content": (
                    f"متن زیر را حداکثر در "
                    f"{payload.max_sentences} جمله "
                    f"خلاصه کن:\n\n{payload.text}"
                ),
            },
        ],
    }

    headers = {
        "Authorization": (
            f"Bearer {DARVAREH_API_KEY}"
        ),
        "Content-Type": "application/json",
    }

    timeout = httpx.Timeout(
        connect=10.0,
        read=60.0,
        write=20.0,
        pool=10.0,
    )

    try:
        async with httpx.AsyncClient(
            timeout=timeout
        ) as http_client:
            response = await http_client.post(
                DARVAREH_URL,
                headers=headers,
                json=request_body,
            )

        if response.status_code == 429:
            raise HTTPException(
                status_code=503,
                detail={
                    "code": "UPSTREAM_RATE_LIMIT",
                    "message": (
                        "سرویس هوش مصنوعی موقتاً "
                        "با محدودیت درخواست مواجه است."
                    ),
                },
            )

        if response.status_code >= 500:
            raise HTTPException(
                status_code=502,
                detail={
                    "code": "UPSTREAM_ERROR",
                    "message": (
                        "سرویس هوش مصنوعی پاسخ "
                        "معتبری برنگرداند."
                    ),
                },
            )

        if response.status_code >= 400:
            raise HTTPException(
                status_code=502,
                detail={
                    "code": "UPSTREAM_REJECTED",
                    "message": (
                        "درخواست توسط سرویس "
                        "بالادستی پذیرفته نشد."
                    ),
                },
            )

        result = response.json()
        summary = (
            result["choices"][0]["message"]["content"]
            .strip()
        )

    except httpx.TimeoutException as exc:
        raise HTTPException(
            status_code=504,
            detail={
                "code": "UPSTREAM_TIMEOUT",
                "message": (
                    "سرویس هوش مصنوعی در زمان "
                    "تعیین‌شده پاسخ نداد."
                ),
            },
        ) from exc
    except httpx.RequestError as exc:
        raise HTTPException(
            status_code=502,
            detail={
                "code": "UPSTREAM_CONNECTION_ERROR",
                "message": (
                    "ارتباط با سرویس "
                    "هوش مصنوعی برقرار نشد."
                ),
            },
        ) from exc
    except (
        ValueError,
        KeyError,
        IndexError,
        TypeError,
    ) as exc:
        raise HTTPException(
            status_code=502,
            detail={
                "code": "INVALID_UPSTREAM_RESPONSE",
                "message": (
                    "ساختار پاسخ سرویس "
                    "هوش مصنوعی معتبر نبود."
                ),
            },
        ) from exc

    if not summary:
        raise HTTPException(
            status_code=502,
            detail={
                "code": "EMPTY_UPSTREAM_RESPONSE",
                "message": (
                    "سرویس هوش مصنوعی "
                    "پاسخ خالی برگرداند."
                ),
            },
        )

    cache_value = json.dumps(
        {
            "summary": summary,
            "model": DARVAREH_MODEL_ID,
        },
        ensure_ascii=False,
    )

    ttl_with_jitter = (
        CACHE_TTL_SECONDS
        + random.randint(0, 300)
    )

    try:
        await app.state.redis.set(
            cache_key,
            cache_value,
            ex=ttl_with_jitter,
        )
    except RedisError:
        pass

    return SummaryResponse(
        summary=summary,
        model=DARVAREH_MODEL_ID,
        cached=False,
    )

اجرای پروژه

ابتدا Redis را اجرا کنید:

docker compose up -d

سپس FastAPI را اجرا کنید:

uvicorn app:app --reload

آدرس سرویس:

http://127.0.0.1:8000

مستندات تعاملی:

http://127.0.0.1:8000/docs

آزمایش Health Check

curl http://127.0.0.1:8000/health

پاسخ:

{
  "status": "ok",
  "redis": "ok"
}

ارسال درخواست خلاصه‌سازی

curl --request POST \
  --url http://127.0.0.1:8000/v1/summaries \
  --header "Content-Type: application/json" \
  --data '{
    "text": "Redis یک Data Store سریع مبتنی بر Memory است که برای Cache، Session، Queue، Counter و پردازش Event استفاده می‌شود. پشتیبانی از Data Typeهای مختلف و TTL باعث شده است Redis در معماری بسیاری از Backendها نقش مهمی داشته باشد.",
    "max_sentences": 2
  }'

پاسخ درخواست اول:

{
  "summary": "Redis یک Data Store سریع مبتنی بر Memory است که برای Cache، Session، Queue و پردازش Event کاربرد دارد. Data Typeهای متنوع و قابلیت TTL آن را به ابزار مهمی در معماری Backend تبدیل کرده‌اند.",
  "model": "YOUR_MODEL_ID",
  "cached": false
}

اگر همان Request را دوباره ارسال کنید:

{
  "summary": "Redis یک Data Store سریع مبتنی بر Memory است که برای Cache، Session، Queue و پردازش Event کاربرد دارد. Data Typeهای متنوع و قابلیت TTL آن را به ابزار مهمی در معماری Backend تبدیل کرده‌اند.",
  "model": "YOUR_MODEL_ID",
  "cached": true
}

در Request دوم، Backend پاسخ را از Redis دریافت کرده و مدل دوباره فراخوانی نشده است.

چرا Cache Key شامل Model ID است؟

دو مدل مختلف ممکن است برای یک متن پاسخ متفاوتی تولید کنند. اگر Model ID در Cache Key قرار نگیرد، پاسخ یک مدل ممکن است برای درخواست مدل دیگری بازگردانده شود.

همچنین این عوامل باید در Cache Key لحاظ شوند:

  • متن نرمال‌شده
  • Model ID
  • نوع عملیات
  • نسخه Prompt
  • پارامترهای مؤثر
  • زبان خروجی
  • طول خروجی
  • Tenant یا User در صورت شخصی بودن پاسخ

آیا پاسخ هوش مصنوعی همیشه باید Cache شود؟

خیر. Cache برای تمام Requestها مناسب نیست.

مناسب‌تر برای Cache:

  • خلاصه‌سازی متن ثابت
  • استخراج Keyword
  • دسته‌بندی محتوای ثابت
  • Embedding یک سند بدون تغییر
  • پاسخ‌های عمومی با ورودی یکسان
  • پردازش‌هایی که خروجی Deterministic یا قابل استفاده مجدد دارند

نامناسب‌تر برای Cache مشترک:

  • پاسخ شخصی‌سازی‌شده
  • اطلاعات حساس کاربر
  • داده بلادرنگ
  • وضعیت موجودی یا قیمت متغیر
  • چت وابسته به تاریخچه
  • Promptهایی با Context متفاوت
  • خروجی‌هایی که باید هر بار تازه باشند

برای داده شخصی، Cache Key و Scope باید طوری طراحی شوند که اطلاعات یک کاربر به کاربر دیگر نمایش داده نشود.

Redis در دسترس نباشد چه اتفاقی می‌افتد؟

در کد این مقاله از الگوی Fail-open برای Cache استفاده شده است:

  • اگر Redis در دسترس باشد، Cache استفاده می‌شود
  • اگر Redis در دسترس نباشد، درخواست مستقیماً به درواره ارسال می‌شود

این رفتار برای Cache مناسب است؛ زیرا Cache یک لایه بهینه‌سازی است و نباید الزاماً کل API را متوقف کند.

اما اگر Redis نقش Queue، Session یا منبع ضروری هماهنگی را داشته باشد، Fail-open ممکن است مناسب نباشد. رفتار سیستم باید بر اساس نقش Redis تعیین شود.

اتصال Redis به API درواره چه مزیتی دارد؟

استفاده درست از Redis در کنار API هوش مصنوعی می‌تواند:

  • Latency درخواست‌های تکراری را کاهش دهد
  • تعداد فراخوانی‌های تکراری مدل را کم کند
  • مصرف Token را کنترل کند
  • هزینه پردازش‌های تکراری را کاهش دهد
  • Rate Limit داخلی ایجاد کند
  • وضعیت Jobها را نگه دارد
  • پردازش‌های Async را مدیریت کند
  • پاسخ‌های پرتکرار را سریع‌تر ارائه دهد

Cache نباید برای پنهان کردن معماری نامناسب استفاده شود. ابتدا باید مشخص شود کدام درخواست‌ها واقعاً قابل استفاده مجدد هستند.

Base URL درواره:

https://api.darvareh.ir/v1

Endpoint مربوط به Chat Completions:

https://api.darvareh.ir/v1/chat/completions

برای مشاهده Model IDها و قیمت به‌روز مدل‌ها، صفحه مدل‌های درواره را بررسی کنید.

Redis Sentinel چیست؟

Redis Sentinel برای مانیتور کردن Instanceها، تشخیص Failure و هماهنگی Failover در معماری Primary و Replica استفاده می‌شود.

کاربردهای اصلی:

  • Monitoring
  • Failure Detection
  • Automatic Failover
  • اعلام آدرس Primary جدید به Clientها

Sentinel جایگزین Backup یا Cluster نیست و نیازهای Scalability و Availability باید جداگانه بررسی شوند.

Redis Cluster چیست؟

Redis Cluster امکان توزیع Keyها بین چند Node را فراهم می‌کند. Keyspace با Hash Slotها تقسیم می‌شود و هر Node بخشی از داده را نگه می‌دارد.

Cluster زمانی مفید است که:

  • Dataset از ظرفیت یک Node بزرگ‌تر است
  • Throughput بیشتری لازم است
  • Sharding خودکار نیاز دارید
  • Availability بالاتر می‌خواهید

Cluster پیچیدگی بیشتری دارد:

  • عملیات چند Key ممکن است محدود شود
  • Client باید Cluster-aware باشد
  • Failover و Rebalancing نیازمند مانیتورینگ است
  • طراحی Keyها و Hash Tagها اهمیت پیدا می‌کند

برای پروژه کوچک، شروع با یک Instance و برنامه‌ریزی برای رشد معمولاً ساده‌تر است.

Naming Convention برای Keyها

یک قرارداد نام‌گذاری یکپارچه، مدیریت Redis را ساده‌تر می‌کند.

نمونه:

app:environment:resource:id:field

مثال‌ها:

darvareh:prod:user:42:session
darvareh:prod:ai:summary:v1:HASH
darvareh:prod:rate:user_42:202608061030
darvareh:prod:job:981:status

اصول مناسب:

  • Prefix برنامه داشته باشید
  • Environment را جدا کنید
  • نوع Resource مشخص باشد
  • نسخه Schema را لحاظ کنید
  • از Keyهای بسیار طولانی پرهیز کنید
  • داده محرمانه را مستقیماً در Key ننویسید

چرا KEYS در Production مناسب نیست؟

Command زیر تمام Keyهای مطابق Pattern را جست‌وجو می‌کند:

KEYS ai:summary:*

روی Dataset بزرگ، این Command می‌تواند Redis را برای مدتی مشغول کند.

برای پیمایش تدریجی از SCAN استفاده کنید:

SCAN 0 MATCH ai:summary:* COUNT 100

SCAN نیز باید با دقت استفاده شود، اما برخلاف KEYS نتیجه را مرحله‌ای برمی‌گرداند.

برای حذف گروهی Cache بهتر است از Versioned Key، Tagging یا ساختار Invalidation هدفمند استفاده شود.

اشتباهات رایج در Redis

استفاده از Redis به‌عنوان جایگزین تمام Databaseها

Redis برای همه مدل‌های داده و Queryها مناسب نیست.

نداشتن TTL برای Cache

Cacheهای بدون Expiration می‌توانند Memory را پر کنند.

انتخاب Cache Key ناقص

اگر یکی از پارامترهای مؤثر در Key نباشد، پاسخ اشتباه برگردانده می‌شود.

Cache کردن خطا

پاسخ Timeout یا خطای موقت را مانند نتیجه موفق ذخیره نکنید؛ مگر با سیاست مشخص و TTL بسیار کوتاه.

Cache کردن اطلاعات شخصی به شکل مشترک

Scope کاربر یا Tenant باید در Key و دسترسی لحاظ شود.

فرض کردن Pub/Sub به‌عنوان Queue پایدار

Subscriber غیرفعال پیام معمول Pub/Sub را دریافت نمی‌کند.

نادیده گرفتن Duplicate در Queue

بعضی معماری‌ها ممکن است پیام را بیش از یک بار تحویل دهند. Worker باید Idempotent باشد.

استفاده زیاد از KEYS

برای Dataset بزرگ از پیمایش کنترل‌شده استفاده کنید.

ساخت Connection جدید در هر Request

از Connection Pool کتابخانه Redis استفاده کنید و Client را با Lifecycle برنامه مدیریت کنید.

ذخیره Object بدون نسخه Schema

اگر ساختار JSON تغییر کند، داده قدیمی ممکن است قابل Parse نباشد. نسخه را در Key یا Value ذخیره کنید.

نداشتن محدودیت Memory

maxmemory و Eviction Policy را متناسب با کاربرد تنظیم کنید.

فرض کردن Persistence به‌جای Backup

Persistence، Replication و Backup سه موضوع جدا هستند.

استفاده از Redis عمومی روی اینترنت

Redis باید در شبکه کنترل‌شده قرار گیرد و تنظیمات اتصال Production متناسب با زیرساخت انجام شود.

چک‌لیست Redis برای Production

پیش از انتشار این موارد را بررسی کنید:

  • نقش Redis دقیقاً مشخص شده است
  • Cache، Session و Queue از هم تفکیک شده‌اند
  • Key Naming Convention وجود دارد
  • Cache Key تمام ورودی‌های مؤثر را دارد
  • TTL برای داده‌های موقت تنظیم شده است
  • TTLها متناسب با نوع داده‌اند
  • TTL Jitter در Cacheهای پرتعداد بررسی شده است
  • Cache Stampede مدیریت می‌شود
  • خطاها Cache نمی‌شوند
  • اطلاعات کاربران Scope مناسب دارند
  • Redis Client از Connection Pool استفاده می‌کند
  • Timeout اتصال و Command مشخص است
  • رفتار هنگام قطع Redis تعریف شده است
  • Memory Limit تعیین شده است
  • Eviction Policy مناسب انتخاب شده است
  • Persistence متناسب با نقش Redis تنظیم شده است
  • Backup جداگانه در صورت نیاز وجود دارد
  • Queue Workerها Idempotent هستند
  • Pub/Sub برای داده ضروری استفاده نشده است
  • Streamهای قدیمی Trim می‌شوند
  • Pending Messageها مانیتور می‌شوند
  • Commandهای سنگین کنترل شده‌اند
  • Metricهای Memory و Latency ثبت می‌شوند
  • Hit Rate و Miss Rate بررسی می‌شوند
  • Connection Count مانیتور می‌شود
  • Replication Lag در معماری Replica بررسی می‌شود
  • سناریوی Recovery آزمایش شده است
  • نسخه Redis و Client ثابت و کنترل‌شده است
  • API Key در Cache یا Log عمومی ذخیره نمی‌شود

پرسش‌های متداول

Redis چیست؟

Redis یک Data Store سریع مبتنی بر Memory است که برای Cache، Session، Queue، Counter، Pub/Sub، Streams و کاربردهای دیگر استفاده می‌شود.

تفاوت Redis و MySQL چیست؟

MySQL یک Database رابطه‌ای برای داده‌های ساختاریافته، Query و رابطه میان جدول‌هاست. Redis یک Data Structure Store سریع است که بیشتر برای داده‌های موقت، پرتکرار و عملیات کم‌تأخیر استفاده می‌شود. آن‌ها معمولاً مکمل یکدیگرند.

آیا Redis فقط Cache است؟

خیر. Redis می‌تواند برای Session، Queue، Pub/Sub، Streams، Counter، Leaderboard و حتی برخی کاربردهای Database استفاده شود.

آیا Redis داده‌ها را فقط در RAM نگه می‌دارد؟

داده فعال Redis در Memory نگهداری می‌شود، اما Redis از روش‌های Persistence مانند RDB و AOF برای ثبت داده روی Disk نیز پشتیبانی می‌کند.

TTL در Redis چیست؟

TTL مدت باقی‌مانده تا Expire شدن یک Key است. با پایان TTL، Key حذف می‌شود.

تفاوت Redis Pub/Sub و Streams چیست؟

Pub/Sub پیام را برای Subscriberهای فعال ارسال می‌کند و معمولاً پیام ازدست‌رفته را نگه نمی‌دارد. Streams پیام‌ها را ذخیره می‌کند و از Consumer Group و Acknowledgement پشتیبانی می‌کند.

آیا Redis برای Queue مناسب است؟

برای Queue ساده می‌توان از List استفاده کرد. برای قابلیت‌هایی مانند Consumer Group و پیگیری پیام‌های پردازش‌نشده، Streams یا یک Queue تخصصی می‌تواند مناسب‌تر باشد.

Redis برای API هوش مصنوعی چه کاربردی دارد؟

Redis می‌تواند پاسخ‌های تکراری را Cache کند، Rate Limit را مدیریت کند، وضعیت Jobها را نگه دارد و Queue پردازش ایجاد کند.

آیا Cache پاسخ هوش مصنوعی همیشه مجاز و مناسب است؟

خیر. باید نوع داده، شخصی‌سازی، Context، تازگی اطلاعات و سیاست نگهداری را بررسی کنید. پاسخ‌های شخصی یا متغیر نباید بدون Scope و TTL مناسب در Cache مشترک قرار گیرند.

آیا می‌توان بدون Redis هم API هوش مصنوعی ساخت؟

بله. Redis یک ابزار اختیاری برای بهبود Performance و معماری است. پروژه ساده یا کم‌ترافیک ممکن است در ابتدا به Redis نیاز نداشته باشد.

آدرس API درواره چیست؟

https://api.darvareh.ir/v1

Endpoint مربوط به Chat Completions:

https://api.darvareh.ir/v1/chat/completions

قیمت مدل‌های درواره را از کجا ببینیم؟

برای مشاهده مدل‌ها، Model ID و قیمت به‌روز، صفحه مدل‌های درواره را بررسی کنید.

جمع‌بندی

Redis یک Data Store سریع و انعطاف‌پذیر است که در معماری Backend، API و سرویس‌های هوش مصنوعی کاربردهای فراوانی دارد. Cache شناخته‌شده‌ترین کاربرد Redis است، اما قابلیت‌هایی مانند TTL، Hash، List، Set، Sorted Set، Pub/Sub و Streams امکان حل مسائل متنوعی را فراهم می‌کنند.

در پروژه عملی این مقاله، یک API خلاصه‌سازی با FastAPI ساختیم که ابتدا Redis را بررسی می‌کند و فقط هنگام Cache Miss به API درواره درخواست می‌فرستد. این معماری می‌تواند زمان پاسخ درخواست‌های تکراری و تعداد فراخوانی‌های غیرضروری مدل را کاهش دهد.

استفاده موفق از Redis فقط به اجرای SET و GET محدود نیست. طراحی Cache Key، انتخاب TTL، Invalidation، مدیریت Cache Stampede، محدودیت Memory، Persistence، Queue و رفتار سیستم هنگام قطع Redis باید از ابتدا مشخص شوند.

برای شروع استفاده از مدل‌های هوش مصنوعی در پروژه‌های Python و Backend، به وب‌سایت درواره مراجعه کنید. فهرست مدل‌ها، Model ID و قیمت‌های به‌روز نیز در صفحه مدل‌های درواره در دسترس است.

منابع

مقالات مرتبط

برای مطالعه شرایط استفاده و محدودیت‌های مسئولیت، صفحه «سلب مسئولیت» را مشاهده کنید.

Read more

اتوماسیون هوش مصنوعی چیست؟ کاربردها و آموزش ساخت AI Automation

اتوماسیون هوش مصنوعی چیست؟ کاربردها و آموزش ساخت AI Automation

اتوماسیون هوش مصنوعی با ترکیب گردش‌کارهای خودکار و مدل‌های هوش مصنوعی، پردازش متن، دسته‌بندی، استخراج اطلاعات و تصمیم‌های پیشنهادی را خودکار می‌کند. در این راهنما، معماری و ساخت نمونه عملی آن با API درواره را می‌آموزید.

Agentic Commerce چیست؟ آینده خرید با ایجنت هوش مصنوعی

Agentic Commerce چیست؟ آینده خرید با ایجنت هوش مصنوعی

Agentic Commerce شیوه‌ای جدید برای خرید اینترنتی است که در آن ایجنت هوش مصنوعی می‌تواند نیاز کاربر را بفهمد، محصولات را جست‌وجو و مقایسه کند و فرایند خرید را پیش ببرد. در این راهنما با معماری، UCP، ACP و پیاده‌سازی آن با API درواره آشنا می‌شوید.