در حال بارگذاری تصویر...

تصویر مقاله آموزش Redis در Django؛ از Cache تا OTP و Celery

آموزش Redis در Django؛ از Cache تا OTP و Celery

خلاصه:

در این آموزش یاد می‌گیریم Redis چیست، چرا در پروژه‌های Django به آن نیاز داریم و چطور Redis را با Docker اجرا و برای Cache، OTP و Celery استفاده کنیم.

مقاله آموزشیلحظاتی پیش46 دقیقه0 نظر
۲۵ بازدید

فرض کنید با Django یک فروشگاه اینترنتی ساخته‌اید. صفحه محصولات سایت شامل نام محصول، قیمت، موجودی، دسته‌بندی و اطلاعات دیگری است که از Database خوانده می‌شوند.

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

اما با بیشتر شدن تعداد کاربران، شرایط کم‌کم تغییر می‌کند.

هر بار که شخصی صفحه محصولات را باز می‌کند، Django باید دوباره به Database مراجعه کند:

Plain text
User Request
     |
     v
   Django
     |
     v
 PostgreSQL
     |
     v
 Response

حالا یک سؤال مهم داریم:

اگر لیست محصولات از درخواست قبلی تا درخواست فعلی هیچ تغییری نکرده است، چرا باید دوباره همان Query را اجرا کنیم؟

اینجا یکی از مهم‌ترین کاربردهای Redis خودش را نشان می‌دهد.

می‌توانیم اطلاعاتی را که زیاد خوانده می‌شوند و مرتب تغییر نمی‌کنند، برای مدت مشخصی در Redis نگه داریم.

در اولین درخواست:

Plain text
Django -> PostgreSQL -> Redis

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

Plain text
Django -> Redis -> Response

تا زمانی که اطلاعات Cache معتبر باشند، دیگر لازم نیست همان Query دوباره روی PostgreSQL اجرا شود.

البته Redis فقط برای Cache نیست. در پروژه‌های Django می‌توانیم از آن برای Session، کدهای OTP، Rate Limiting، Celery و بسیاری از داده‌های موقت دیگر هم استفاده کنیم.

در این مقاله می‌خواهیم دقیقاً ببینیم Redis چیست، چرا به آن نیاز پیدا می‌کنیم و چطور آن را وارد یک پروژه Django کنیم.

در حال بارگذاری تصویر...

یک دیاگرام آموزشی حرفه‌ای برای توضیح مشکل Queryهای تکراری در پروژه Django طراحی کن.

در سمت چپ سه آیکون کوچک کاربر یا سه Request مجزا نمایش داده شوند. هر سه Request به یک باکس سبزرنگ با عنوان `Django` برسند.

از Django سه فلش یا یک مسیر تکرارشونده به یک باکس آبی با عنوان `PostgreSQL` متصل شود.

روی مسیر بین Django و PostgreSQL نوشته شود:

«اجرای Query در هر درخواست»

در سمت راست PostgreSQL یک باکس با عنوان:

«پاسخ»

قرار داشته باشد.

در بالای تصویر عنوان فارسی:

«بدون Cache چه اتفاقی می‌افتد؟»

نوشته شود.

هدف تصویر این باشد که کاربر با یک نگاه متوجه شود چند Request مشابه می‌توانند باعث اجرای چندباره Query روی Database شوند.

تمام اجزا با فاصله مناسب، فلش‌های واضح و متن کم طراحی شوند.

تصویر داخل قاب ثابت اختصاصی کدینگ‌یار باشد: گوشه‌های گرد، حاشیه خاکستری تیره، خط داخلی سبز بسیار ظریف و سایه نرم.

در پایین قاب نوار برندینگ ثابت وجود داشته باشد.

پایین سمت چپ:

`codingyar.com`

پایین سمت راست:

`وبسایت آموزش برنامه نویسی کدینگ‌یار`

نسبت تصویر `16:9`، سبک مینیمال، مدرن، تکنولوژیک و آموزشی باشد.

Redis چیست؟

Redis یک In-Memory Data Store است.

یعنی بخش اصلی اطلاعاتی که Redis با آن‌ها کار می‌کند در حافظه RAM قرار می‌گیرند. دسترسی به RAM بسیار سریع است و به همین دلیل Redis برای سناریوهایی که سرعت بالا اهمیت دارد انتخاب مناسبی محسوب می‌شود.

Redis فقط یک سیستم ساده برای ذخیره key و value نیست و ساختارهای داده مختلفی در اختیار ما قرار می‌دهد، از جمله:

  • String
  • List
  • Set
  • Hash
  • Sorted Set
  • Stream

اما اگر در حال یادگیری Django هستید، لازم نیست از همان ابتدا تمام این ساختارها را بلد باشید.

مهم‌ترین کاربردهای Redis در پروژه‌های Django معمولاً شامل موارد زیر هستند:

  • Cache
  • Session Storage
  • ذخیره اطلاعات موقت مثل OTP
  • Rate Limiting
  • Message Broker برای Celery
  • Counter
  • Queue
  • اطلاعات Real-time

چرا Database به‌تنهایی کافی نیست؟

ممکن است این سؤال برایتان پیش بیاید:

وقتی PostgreSQL داریم، چرا باید Redis را هم وارد پروژه کنیم؟

نکته مهم این است که Redis قرار نیست PostgreSQL را حذف کند.

این دو ابزار معمولاً مسئولیت‌های متفاوتی دارند.

فرض کنید اطلاعات محصول را در PostgreSQL ذخیره کرده‌ایم:

Plain text
Product
----------------
id
name
price
stock
description

این اطلاعات اصلی پروژه هستند و باید به شکل مطمئن و دائمی نگهداری شوند.

PostgreSQL برای این کار مناسب است.

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

اگر در هر Request دوباره Query مشابهی اجرا کنیم، Database باید بارها یک کار تکراری انجام دهد.

اینجا Cache وارد می‌شود.

Plain text
Request
   |
   v
Django
   |
   v
Redis
   |
   +---- اطلاعات وجود دارد؟ ---- بله ---> Response
   |
   خیر
   |
   v
PostgreSQL
   |
   v
Save in Redis
   |
   v
Response

Redis می‌تواند یک لایه سریع در کنار Database ایجاد کند و تعداد Queryهای تکراری را کاهش دهد.

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

قبل از اینکه Redis را اجرا کنیم، چند مثال واقعی ببینیم.

Cache کردن لیست محصولات

فرض کنید مسیر زیر را داریم:

Plain text
GET /products/

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

اگر اطلاعات محصولات هر چند ثانیه تغییر نمی‌کنند، می‌توانیم نتیجه را مثلاً برای ۵ دقیقه Cache کنیم.

در اولین Request:

Plain text
Django -> PostgreSQL -> Redis

در Requestهای بعدی:

Plain text
Django -> Redis

این یکی از رایج‌ترین کاربردهای Redis است.

ذخیره OTP

فرض کنید کاربر برای ورود به سایت یک کد شش‌رقمی دریافت می‌کند:

Plain text
482931

این کد فقط دو دقیقه اعتبار دارد.

در چنین شرایطی معمولاً نمی‌خواهیم یک رکورد دائمی در Database اصلی ایجاد کنیم.

می‌توانیم چیزی شبیه این در Redis داشته باشیم:

Plain text
otp:0912xxxxxxx = 482931
TTL = 120 seconds

بعد از پایان زمان اعتبار، کد منقضی می‌شود.

Rate Limiting

فرض کنید کاربر فقط اجازه دارد در یک دقیقه پنج بار تلاش کند وارد حسابش شود.

Redis می‌تواند یک Counter کوتاه‌مدت نگه دارد:

Plain text
login_attempt:user123 = 3

و بعد از مدت مشخصی آن Counter منقضی شود.

Celery

در پروژه‌های واقعی بعضی عملیات بهتر است داخل Request اصلی انجام نشوند.

مثلاً:

  • ارسال ایمیل
  • ارسال پیامک
  • پردازش فایل
  • پردازش تصویر
  • ساخت گزارش
  • اجرای کارهای زمان‌بر

یکی از ابزارهای معروف برای اجرای چنین کارهایی در پروژه‌های Django، Celery است.

Celery یک Task Queue است.

Django یک Task ایجاد می‌کند و Celery Worker آن Task را جدا از Request کاربر اجرا می‌کند.

Redis می‌تواند بین Django و Celery نقش Message Broker را داشته باشد.

Plain text
Django
   |
   v
Redis
   |
   v
Celery Worker

کمی جلوتر دوباره به Celery برمی‌گردیم.

در حال بارگذاری تصویر...

یک دیاگرام معماری جامع و در عین حال ساده برای نمایش جایگاه Redis در یک پروژه Django طراحی کن.

در مرکز تصویر یک باکس سبزرنگ بزرگ با عنوان:

`Django`

قرار داشته باشد.

در سمت چپ یک آیکون کاربر با عنوان:

«کاربر»

باشد و با فلش به Django متصل شود.

در سمت راست Django دو مسیر اصلی قرار بگیرد.

مسیر اول به یک باکس قرمز با عنوان:

`Redis`

متصل شود.

در کنار Redis چهار کاربرد کوچک و مرتب نمایش داده شود:

`Cache`

`OTP`

`Session`

`Rate Limit`

مسیر دوم از Django به یک باکس آبی با عنوان:

`PostgreSQL`

متصل شود.

زیر PostgreSQL نوشته شود:

«اطلاعات اصلی و دائمی»

در پایین Redis یک فلش به یک باکس بنفش یا نارنجی با عنوان:

`Celery Worker`

وجود داشته باشد.

روی مسیر Redis به Celery نوشته شود:

«Taskهای پس‌زمینه»

در بالای تصویر عنوان:

«Redis در معماری یک پروژه Django»

قرار داده شود.

هدف دیاگرام نمایش این سه مفهوم باشد:

- PostgreSQL برای اطلاعات اصلی و دائمی
- Redis برای اطلاعات سریع و موقت
- Redis به‌عنوان واسط Django و Celery

تمام تصویر داخل قاب ثابت حرفه‌ای کدینگ‌یار با گوشه‌های گرد، حاشیه تیره، خط داخلی سبز ظریف، سایه ملایم و نوار برندینگ پایین قرار داشته باشد.

پایین سمت چپ:

`codingyar.com`

پایین سمت راست:

`وبسایت آموزش برنامه نویسی کدینگ‌یار`

نسبت تصویر `16:9`، طراحی مدرن، فنی، مینیمال و کاملاً خوانا باشد.

اجرای Redis برای پروژه Django

برای استفاده از Redis ابتدا باید یک Redis Server اجرا کنیم.

روش‌های مختلفی برای این کار وجود دارد، اما در این مقاله از Docker استفاده می‌کنیم.

Docker چیست؟

Docker ابزاری است که کمک می‌کند نرم‌افزارهایی مثل Redis، PostgreSQL یا حتی خود Django را داخل محیط‌هایی ایزوله به نام Container اجرا کنیم.

برای ادامه این مقاله لازم نیست Docker را حرفه‌ای بلد باشید.

ما فقط Redis را با یک دستور اجرا می‌کنیم و Django همچنان مثل قبل روی سیستم خودتان اجرا خواهد شد.

اگر با Django کار می‌کنید، پیشنهاد می‌کنیم بعداً حتماً Docker را هم یاد بگیرید؛ چون در پروژه‌های واقعی و زمان Deploy بسیار کاربردی است.

ساختار مثال این مقاله به شکل زیر است:

Plain text
Your Computer

Django
localhost:8000
      |
      v

Redis Docker Container
localhost:6379

یعنی:

فقط Redis داخل Docker است.

Django همچنان به‌صورت Local روی سیستم اجرا می‌شود.

در حال بارگذاری تصویر...

یک دیاگرام آموزشی بسیار واضح برای دانشجویی که Docker را هنوز کامل بلد نیست طراحی کن.

در سمت چپ یک بخش بزرگ با عنوان:

«سیستم شما»

قرار داشته باشد.

داخل آن یک باکس سبزرنگ با عنوان:

`Django`

قرار بگیرد و زیر آن نوشته شود:

`localhost:8000`

در سمت راست یک Container جدا با ظاهر ساده و مدرن نمایش داده شود و بالای آن نوشته شود:

`Docker Container`

داخل Container یک باکس قرمز با عنوان:

`Redis`

قرار بگیرد.

زیر Redis نوشته شود:

`localhost:6379`

بین Django و Redis یک فلش دوطرفه بزرگ و واضح وجود داشته باشد.

روی فلش نوشته شود:

«اتصال از طریق پورت 6379»

در گوشه تصویر یک یادداشت آموزشی کوچک قرار داشته باشد:

«فقط Redis داخل Docker اجرا می‌شود»

و زیر آن:

«Django روی سیستم شما اجرا می‌شود»

در این دیاگرام PostgreSQL و Celery نمایش داده نشوند.

بالای تصویر عنوان:

«ساختار ساده این آموزش»

قرار داشته باشد.

تصویر داخل همان قاب ثابت اختصاصی کدینگ‌یار، با گوشه‌های گرد، حاشیه تیره، خط سبز ظریف، سایه نرم و نوار برندینگ پایین طراحی شود.

پایین سمت چپ:

`codingyar.com`

پایین سمت راست:

`وبسایت آموزش برنامه نویسی کدینگ‌یار`

نسبت تصویر `16:9` و سبک کاملاً آموزشی و حرفه‌ای باشد.

اجرای Redis با Docker

بعد از نصب Docker یا Docker Desktop، ترمینال را باز کنید و دستور زیر را اجرا کنید:

Bash / Shell
docker run --name codingyar-redis -p 6379:6379 -d redis:8-alpine

قسمت:

Bash / Shell
--name codingyar-redis

نام Container را مشخص می‌کند.

قسمت:

Bash / Shell
-p 6379:6379

پورت Redis داخل Container را روی پورت 6379 سیستم شما در دسترس قرار می‌دهد.

و:

Plain text
redis:8-alpine

ایمیجی است که Redis با استفاده از آن اجرا می‌شود.

چطور بفهمیم Redis اجرا شده است؟

ابتدا دستور زیر را اجرا کنید:

Bash / Shell
docker ps

باید Containerای با نام:

Plain text
codingyar-redis

ببینید.

حالا Redis CLI را داخل همان Container اجرا کنید:

Bash / Shell
docker exec -it codingyar-redis redis-cli

بعد دستور زیر را وارد کنید:

Plain text
PING

اگر همه‌چیز درست باشد، Redis پاسخ می‌دهد:

Plain text
PONG

همین PONG یعنی Redis اجرا شده و آماده دریافت درخواست است.

برای خروج از Redis CLI بنویسید:

Plain text
exit

اتصال Django به Redis

حالا Redis آماده است.

در پروژه Django ابتدا Python Client مربوط به Redis را نصب می‌کنیم:

Bash / Shell
pip install redis

در نسخه‌های جدید Django برای Cache ساده نیازی نیست حتماً django-redis نصب کنیم؛ Django خودش Redis Cache Backend دارد.

داخل settings.py تنظیم زیر را اضافه کنید:

Python
CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.redis.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
    }
}

قسمت مهم تنظیمات:

Plain text
redis://127.0.0.1:6379/1

را بررسی کنیم.

redis:// یعنی نوع اتصال Redis است.

127.0.0.1 یعنی Redis از طریق همین سیستم در دسترس است.

6379 پورت پیش‌فرض Redis است.

و /1 شماره Database منطقی Redis است که برای Cache پروژه انتخاب کرده‌ایم.

تست اتصال Django و Redis

حالا باید مطمئن شویم Django واقعاً به Redis متصل می‌شود.

Django Shell را باز کنید:

Bash / Shell
python manage.py shell

سپس:

Python
from django.core.cache import cache

cache.set("name", "CodingYar", timeout=60)

cache.get("name")

خروجی باید چیزی شبیه این باشد:

Plain text
'CodingYar'

یعنی Django مقدار را داخل Cache ذخیره کرده و دوباره از Redis خوانده است.

Cache کردن لیست محصولات در Django

حالا برویم سراغ مثال واقعی.

فرض کنید View فعلی محصولات به این شکل است:

Python
from django.shortcuts import render

from .models import Product


def products(request):
    products = Product.objects.all()

    return render(
        request,
        "products.html",
        {
            "products": products,
        },
    )

در این شرایط هر بار صفحه باز شود Query مربوط به محصولات اجرا می‌شود.

حالا Cache را اضافه کنیم.

Python
from django.core.cache import cache
from django.shortcuts import render

from .models import Product


def products(request):
    products = cache.get("products")

    if products is None:
        products = list(
            Product.objects.values(
                "id",
                "name",
                "price",
            )
        )

        cache.set(
            "products",
            products,
            timeout=300,
        )

    return render(
        request,
        "products.html",
        {
            "products": products,
        },
    )

در ابتدا:

Python
products = cache.get("products")

از Cache می‌پرسیم آیا اطلاعات محصولات وجود دارد یا نه.

اگر وجود نداشته باشد:

Python
if products is None:

اطلاعات را از Database می‌خوانیم:

Python
products = list(
    Product.objects.values(
        "id",
        "name",
        "price",
    )
)

و بعد آن را برای ۳۰۰ ثانیه یا ۵ دقیقه Cache می‌کنیم:

Python
cache.set(
    "products",
    products,
    timeout=300,
)

از این به بعد، تا زمانی که Cache منقضی نشده باشد، Requestهای بعدی می‌توانند اطلاعات را از Redis دریافت کنند.

چرا if not products ننوشتیم؟

ممکن است کدی شبیه این بنویسید:

Python
if not products:

اما فرض کنید لیست محصولات واقعاً خالی باشد:

Python
[]

این مقدار ممکن است به‌درستی داخل Cache ذخیره شده باشد، اما شرط if not products آن را False در نظر می‌گیرد و دوباره Query اجرا می‌شود.

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

Python
if products is None:

تا فقط نبودن مقدار در Cache را تشخیص دهیم.

در حال بارگذاری تصویر...

یک فلوچارت آموزشی حرفه‌ای برای توضیح الگوریتم Cache Aside در Django طراحی کن.

فلوچارت از بالا به پایین باشد.

مرحله اول:

«درخواست کاربر»

سپس فلش به:

`Django`

بعد یک لوزی تصمیم‌گیری با متن:

«اطلاعات در Redis وجود دارد؟»

از لوزی دو مسیر خارج شود.

مسیر سبزرنگ با برچسب:

«بله»

به:

«خواندن اطلاعات از Redis»

و سپس:

«ارسال پاسخ»

متصل شود.

مسیر نارنجی یا قرمز با برچسب:

«خیر»

به:

«خواندن اطلاعات از PostgreSQL»

سپس:

«ذخیره نتیجه در Redis»

و زیر آن:

«مثلاً برای ۵ دقیقه»

و در نهایت:

«ارسال پاسخ»

متصل شود.

بالای تصویر نوشته شود:

«الگوی Cache Aside در Django»

در پایین تصویر یک نکته کوتاه قرار بگیرد:

«درخواست‌های بعدی تا زمان انقضای Cache به Query مجدد نیاز ندارند.»

Django سبز، Redis قرمز و PostgreSQL آبی باشد.

تصویر در قاب ثابت و حرفه‌ای کدینگ‌یار با گوشه‌های گرد، حاشیه تیره، خط داخلی سبز، سایه نرم و نوار برندینگ پایین قرار بگیرد.

پایین سمت چپ:

`codingyar.com`

پایین سمت راست:

`وبسایت آموزش برنامه نویسی کدینگ‌یار`

نسبت تصویر `16:9`، کاملاً خوانا و مناسب مقاله آموزشی باشد.

Cache Hit و Cache Miss چیست؟

وقتی اطلاعاتی را از Cache درخواست می‌کنیم، دو حالت اصلی داریم.

اگر اطلاعات وجود داشته باشند:

Cache Hit

اتفاق افتاده است.

Plain text
Django -> Redis -> Data

اما اگر اطلاعات وجود نداشته باشند:

Cache Miss

داریم.

Plain text
Django -> Redis -> Not Found
                   |
                   v
              PostgreSQL

در Cache Miss معمولاً اطلاعات را از Database دریافت می‌کنیم و برای Requestهای بعدی داخل Cache ذخیره می‌کنیم.

Cache Invalidation؛ وقتی اطلاعات Cache قدیمی می‌شوند

Cache یک مسئله مهم دارد.

فرض کنید لیست محصولات را برای ۵ دقیقه Cache کرده‌ایم.

بعد از یک دقیقه مدیر سایت قیمت یک محصول را تغییر می‌دهد.

Database به‌روز شده، اما Redis هنوز نسخه قبلی اطلاعات را دارد.

در نتیجه ممکن است کاربر اطلاعات قدیمی دریافت کند.

به این وضعیت Stale Cache می‌گوییم.

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

Python
from django.core.cache import cache

cache.delete("products")

در Request بعدی، اطلاعات جدید از Database خوانده و دوباره Cache می‌شوند.

در پروژه‌های بزرگ‌تر، Cache Invalidation خودش یکی از موضوعات مهم طراحی سیستم است.

در حال بارگذاری تصویر...

یک دیاگرام آموزشی برای توضیح Cache Invalidation و Stale Cache طراحی کن.

در سمت چپ یک باکس آبی با عنوان:

`PostgreSQL`

قرار داشته باشد.

داخل آن یک محصول نمونه نمایش داده شود:

«قیمت جدید: ۸۰۰ هزار تومان»

در سمت راست یک باکس قرمز با عنوان:

`Redis`

قرار داشته باشد.

داخل Redis نوشته شود:

«قیمت Cache شده: ۷۵۰ هزار تومان»

بین دو بخش یک علامت هشدار نارنجی بزرگ قرار بگیرد و بالای آن نوشته شود:

«Cache قدیمی شده است»

در قسمت پایین تصویر یک مرحله با عنوان:

`cache.delete("products")`

نمایش داده شود.

بعد از آن یک فلش به Redis جدید وجود داشته باشد و داخل آن نوشته شود:

«در درخواست بعدی اطلاعات جدید Cache می‌شود»

بالای تصویر عنوان:

«Stale Cache و Cache Invalidation»

قرار بگیرد.

قاب ثابت کدینگ‌یار با گوشه‌های گرد، حاشیه خاکستری تیره، خط داخلی سبز، سایه ملایم و نوار برندینگ پایین استفاده شود.

پایین سمت چپ:

`codingyar.com`

پایین سمت راست:

`وبسایت آموزش برنامه نویسی کدینگ‌یار`

نسبت تصویر `16:9` و سبک آموزشی، مدرن و کاملاً واضح باشد.

مشاهده Keyهای Redis

برای بررسی اطلاعات داخل Redis دوباره Redis CLI را اجرا کنید:

Bash / Shell
docker exec -it codingyar-redis redis-cli

چون در تنظیمات Django از Database شماره 1 استفاده کردیم:

Plain text
SELECT 1

حالا می‌توانیم Keyها را بررسی کنیم:

Plain text
SCAN 0

یا برای پیدا کردن Key محصولات:

Plain text
SCAN 0 MATCH "*products*"

ممکن است Key نهایی چیزی شبیه این باشد:

Plain text
:1:products

Django ممکن است Prefix و Version را هم به نام Key اضافه کند.

در محیط‌های کوچک توسعه احتمالاً دستور زیر را هم دیده‌اید:

Plain text
KEYS *

اما برای Redisهای بزرگ‌تر بهتر است به‌جای KEYS از SCAN استفاده کنیم.

آیا Redis همیشه پروژه را سریع‌تر می‌کند؟

Redis معمولاً می‌تواند زمان بعضی عملیات تکراری را کاهش دهد، اما نباید انتظار داشته باشیم فقط با اضافه کردن Redis تمام بخش‌های پروژه ناگهان سریع شوند.

سرعت واقعی به عوامل مختلفی بستگی دارد:

  • نوع Query
  • تعداد رکوردها
  • Indexهای Database
  • حجم داده Cache شده
  • شبکه
  • سخت‌افزار
  • تعداد کاربران
  • معماری پروژه

به همین دلیل نباید اعدادی مثل این را به‌عنوان یک قانون در نظر بگیریم:

Plain text
Database = 300ms
Redis = 5ms

ممکن است در یک پروژه اختلاف بسیار بیشتر باشد و در پروژه دیگر کمتر.

اصل مهم این است:

اول Bottleneck را پیدا کنید، بعد Cache اضافه کنید.

Cache باید یک Optimization هدفمند باشد، نه چیزی که بدون دلیل به تمام Viewهای پروژه اضافه شود.

ذخیره OTP در Redis

یکی دیگر از کاربردهای خوب Redis، اطلاعات کوتاه‌عمر است.

فرض کنید می‌خواهیم برای کاربر یک OTP شش‌رقمی ایجاد کنیم.

برای تولید کد تصادفی می‌توانیم از secrets استفاده کنیم:

Python
import secrets

otp = f"{secrets.randbelow(1_000_000):06d}"

حالا کد را برای ۱۲۰ ثانیه در Cache ذخیره می‌کنیم:

Python
from django.core.cache import cache


phone = "09121234567"
otp = "482931"

cache.set(
    f"otp:{phone}",
    otp,
    timeout=120,
)

برای خواندن کد:

Python
saved_otp = cache.get(
    f"otp:{phone}"
)

بعد از دو دقیقه، این مقدار دیگر معتبر نخواهد بود.

در پروژه واقعی بهتر است OTP را Plain Text نگهداری نکنیم.

برای نمونه می‌توانیم Hash آن را ذخیره کنیم:

Python
import secrets

from django.contrib.auth.hashers import (
    check_password,
    make_password,
)
from django.core.cache import cache


phone = "09121234567"

otp = f"{secrets.randbelow(1_000_000):06d}"

cache.set(
    f"otp:{phone}",
    make_password(otp),
    timeout=120,
)

و هنگام اعتبارسنجی:

Python
saved_otp_hash = cache.get(
    f"otp:{phone}"
)

if (
    saved_otp_hash is not None
    and check_password(
        user_entered_otp,
        saved_otp_hash,
    )
):
    print("OTP is valid")

در یک سیستم واقعی باید محدودیت تعداد درخواست OTP، تعداد تلاش برای وارد کردن کد و موارد امنیتی دیگر را هم در نظر بگیرید.

در حال بارگذاری تصویر...

یک دیاگرام آموزشی مرحله‌به‌مرحله برای نمایش ذخیره OTP در Redis همراه با TTL طراحی کن.

در سمت چپ یک آیکون موبایل با عنوان:

«کاربر»

قرار داشته باشد.

کنار موبایل شماره نمونه:

`0912xxxxxxx`

نمایش داده شود.

فلش به یک باکس سبز با عنوان:

`Django`

متصل شود.

داخل Django نوشته شود:

«تولید کد OTP»

و یک کد نمونه:

`482931`

نمایش داده شود.

سپس فلش به یک باکس قرمز با عنوان:

`Redis`

برود.

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

`otp:0912xxxxxxx`

و زیر آن:

«کد OTP»

کنار Redis یک آیکون ساعت یا تایمر قرار داشته باشد و روی آن نوشته شود:

«TTL = 120 ثانیه»

در انتهای مسیر Key به‌صورت محوشده یا حذف‌شده نمایش داده شود و نوشته شود:

«بعد از ۲ دقیقه منقضی می‌شود»

در پایین تصویر یک نکته کوتاه:

«در پروژه واقعی OTP را به‌صورت امن ذخیره کنید.»

قرار داده شود.

تمام تصویر در همان قاب ثابت کدینگ‌یار، با گوشه‌های گرد، حاشیه تیره، خط داخلی سبز، سایه ملایم و نوار برندینگ پایین باشد.

پایین سمت چپ:

`codingyar.com`

پایین سمت راست:

`وبسایت آموزش برنامه نویسی کدینگ‌یار`

نسبت تصویر `16:9` و سبک مدرن، آموزشی و هماهنگ با سایر تصاویر مقاله باشد.

استفاده از Redis برای Session

یکی دیگر از کاربردهای Redis، Session Storage است.

فرض کنید پروژه شما چند Django Server دارد:

Plain text
Django Server 1
Django Server 2
Django Server 3

اگر اطلاعات Session فقط داخل Memory هر Server قرار بگیرند، مدیریت Session مشترک بین Serverها مشکل می‌شود.

Redis می‌تواند نقش Storage مرکزی را داشته باشد:

Plain text
Redis
            /  |  \
           /   |   \
          v    v    v

       Django Django Django

در این حالت تمام Serverها می‌توانند اطلاعات Session را از یک محل مشترک دریافت کنند.

در حال بارگذاری تصویر...

یک دیاگرام معماری آموزشی برای نمایش Session مشترک بین چند Django Server طراحی کن.

در پایین تصویر سه باکس سبز مجزا قرار داشته باشند:

`Django Server 1`

`Django Server 2`

`Django Server 3`

هر سه با فلش به یک Redis مرکزی در بالای تصویر متصل شوند.

Redis با رنگ قرمز و عنوان:

`Redis Session Store`

نمایش داده شود.

داخل Redis چند کارت کوچک با عنوان‌های:

`Session A`

`Session B`

`Session C`

قرار داشته باشد.

در سمت چپ یک کاربر نمایش داده شود که Request او می‌تواند به هر یک از Django Serverها برسد.

در بالای تصویر عنوان:

«Session مشترک بین چند Django Server»

و پایین تصویر نوشته شود:

«تمام سرورها Session را از یک Storage مشترک دریافت می‌کنند.»

قاب استاندارد کدینگ‌یار با گوشه‌های گرد، حاشیه تیره، خط سبز ظریف، سایه نرم و نوار برندینگ ثابت استفاده شود.

پایین سمت چپ:

`codingyar.com`

پایین سمت راست:

`وبسایت آموزش برنامه نویسی کدینگ‌یار`

نسبت تصویر `16:9` و طراحی مینیمال، فنی و بسیار خوانا باشد.

Rate Limiting با Redis

Redis برای نگهداری Counterهای کوتاه‌مدت هم مناسب است.

فرض کنید می‌خواهیم این قانون را اجرا کنیم:

Plain text
حداکثر ۵ تلاش برای ورود در ۶۰ ثانیه

می‌توانیم Counterای مثل این داشته باشیم:

Plain text
login_attempt:user123 = 3

هر بار که کاربر تلاش می‌کند وارد شود، مقدار Counter افزایش پیدا می‌کند.

همزمان یک زمان انقضا هم برای آن تعریف می‌کنیم.

از همین الگو می‌توان برای محدود کردن درخواست OTP، Login، API و بسیاری از Endpointهای دیگر استفاده کرد.

در حال بارگذاری تصویر...

یک دیاگرام آموزشی برای مفهوم Rate Limiting با Redis طراحی کن.

در سمت چپ یک کاربر نمایش داده شود که چند Request سریع به Django ارسال می‌کند.

Requestها با برچسب‌های زیر نمایش داده شوند:

`Request 1`

`Request 2`

`Request 3`

`Request 4`

`Request 5`

`Request 6`

پنج Request اول سبزرنگ و Request ششم قرمز باشد.

Django در مرکز تصویر با رنگ سبز قرار بگیرد.

یک فلش از Django به Redis قرمزرنگ وجود داشته باشد.

داخل Redis یک Counter با متن:

`login_attempt:user123`

و زیر آن:

`5 / 60 sec`

نمایش داده شود.

Request ششم به یک علامت توقف برسد و کنار آن نوشته شود:

«درخواست بیش از حد مجاز»

کنار Redis یک تایمر کوچک قرار داشته باشد و نوشته شود:

«انقضا بعد از ۶۰ ثانیه»

بالای تصویر عنوان:

«Rate Limiting با Redis»

قرار بگیرد.

تصویر مفهوم Counter + TTL + محدودیت Request را واضح نشان دهد.

قاب ثابت حرفه‌ای کدینگ‌یار با گوشه‌های گرد، حاشیه تیره، خط داخلی سبز و نوار برندینگ پایین استفاده شود.

پایین سمت چپ:

`codingyar.com`

پایین سمت راست:

`وبسایت آموزش برنامه نویسی کدینگ‌یار`

نسبت تصویر `16:9`، طراحی حرفه‌ای و هماهنگ با سایر تصاویر مقاله باشد.

Redis و Celery

حالا به یکی از مهم‌ترین کاربردهای Redis در پروژه‌های بزرگ‌تر Django می‌رسیم.

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

اگر ارسال ایمیل داخل Request اصلی انجام شود، ممکن است کاربر مجبور شود چند ثانیه منتظر بماند.

Celery کمک می‌کند کار را به Background منتقل کنیم.

ایده ساده است:

Django به جای اینکه خودش عملیات را انجام دهد، یک Task ایجاد می‌کند.

Task وارد یک Queue می‌شود.

Celery Worker آن را دریافت و اجرا می‌کند.

Plain text
User
 |
 v
Django
 |
 v
Redis
 |
 v
Celery Worker
 |
 v
Send Email

Redis در این معماری می‌تواند نقش Message Broker را داشته باشد.

برای مثال تنظیم اولیه Celery ممکن است چیزی شبیه این باشد:

Python
CELERY_BROKER_URL = "redis://127.0.0.1:6379/2"

و اگر بخواهیم Result Taskها هم داخل Redis نگهداری شوند:

Python
CELERY_RESULT_BACKEND = "redis://127.0.0.1:6379/3"

برای نصب Celery همراه پشتیبانی Redis:

Bash / Shell
pip install "celery[redis]"

البته Redis تنها Broker قابل استفاده برای Celery نیست و گزینه‌هایی مثل RabbitMQ هم وجود دارند.

Celery خودش موضوع بزرگی است و بهتر است در یک مقاله جداگانه آن را کامل بررسی کنیم.

در حال بارگذاری تصویر...

یک دیاگرام معماری مرحله‌به‌مرحله برای توضیح ارتباط Django، Redis و Celery طراحی کن.

مسیر اصلی از چپ به راست باشد.

ابتدا یک آیکون کاربر با عنوان:

«کاربر»

سپس یک فلش به:

`Django`

Django سبزرنگ باشد.

بعد از Django دو مسیر وجود داشته باشد.

مسیر اول یک فلش کوتاه به سمت کاربر برگرداند و روی آن نوشته شود:

«پاسخ سریع»

مسیر دوم از Django به Redis قرمزرنگ متصل شود.

روی این فلش نوشته شود:

«ارسال Task به صف»

بعد Redis با فلش به یک باکس بنفش یا نارنجی با عنوان:

`Celery Worker`

متصل شود.

روی فلش نوشته شود:

«دریافت Task»

از Celery Worker سه خروجی کوچک وجود داشته باشد:

«ارسال ایمیل»

«پردازش فایل»

«ساخت گزارش»

بالای تصویر عنوان:

«اجرای Taskهای پس‌زمینه با Celery و Redis»

و پایین تصویر نوشته شود:

«Redis در این معماری می‌تواند نقش Message Broker را داشته باشد.»

تصویر باید به‌وضوح نشان دهد کاربر منتظر پایان Task پس‌زمینه نمی‌ماند.

تمام تصویر داخل قاب ثابت اختصاصی کدینگ‌یار با گوشه‌های گرد، حاشیه خاکستری تیره، خط سبز ظریف، سایه نرم و نوار برندینگ پایین قرار داشته باشد.

پایین سمت چپ:

`codingyar.com`

پایین سمت راست:

`وبسایت آموزش برنامه نویسی کدینگ‌یار`

نسبت تصویر `16:9` و طراحی حرفه‌ای، مینیمال و مناسب آموزش معماری نرم‌افزار باشد.

Redis در برابر Local Memory Cache

ممکن است بپرسید چرا از یک Dictionary ساده در Python استفاده نکنیم؟

مثلاً:

Python
cache = {}

در یک Process ساده شاید کار کند.

اما فرض کنید دو Django Server داریم:

Plain text
Server 1
Cache A

Server 2
Cache B

هر Server حافظه خودش را دارد.

در نتیجه Cacheها با هم مشترک نیستند.

اما Redis می‌تواند یک Cache مرکزی ایجاد کند که همه Serverها از آن استفاده کنند.

در حال بارگذاری تصویر...

یک تصویر مقایسه‌ای دو قسمتی طراحی کن.

نیمه اول با عنوان:

«Local Memory Cache»

باشد.

دو Server نمایش داده شوند:

`Django Server 1`

`Django Server 2`

داخل Server اول نوشته شود:

`Cache A`

و داخل Server دوم:

`Cache B`

بین این دو Cache هیچ ارتباطی وجود نداشته باشد و یک علامت هشدار نمایش داده شود.

زیر آن نوشته شود:

«Cacheها با هم هماهنگ نیستند»

نیمه دوم با عنوان:

«Redis Cache»

همان دو Django Server نمایش داده شوند اما هر دو با فلش به یک Redis مرکزی متصل باشند.

داخل Redis نوشته شود:

«Cache مشترک»

زیر آن با رنگ سبز نوشته شود:

«اطلاعات مشترک بین تمام Serverها»

تصویر داخل قاب ثابت کدینگ‌یار با گوشه‌های گرد، حاشیه تیره، خط سبز ظریف، سایه نرم و نوار برندینگ پایین باشد.

پایین سمت چپ:

`codingyar.com`

پایین سمت راست:

`وبسایت آموزش برنامه نویسی کدینگ‌یار`

نسبت تصویر `16:9` و طراحی مینیمال و آموزشی باشد.

Redis بهتر است یا Memcached؟

Memcached هم یک In-Memory Cache شناخته‌شده است.

اگر فقط Cache ساده بخواهیم، می‌تواند گزینه بسیار خوبی باشد.

اما Redis امکانات بیشتری در اختیار ما قرار می‌دهد.

مثلاً Redis علاوه بر Cache می‌تواند در سناریوهای زیر هم استفاده شود:

  • Counter
  • Queue
  • Rate Limiting
  • Pub/Sub
  • Sorted Set
  • Celery Broker
  • Temporary Data

به همین دلیل در بسیاری از پروژه‌های Django، Redis می‌تواند همزمان چند نیاز را پوشش دهد.

آیا Redis جای PostgreSQL را می‌گیرد؟

خیر.

این نکته بسیار مهم است.

Redis را نباید فقط به دلیل سرعت بالاتر جای Database اصلی قرار دهیم.

اطلاعاتی مثل:

  • User
  • Order
  • Product
  • Payment
  • Invoice

معمولاً باید در Database اصلی ذخیره شوند.

در مقابل Redis برای مواردی مثل این بسیار مناسب است:

  • Cache
  • OTP
  • Session
  • Counter
  • Rate Limit
  • Queue
  • Temporary Token

Redis قابلیت Persistence هم دارد، اما این به معنی آن نیست که همیشه باید جای Database رابطه‌ای پروژه استفاده شود.

در حال بارگذاری تصویر...

یک تصویر مفهومی دو ستونه برای توضیح تفاوت PostgreSQL و Redis طراحی کن.

در سمت راست یک باکس بزرگ آبی با عنوان:

`PostgreSQL`

قرار داشته باشد.

داخل آن کارت‌های:

`User`

`Order`

`Product`

`Payment`

`Invoice`

وجود داشته باشد.

زیر PostgreSQL نوشته شود:

«اطلاعات اصلی و دائمی»

در سمت چپ یک باکس بزرگ قرمز با عنوان:

`Redis`

قرار داشته باشد.

داخل آن کارت‌های:

`Cache`

`OTP`

`Session`

`Counter`

`Rate Limit`

`Queue`

نمایش داده شوند.

زیر Redis نوشته شود:

«اطلاعات سریع، موقت یا مکمل»

بین دو باکس عبارت:

«جایگزین یکدیگر نیستند»

به‌صورت بسیار واضح نمایش داده شود.

بالای تصویر عنوان:

«Redis و PostgreSQL مسئولیت‌های متفاوتی دارند»

قرار بگیرد.

قاب ثابت اختصاصی کدینگ‌یار با گوشه‌های گرد، حاشیه خاکستری تیره، خط داخلی سبز، سایه نرم و نوار برندینگ پایین استفاده شود.

پایین سمت چپ:

`codingyar.com`

پایین سمت راست:

`وبسایت آموزش برنامه نویسی کدینگ‌یار`

نسبت تصویر `16:9`، طراحی ساده، حرفه‌ای و بسیار خوانا باشد.

چه زمانی نباید از Redis استفاده کنیم؟

Redis ابزار قدرتمندی است، اما قرار نیست به هر پروژه‌ای اضافه شود.

اگر پروژه کوچک است و مشکل Performance مشخصی ندارید، شاید هنوز نیازی به Cache خارجی نداشته باشید.

همچنین:

  • هر Query را Cache نکنید.
  • اطلاعاتی که دائماً تغییر می‌کنند را بدون طراحی مناسب Cache نکنید.
  • Cache Invalidation را فراموش نکنید.
  • Redis را بدون تنظیمات امنیتی مناسب مستقیماً روی اینترنت قرار ندهید.
  • Cache را Source of Truth اطلاعات حیاتی در نظر نگیرید.

یک قانون ساده:

اول مشکل را پیدا کنید، بعد Redis را به‌عنوان راه‌حل وارد کنید.

اگر Docker را بهتر بلد باشیم چه؟

در این مقاله عمداً فقط Redis را داخل Docker اجرا کردیم:

Plain text
Django Local
     |
     v
Redis Container

دلیل این کار این بود که اگر Docker را بلد نباشید، همچنان بتوانید آموزش Redis را دنبال کنید.

اما در پروژه‌های واقعی‌تر معمولاً ممکن است کل Stack را با Docker Compose اجرا کنیم:

Plain text
Django
PostgreSQL
Redis
Celery

نمونه ساده:

Plain text
services:
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/app
    ports:
      - "8000:8000"
    depends_on:
      - db
      - redis

  db:
    image: postgres:17
    environment:
      POSTGRES_DB: codingyar
      POSTGRES_USER: codingyar
      POSTGRES_PASSWORD: codingyar
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:8-alpine

  celery:
    build: .
    command: celery -A config worker -l info
    volumes:
      - .:/app
    depends_on:
      - redis
      - db

volumes:
  postgres_data:

وقتی Django روی سیستم شما اجرا می‌شد، آدرس Redis این بود:

Plain text
redis://127.0.0.1:6379/1

اما وقتی Django هم داخل Docker Compose قرار بگیرد، سرویس‌ها می‌توانند با نام یکدیگر ارتباط برقرار کنند.

در نتیجه آدرس Redis می‌تواند به شکل زیر باشد:

Plain text
redis://redis:6379/1

و برای Celery:

Python
CELERY_BROKER_URL = "redis://redis:6379/2"

این ساختار موضوع اصلی مقاله فعلی نیست، اما اگر قصد دارید Django را حرفه‌ای ادامه دهید، یادگیری Docker و Docker Compose قدم مهمی در ادامه مسیر است.

در حال بارگذاری تصویر...

یک دیاگرام معماری حرفه‌ای برای پروژه‌ای شامل Django، PostgreSQL، Redis و Celery طراحی کن.

یک قاب داخلی بزرگ با عنوان:

`Docker Compose`

در مرکز تصویر قرار داشته باشد.

داخل آن چهار سرویس نمایش داده شوند:

یک باکس سبز:

`Django`

یک باکس آبی:

`PostgreSQL`

یک باکس قرمز:

`Redis`

یک باکس بنفش یا نارنجی:

`Celery Worker`

ارتباط‌ها:

از Django به PostgreSQL با برچسب:

«اطلاعات اصلی»

از Django به Redis با برچسب:

«Cache / Broker»

از Redis به Celery Worker با برچسب:

«Task Queue»

و از Celery Worker به PostgreSQL برای نمایش دسترسی Worker به Database.

در بیرون Docker Compose یک کاربر قرار داشته باشد که فقط به Django متصل است.

روی Django نوشته شود:

`port 8000`

و روی Redis نوشته شود:

`redis:6379`

در گوشه‌ای از تصویر یک یادداشت کوتاه باشد:

«سرویس‌ها در Docker Compose با نام Service به هم متصل می‌شوند.»

بالای تصویر عنوان:

«معماری کامل‌تر Django + PostgreSQL + Redis + Celery»

باشد.

تصویر داخل همان قاب ثابت حرفه‌ای کدینگ‌یار با گوشه‌های گرد، حاشیه تیره، خط داخلی سبز، سایه نرم و نوار برندینگ پایین قرار بگیرد.

پایین سمت چپ:

`codingyar.com`

پایین سمت راست:

`وبسایت آموزش برنامه نویسی کدینگ‌یار`

نسبت تصویر `16:9` و ظاهر آن شبیه یک دیاگرام معماری حرفه‌ای نرم‌افزار باشد.

Redis در پروژه‌های Django کجا استفاده می‌شود؟

اگر بخواهیم کاربردهای Redis را خلاصه کنیم:

  • Cache: کاهش Queryهای تکراری و فشار روی Database

  • Session: Storage سریع و مشترک بین چند Server

  • OTP: ذخیره موقت همراه با زمان انقضا

  • Rate Limiting: کنترل تعداد درخواست

  • Celery Broker: انتقال Task از Django به Worker

  • Celery Result Backend: نگهداری نتیجه Taskها

  • Temporary Data: نگهداری اطلاعات کوتاه‌عمر

  • Real-time Features: استفاده در برخی معماری‌های Pub/Sub و Channel

در حال بارگذاری تصویر...

یک Infographic حرفه‌ای و آموزشی برای مرور کاربردهای Redis در Django طراحی کن.

در مرکز تصویر یک شش‌ضلعی یا دایره قرمز با عنوان بزرگ:

`Redis`

قرار داشته باشد.

دور Redis شش بخش متقارن قرار بگیرند.

بخش اول:

`Cache`

زیر آن:

«کاهش Query تکراری»

بخش دوم:

`OTP`

زیر آن:

«داده موقت + TTL»

بخش سوم:

`Session`

زیر آن:

«Storage مشترک»

بخش چهارم:

`Rate Limiting`

زیر آن:

«کنترل تعداد درخواست»

بخش پنجم:

`Celery`

زیر آن:

«Message Broker»

بخش ششم:

`Temporary Data`

زیر آن:

«اطلاعات کوتاه‌عمر»

در پس‌زمینه به‌صورت بسیار ظریف Django و PostgreSQL نمایش داده شوند.

در بالای تصویر عنوان:

«Redis در Django چه کاربردهایی دارد؟»

قرار داشته باشد.

تصویر باید مثل یک خلاصه تصویری از مقاله عمل کند.

همان قاب ثابت و یکدست کدینگ‌یار با گوشه‌های گرد، حاشیه خاکستری تیره، خط داخلی سبز، سایه ملایم و نوار برندینگ پایین استفاده شود.

پایین سمت چپ:

`codingyar.com`

پایین سمت راست:

`وبسایت آموزش برنامه نویسی کدینگ‌یار`

نسبت تصویر `16:9`، کیفیت بالا، طراحی تمیز، مینیمال و حرفه‌ای باشد.

جمع‌بندی

تا قبل از Redis، معماری ساده پروژه ما تقریباً به این شکل بود:

Plain text
Django -> PostgreSQL

حالا یک ابزار جدید به معماری اضافه شده است:

Plain text
Django
  |
  +----> PostgreSQL
  |
  +----> Redis

PostgreSQL همچنان Database اصلی پروژه است.

Redis در کنار آن می‌تواند مسئولیت‌هایی مثل Cache، OTP، Session، Rate Limiting و داده‌های موقت را برعهده بگیرد.

وقتی Celery را هم وارد پروژه کنیم، معماری می‌تواند به این شکل برسد:

Plain text
Django
  |
  +----> PostgreSQL
  |
  +----> Redis <----> Celery Worker

مهم‌ترین نکته این مقاله این است:

Redis جای Database اصلی نیست؛ Redis ابزاری مکمل برای حل بعضی مشکلات مشخص در معماری برنامه است.

اگر داده‌ای:

  • زیاد خوانده می‌شود،
  • موقت است،
  • نیاز به TTL دارد،
  • Counter است،
  • باید سریع در دسترس باشد،
  • یا در Queue پردازش می‌شود،

Redis می‌تواند انتخاب بسیار مناسبی باشد.

مسیر ادامه یادگیری

بعد از این مقاله می‌توانید سراغ موضوعات زیر بروید:

  1. آموزش Celery در Django
  2. اجرای Taskهای Background با Redis و Celery
  3. Cache کردن Viewها و Queryها در Django
  4. Cache Invalidation در پروژه‌های واقعی
  5. Rate Limiting با Redis
  6. Session در Redis
  7. بهینه‌سازی Performance در Django
  8. Redis در محیط Production
  9. Docker و Docker Compose برای پروژه‌های Django

سوالات متداول

آیا برای استفاده از Redis در Django حتماً باید Docker بلد باشیم؟

خیر.

Redis را می‌توان به روش‌های دیگری هم نصب کرد.

در این مقاله از Docker استفاده کردیم چون با یک دستور می‌توان Redis را اجرا کرد و لازم نیست نصب مستقیم آن روی سیستم را انجام دهید.

برای دنبال کردن این مقاله فقط چند دستور ساده Docker کافی است.

با این حال اگر قصد دارید Django را به شکل حرفه‌ای ادامه دهید، یادگیری Docker بسیار پیشنهاد می‌شود.

آیا برای Redis حتماً باید django-redis نصب کنیم؟

خیر.

برای Cache ساده در نسخه‌های جدید Django می‌توانیم از Backend داخلی Redis استفاده کنیم:

Plain text
django.core.cache.backends.redis.RedisCache

و Python Client مربوط به Redis را نصب کنیم:

Bash / Shell
pip install redis

پکیج django-redis همچنان امکانات خودش را دارد و در بعضی پروژه‌ها ممکن است انتخاب مناسبی باشد، اما برای مثال پایه این مقاله ضروری نیست.

Redis بهتر است یا PostgreSQL؟

این دو ابزار معمولاً رقیب یکدیگر نیستند.

PostgreSQL برای اطلاعات اصلی، دائمی و رابطه‌ای پروژه مناسب است.

Redis بیشتر برای Cache، داده‌های موقت، Session، Counter، Queue و سناریوهایی که سرعت بالا مهم است استفاده می‌شود.

آیا Celery بدون Redis کار می‌کند؟

بله.

Celery به Message Broker نیاز دارد، اما Redis تنها گزینه نیست.

RabbitMQ یکی دیگر از انتخاب‌های مهم است.

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

TTL چیست؟

TTL مخفف Time To Live است.

TTL مشخص می‌کند یک Key چه مدت معتبر باشد.

مثلاً:

Plain text
OTP = 482931
TTL = 120 seconds

بعد از پایان این زمان، کد دیگر معتبر نخواهد بود.

آیا باید همه Queryهای Django را Cache کنیم؟

خیر.

Cache کردن بدون تحلیل می‌تواند پیچیدگی پروژه را بیشتر کند.

بهتر است ابتدا بخش‌هایی را پیدا کنید که Queryهای سنگین یا پرتکرار دارند و بعد برای همان قسمت‌ها Cache اضافه کنید.

همیشه باید به Cache Invalidation و قدیمی شدن اطلاعات Cache شده هم فکر کنید.

نتیجه نهایی

Redis یکی از ابزارهایی است که معمولاً وقتی پروژه Django از حالت ساده و آموزشی فاصله می‌گیرد، اهمیت آن بیشتر مشخص می‌شود.

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

اما وقتی تعداد کاربران بیشتر شود، Taskهای پس‌زمینه داشته باشید، OTP ارسال کنید، Session مشترک نیاز داشته باشید یا بخواهید Queryهای پرتکرار را کاهش دهید، Redis می‌تواند بخش مهمی از معماری پروژه شما شود.

در این مقاله Redis را اجرا کردیم، آن را به Django متصل کردیم، Cache را به‌صورت عملی پیاده‌سازی کردیم، یک نمونه OTP ساختیم و با کاربرد Redis در Session، Rate Limiting و Celery آشنا شدیم.

از اینجا به بعد، قدم منطقی بعدی می‌تواند آموزش Celery در Django و اجرای Taskهای Background با Redis باشد.

اشتراک‌گذاری

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

نویسنده
م

محمدهادی حاجی حسینی

نویسنده مقالات آموزشی کدینگ‌یار

دوره‌های مرتبط

یادگیری عمیق‌تر با دوره‌های پروژه‌محور

مقالات VIP

در هر دوره‌ای شرکت کنید، به محتوای اختصاصی همان دوره دسترسی پیدا می‌کنید.