فرض کنید با Django یک فروشگاه اینترنتی ساختهاید. صفحه محصولات سایت شامل نام محصول، قیمت، موجودی، دستهبندی و اطلاعات دیگری است که از Database خوانده میشوند.
در روزهای اول همهچیز خوب کار میکند. تعداد کاربران کم است و Database هم بدون مشکل Queryها را پاسخ میدهد.
اما با بیشتر شدن تعداد کاربران، شرایط کمکم تغییر میکند.
هر بار که شخصی صفحه محصولات را باز میکند، Django باید دوباره به Database مراجعه کند:
User Request
|
v
Django
|
v
PostgreSQL
|
v
Responseحالا یک سؤال مهم داریم:
اگر لیست محصولات از درخواست قبلی تا درخواست فعلی هیچ تغییری نکرده است، چرا باید دوباره همان Query را اجرا کنیم؟
اینجا یکی از مهمترین کاربردهای Redis خودش را نشان میدهد.
میتوانیم اطلاعاتی را که زیاد خوانده میشوند و مرتب تغییر نمیکنند، برای مدت مشخصی در Redis نگه داریم.
در اولین درخواست:
Django -> PostgreSQL -> Redisاما در درخواستهای بعدی:
Django -> Redis -> Responseتا زمانی که اطلاعات Cache معتبر باشند، دیگر لازم نیست همان Query دوباره روی PostgreSQL اجرا شود.
البته Redis فقط برای Cache نیست. در پروژههای Django میتوانیم از آن برای Session، کدهای OTP، Rate Limiting، Celery و بسیاری از دادههای موقت دیگر هم استفاده کنیم.
در این مقاله میخواهیم دقیقاً ببینیم Redis چیست، چرا به آن نیاز پیدا میکنیم و چطور آن را وارد یک پروژه Django کنیم.
در حال بارگذاری تصویر...

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 ذخیره کردهایم:
Product
----------------
id
name
price
stock
descriptionاین اطلاعات اصلی پروژه هستند و باید به شکل مطمئن و دائمی نگهداری شوند.
PostgreSQL برای این کار مناسب است.
اما تصور کنید در مدت کوتاهی صدها کاربر صفحهای را باز کنند که همان لیست محصولات را نمایش میدهد.
اگر در هر Request دوباره Query مشابهی اجرا کنیم، Database باید بارها یک کار تکراری انجام دهد.
اینجا Cache وارد میشود.
Request
|
v
Django
|
v
Redis
|
+---- اطلاعات وجود دارد؟ ---- بله ---> Response
|
خیر
|
v
PostgreSQL
|
v
Save in Redis
|
v
ResponseRedis میتواند یک لایه سریع در کنار Database ایجاد کند و تعداد Queryهای تکراری را کاهش دهد.
Redis چه کاربردهایی در Django دارد؟
قبل از اینکه Redis را اجرا کنیم، چند مثال واقعی ببینیم.
Cache کردن لیست محصولات
فرض کنید مسیر زیر را داریم:
GET /products/و هر بار که این صفحه باز میشود، لیست محصولات از Database خوانده میشود.
اگر اطلاعات محصولات هر چند ثانیه تغییر نمیکنند، میتوانیم نتیجه را مثلاً برای ۵ دقیقه Cache کنیم.
در اولین Request:
Django -> PostgreSQL -> Redisدر Requestهای بعدی:
Django -> Redisاین یکی از رایجترین کاربردهای Redis است.
ذخیره OTP
فرض کنید کاربر برای ورود به سایت یک کد ششرقمی دریافت میکند:
482931این کد فقط دو دقیقه اعتبار دارد.
در چنین شرایطی معمولاً نمیخواهیم یک رکورد دائمی در Database اصلی ایجاد کنیم.
میتوانیم چیزی شبیه این در Redis داشته باشیم:
otp:0912xxxxxxx = 482931
TTL = 120 secondsبعد از پایان زمان اعتبار، کد منقضی میشود.
Rate Limiting
فرض کنید کاربر فقط اجازه دارد در یک دقیقه پنج بار تلاش کند وارد حسابش شود.
Redis میتواند یک Counter کوتاهمدت نگه دارد:
login_attempt:user123 = 3و بعد از مدت مشخصی آن Counter منقضی شود.
Celery
در پروژههای واقعی بعضی عملیات بهتر است داخل Request اصلی انجام نشوند.
مثلاً:
- ارسال ایمیل
- ارسال پیامک
- پردازش فایل
- پردازش تصویر
- ساخت گزارش
- اجرای کارهای زمانبر
یکی از ابزارهای معروف برای اجرای چنین کارهایی در پروژههای Django، Celery است.
Celery یک Task Queue است.
Django یک Task ایجاد میکند و Celery Worker آن Task را جدا از Request کاربر اجرا میکند.
Redis میتواند بین Django و Celery نقش Message Broker را داشته باشد.
Django
|
v
Redis
|
v
Celery Workerکمی جلوتر دوباره به Celery برمیگردیم.
در حال بارگذاری تصویر...

اجرای Redis برای پروژه Django
برای استفاده از Redis ابتدا باید یک Redis Server اجرا کنیم.
روشهای مختلفی برای این کار وجود دارد، اما در این مقاله از Docker استفاده میکنیم.
Docker چیست؟
Docker ابزاری است که کمک میکند نرمافزارهایی مثل Redis، PostgreSQL یا حتی خود Django را داخل محیطهایی ایزوله به نام Container اجرا کنیم.
برای ادامه این مقاله لازم نیست Docker را حرفهای بلد باشید.
ما فقط Redis را با یک دستور اجرا میکنیم و Django همچنان مثل قبل روی سیستم خودتان اجرا خواهد شد.
اگر با Django کار میکنید، پیشنهاد میکنیم بعداً حتماً Docker را هم یاد بگیرید؛ چون در پروژههای واقعی و زمان Deploy بسیار کاربردی است.
ساختار مثال این مقاله به شکل زیر است:
Your Computer
Django
localhost:8000
|
v
Redis Docker Container
localhost:6379یعنی:
فقط Redis داخل Docker است.
Django همچنان بهصورت Local روی سیستم اجرا میشود.
در حال بارگذاری تصویر...

اجرای Redis با Docker
بعد از نصب Docker یا Docker Desktop، ترمینال را باز کنید و دستور زیر را اجرا کنید:
docker run --name codingyar-redis -p 6379:6379 -d redis:8-alpine
قسمت:
--name codingyar-redis
نام Container را مشخص میکند.
قسمت:
-p 6379:6379
پورت Redis داخل Container را روی پورت 6379 سیستم شما در دسترس قرار میدهد.
و:
redis:8-alpineایمیجی است که Redis با استفاده از آن اجرا میشود.
چطور بفهمیم Redis اجرا شده است؟
ابتدا دستور زیر را اجرا کنید:
docker ps
باید Containerای با نام:
codingyar-redisببینید.
حالا Redis CLI را داخل همان Container اجرا کنید:
docker exec -it codingyar-redis redis-cli
بعد دستور زیر را وارد کنید:
PINGاگر همهچیز درست باشد، Redis پاسخ میدهد:
PONGهمین PONG یعنی Redis اجرا شده و آماده دریافت درخواست است.
برای خروج از Redis CLI بنویسید:
exitاتصال Django به Redis
حالا Redis آماده است.
در پروژه Django ابتدا Python Client مربوط به Redis را نصب میکنیم:
pip install redis
در نسخههای جدید Django برای Cache ساده نیازی نیست حتماً django-redis نصب کنیم؛ Django خودش Redis Cache Backend دارد.
داخل settings.py تنظیم زیر را اضافه کنید:
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.redis.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
}
}قسمت مهم تنظیمات:
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 را باز کنید:
python manage.py shell
سپس:
from django.core.cache import cache
cache.set("name", "CodingYar", timeout=60)
cache.get("name")خروجی باید چیزی شبیه این باشد:
'CodingYar'یعنی Django مقدار را داخل Cache ذخیره کرده و دوباره از Redis خوانده است.
Cache کردن لیست محصولات در Django
حالا برویم سراغ مثال واقعی.
فرض کنید View فعلی محصولات به این شکل است:
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 را اضافه کنیم.
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,
},
)در ابتدا:
products = cache.get("products")از Cache میپرسیم آیا اطلاعات محصولات وجود دارد یا نه.
اگر وجود نداشته باشد:
if products is None:اطلاعات را از Database میخوانیم:
products = list(
Product.objects.values(
"id",
"name",
"price",
)
)و بعد آن را برای ۳۰۰ ثانیه یا ۵ دقیقه Cache میکنیم:
cache.set(
"products",
products,
timeout=300,
)از این به بعد، تا زمانی که Cache منقضی نشده باشد، Requestهای بعدی میتوانند اطلاعات را از Redis دریافت کنند.
چرا if not products ننوشتیم؟
ممکن است کدی شبیه این بنویسید:
if not products:اما فرض کنید لیست محصولات واقعاً خالی باشد:
[]این مقدار ممکن است بهدرستی داخل Cache ذخیره شده باشد، اما شرط if not products آن را False در نظر میگیرد و دوباره Query اجرا میشود.
برای همین بهتر است بنویسیم:
if products is None:تا فقط نبودن مقدار در Cache را تشخیص دهیم.
در حال بارگذاری تصویر...

Cache Hit و Cache Miss چیست؟
وقتی اطلاعاتی را از Cache درخواست میکنیم، دو حالت اصلی داریم.
اگر اطلاعات وجود داشته باشند:
Cache Hit
اتفاق افتاده است.
Django -> Redis -> Dataاما اگر اطلاعات وجود نداشته باشند:
Cache Miss
داریم.
Django -> Redis -> Not Found
|
v
PostgreSQLدر Cache Miss معمولاً اطلاعات را از Database دریافت میکنیم و برای Requestهای بعدی داخل Cache ذخیره میکنیم.
Cache Invalidation؛ وقتی اطلاعات Cache قدیمی میشوند
Cache یک مسئله مهم دارد.
فرض کنید لیست محصولات را برای ۵ دقیقه Cache کردهایم.
بعد از یک دقیقه مدیر سایت قیمت یک محصول را تغییر میدهد.
Database بهروز شده، اما Redis هنوز نسخه قبلی اطلاعات را دارد.
در نتیجه ممکن است کاربر اطلاعات قدیمی دریافت کند.
به این وضعیت Stale Cache میگوییم.
یکی از راههای ساده این است که بعد از تغییر اطلاعات، Cache مربوطه را حذف کنیم:
from django.core.cache import cache
cache.delete("products")در Request بعدی، اطلاعات جدید از Database خوانده و دوباره Cache میشوند.
در پروژههای بزرگتر، Cache Invalidation خودش یکی از موضوعات مهم طراحی سیستم است.
در حال بارگذاری تصویر...

مشاهده Keyهای Redis
برای بررسی اطلاعات داخل Redis دوباره Redis CLI را اجرا کنید:
docker exec -it codingyar-redis redis-cli
چون در تنظیمات Django از Database شماره 1 استفاده کردیم:
SELECT 1حالا میتوانیم Keyها را بررسی کنیم:
SCAN 0یا برای پیدا کردن Key محصولات:
SCAN 0 MATCH "*products*"ممکن است Key نهایی چیزی شبیه این باشد:
:1:productsDjango ممکن است Prefix و Version را هم به نام Key اضافه کند.
در محیطهای کوچک توسعه احتمالاً دستور زیر را هم دیدهاید:
KEYS *اما برای Redisهای بزرگتر بهتر است بهجای KEYS از SCAN استفاده کنیم.
آیا Redis همیشه پروژه را سریعتر میکند؟
Redis معمولاً میتواند زمان بعضی عملیات تکراری را کاهش دهد، اما نباید انتظار داشته باشیم فقط با اضافه کردن Redis تمام بخشهای پروژه ناگهان سریع شوند.
سرعت واقعی به عوامل مختلفی بستگی دارد:
- نوع Query
- تعداد رکوردها
- Indexهای Database
- حجم داده Cache شده
- شبکه
- سختافزار
- تعداد کاربران
- معماری پروژه
به همین دلیل نباید اعدادی مثل این را بهعنوان یک قانون در نظر بگیریم:
Database = 300ms
Redis = 5msممکن است در یک پروژه اختلاف بسیار بیشتر باشد و در پروژه دیگر کمتر.
اصل مهم این است:
اول Bottleneck را پیدا کنید، بعد Cache اضافه کنید.
Cache باید یک Optimization هدفمند باشد، نه چیزی که بدون دلیل به تمام Viewهای پروژه اضافه شود.
ذخیره OTP در Redis
یکی دیگر از کاربردهای خوب Redis، اطلاعات کوتاهعمر است.
فرض کنید میخواهیم برای کاربر یک OTP ششرقمی ایجاد کنیم.
برای تولید کد تصادفی میتوانیم از secrets استفاده کنیم:
import secrets
otp = f"{secrets.randbelow(1_000_000):06d}"حالا کد را برای ۱۲۰ ثانیه در Cache ذخیره میکنیم:
from django.core.cache import cache
phone = "09121234567"
otp = "482931"
cache.set(
f"otp:{phone}",
otp,
timeout=120,
)برای خواندن کد:
saved_otp = cache.get(
f"otp:{phone}"
)بعد از دو دقیقه، این مقدار دیگر معتبر نخواهد بود.
در پروژه واقعی بهتر است OTP را Plain Text نگهداری نکنیم.
برای نمونه میتوانیم Hash آن را ذخیره کنیم:
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,
)و هنگام اعتبارسنجی:
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، تعداد تلاش برای وارد کردن کد و موارد امنیتی دیگر را هم در نظر بگیرید.
در حال بارگذاری تصویر...

استفاده از Redis برای Session
یکی دیگر از کاربردهای Redis، Session Storage است.
فرض کنید پروژه شما چند Django Server دارد:
Django Server 1
Django Server 2
Django Server 3اگر اطلاعات Session فقط داخل Memory هر Server قرار بگیرند، مدیریت Session مشترک بین Serverها مشکل میشود.
Redis میتواند نقش Storage مرکزی را داشته باشد:
Redis
/ | \
/ | \
v v v
Django Django Djangoدر این حالت تمام Serverها میتوانند اطلاعات Session را از یک محل مشترک دریافت کنند.
در حال بارگذاری تصویر...

Rate Limiting با Redis
Redis برای نگهداری Counterهای کوتاهمدت هم مناسب است.
فرض کنید میخواهیم این قانون را اجرا کنیم:
حداکثر ۵ تلاش برای ورود در ۶۰ ثانیهمیتوانیم Counterای مثل این داشته باشیم:
login_attempt:user123 = 3هر بار که کاربر تلاش میکند وارد شود، مقدار Counter افزایش پیدا میکند.
همزمان یک زمان انقضا هم برای آن تعریف میکنیم.
از همین الگو میتوان برای محدود کردن درخواست OTP، Login، API و بسیاری از Endpointهای دیگر استفاده کرد.
در حال بارگذاری تصویر...

Redis و Celery
حالا به یکی از مهمترین کاربردهای Redis در پروژههای بزرگتر Django میرسیم.
فرض کنید بعد از ثبتنام کاربر میخواهیم ایمیل خوشآمدگویی ارسال کنیم.
اگر ارسال ایمیل داخل Request اصلی انجام شود، ممکن است کاربر مجبور شود چند ثانیه منتظر بماند.
Celery کمک میکند کار را به Background منتقل کنیم.
ایده ساده است:
Django به جای اینکه خودش عملیات را انجام دهد، یک Task ایجاد میکند.
Task وارد یک Queue میشود.
Celery Worker آن را دریافت و اجرا میکند.
User
|
v
Django
|
v
Redis
|
v
Celery Worker
|
v
Send EmailRedis در این معماری میتواند نقش Message Broker را داشته باشد.
برای مثال تنظیم اولیه Celery ممکن است چیزی شبیه این باشد:
CELERY_BROKER_URL = "redis://127.0.0.1:6379/2"و اگر بخواهیم Result Taskها هم داخل Redis نگهداری شوند:
CELERY_RESULT_BACKEND = "redis://127.0.0.1:6379/3"برای نصب Celery همراه پشتیبانی Redis:
pip install "celery[redis]"
البته Redis تنها Broker قابل استفاده برای Celery نیست و گزینههایی مثل RabbitMQ هم وجود دارند.
Celery خودش موضوع بزرگی است و بهتر است در یک مقاله جداگانه آن را کامل بررسی کنیم.
در حال بارگذاری تصویر...

Redis در برابر Local Memory Cache
ممکن است بپرسید چرا از یک Dictionary ساده در Python استفاده نکنیم؟
مثلاً:
cache = {}در یک Process ساده شاید کار کند.
اما فرض کنید دو Django Server داریم:
Server 1
Cache A
Server 2
Cache Bهر Server حافظه خودش را دارد.
در نتیجه Cacheها با هم مشترک نیستند.
اما Redis میتواند یک Cache مرکزی ایجاد کند که همه Serverها از آن استفاده کنند.
در حال بارگذاری تصویر...

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 رابطهای پروژه استفاده شود.
در حال بارگذاری تصویر...

چه زمانی نباید از Redis استفاده کنیم؟
Redis ابزار قدرتمندی است، اما قرار نیست به هر پروژهای اضافه شود.
اگر پروژه کوچک است و مشکل Performance مشخصی ندارید، شاید هنوز نیازی به Cache خارجی نداشته باشید.
همچنین:
- هر Query را Cache نکنید.
- اطلاعاتی که دائماً تغییر میکنند را بدون طراحی مناسب Cache نکنید.
- Cache Invalidation را فراموش نکنید.
- Redis را بدون تنظیمات امنیتی مناسب مستقیماً روی اینترنت قرار ندهید.
- Cache را Source of Truth اطلاعات حیاتی در نظر نگیرید.
یک قانون ساده:
اول مشکل را پیدا کنید، بعد Redis را بهعنوان راهحل وارد کنید.
اگر Docker را بهتر بلد باشیم چه؟
در این مقاله عمداً فقط Redis را داخل Docker اجرا کردیم:
Django Local
|
v
Redis Containerدلیل این کار این بود که اگر Docker را بلد نباشید، همچنان بتوانید آموزش Redis را دنبال کنید.
اما در پروژههای واقعیتر معمولاً ممکن است کل Stack را با Docker Compose اجرا کنیم:
Django
PostgreSQL
Redis
Celeryنمونه ساده:
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 این بود:
redis://127.0.0.1:6379/1اما وقتی Django هم داخل Docker Compose قرار بگیرد، سرویسها میتوانند با نام یکدیگر ارتباط برقرار کنند.
در نتیجه آدرس Redis میتواند به شکل زیر باشد:
redis://redis:6379/1و برای Celery:
CELERY_BROKER_URL = "redis://redis:6379/2"این ساختار موضوع اصلی مقاله فعلی نیست، اما اگر قصد دارید Django را حرفهای ادامه دهید، یادگیری Docker و Docker Compose قدم مهمی در ادامه مسیر است.
در حال بارگذاری تصویر...

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
در حال بارگذاری تصویر...

جمعبندی
تا قبل از Redis، معماری ساده پروژه ما تقریباً به این شکل بود:
Django -> PostgreSQLحالا یک ابزار جدید به معماری اضافه شده است:
Django
|
+----> PostgreSQL
|
+----> RedisPostgreSQL همچنان Database اصلی پروژه است.
Redis در کنار آن میتواند مسئولیتهایی مثل Cache، OTP، Session، Rate Limiting و دادههای موقت را برعهده بگیرد.
وقتی Celery را هم وارد پروژه کنیم، معماری میتواند به این شکل برسد:
Django
|
+----> PostgreSQL
|
+----> Redis <----> Celery Workerمهمترین نکته این مقاله این است:
Redis جای Database اصلی نیست؛ Redis ابزاری مکمل برای حل بعضی مشکلات مشخص در معماری برنامه است.
اگر دادهای:
- زیاد خوانده میشود،
- موقت است،
- نیاز به TTL دارد،
- Counter است،
- باید سریع در دسترس باشد،
- یا در Queue پردازش میشود،
Redis میتواند انتخاب بسیار مناسبی باشد.
مسیر ادامه یادگیری
بعد از این مقاله میتوانید سراغ موضوعات زیر بروید:
- آموزش Celery در Django
- اجرای Taskهای Background با Redis و Celery
- Cache کردن Viewها و Queryها در Django
- Cache Invalidation در پروژههای واقعی
- Rate Limiting با Redis
- Session در Redis
- بهینهسازی Performance در Django
- Redis در محیط Production
- Docker و Docker Compose برای پروژههای Django
سوالات متداول
آیا برای استفاده از Redis در Django حتماً باید Docker بلد باشیم؟
خیر.
Redis را میتوان به روشهای دیگری هم نصب کرد.
در این مقاله از Docker استفاده کردیم چون با یک دستور میتوان Redis را اجرا کرد و لازم نیست نصب مستقیم آن روی سیستم را انجام دهید.
برای دنبال کردن این مقاله فقط چند دستور ساده Docker کافی است.
با این حال اگر قصد دارید Django را به شکل حرفهای ادامه دهید، یادگیری Docker بسیار پیشنهاد میشود.
آیا برای Redis حتماً باید django-redis نصب کنیم؟
خیر.
برای Cache ساده در نسخههای جدید Django میتوانیم از Backend داخلی Redis استفاده کنیم:
django.core.cache.backends.redis.RedisCacheو Python Client مربوط به Redis را نصب کنیم:
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 چه مدت معتبر باشد.
مثلاً:
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 باشد.















