سشن یه جای خیلی وسوسهکنندهست؛ چون هر چیزی رو میشه موقتاً گذاشت توش و بعد توی Request بعدی دوباره تحویل گرفت. سبد خرید؟ بذار تو Session. فیلترهای کاربر؟ Session. اطلاعات فرم چندمرحلهای؟ Session. حتی بعضی پروژهها میرن سراغ ذخیره یه عالمه داده موقت و تنظیمات مختلف کاربر داخل همون سشن و کمکم چیزی که قرار بود یه فضای سبک و موقتی باشه، تبدیل میشه به انباری کل پروژه!
مشکل اینجاست که Session جادو نیست. دادهای که داخلش ذخیره میکنید بالاخره باید یه جایی نگهداری بشه و هر بار هم ممکنه لازم باشه خونده، نوشته یا Serialize بشه. اگه حجم Sessionها زیاد بشه، بسته به Backendای که استفاده میکنید میتونه فشار مستقیم روی دیتابیس، Cache یا حتی Cookie کاربر ایجاد کنه.
Session در Django اصلاً کجا ذخیره میشه؟
Django چند روش مختلف برای ذخیره Session داره و رفتار هرکدوم کمی متفاوته. یکی از رایجترین حالتها Database-backed Session هست؛ یعنی داده Session داخل جدول مربوط به Sessionها در دیتابیس ذخیره میشه و مرورگر فقط یه Session ID دریافت میکنه.
در این حالت اگه برای هزاران کاربر Sessionهای بزرگ بسازید، جدول Session میتونه رشد کنه و هر Request هم ممکنه باعث خوندن یا نوشتن اطلاعات بیشتری از دیتابیس بشه.
روش دیگه استفاده از Cache مثل Redis هست که معمولاً سریعتره، ولی اونجا هم حافظه بینهایت ندارید. اگه برای هر کاربر چند صد کیلوبایت اطلاعات نگهداری کنید و تعداد کاربران زیاد بشه، خیلی راحت چند گیگابایت RAM فقط صرف Session میشه.
اشتباه رایج: ریختن همهچیز داخل Session
فرض کنید کاربر وارد فروشگاه شده و ما کل اطلاعات محصول رو داخل Session ذخیره میکنیم:
request.session["cart"] = {
"product_id": product.id,
"title": product.title,
"description": product.description,
"price": product.price,
"images": product.images,
"category": product.category.name,
}
در نگاه اول کار میکنه، ولی بیشتر این اطلاعات اصلاً لازم نیست داخل Session باشن. عنوان محصول، توضیحات، تصاویر و دستهبندی همین الان داخل دیتابیس وجود دارن و میشه هر وقت لازم شد از اونجا دریافتشون کرد.
معمولاً بهتره Session فقط اطلاعات ضروری رو نگه داره، مثلاً شناسه محصول و تعداد:
request.session["cart"] = {
"product_id": product.id,
"quantity": 2
}
اینطوری Session خیلی سبکتر میمونه و اطلاعات اصلی هم از منبع واقعی خودش یعنی دیتابیس دریافت میشه.
Session نباید نسخه دوم دیتابیس باشه
یه قانون خوب اینه که Session رو جای ذخیره اطلاعات اصلی پروژه در نظر نگیرید. Session بیشتر برای State موقت کاربر مناسبه؛ چیزهایی که بین چند Request لازمه یادتون بمونه ولی قرار نیست منبع دائمی اطلاعات باشه.
مثلاً شناسه سبد خرید، مرحله فعلی یه فرم چندمرحلهای یا یه تنظیم موقت میتونه انتخاب مناسبی باشه. ولی ذخیره لیست کامل سفارشها، Profile کامل کاربر یا دادههای بزرگ API داخل Session معمولاً طراحی خوبی نیست.
مشکل فقط حجم نیست. داده Session ممکنه قدیمی بشه. مثلاً قیمت محصول عوض شده ولی شما قیمت قبلی رو داخل Session نگه داشتید و همچنان دارید از همون استفاده میکنید. اینجا علاوه بر Performance، با مشکل Stale Data هم روبهرو میشید.
Cookie-based Session هم مجوز ذخیره هر چیزی نیست
Django امکان ذخیره Session داخل Cookie رو هم داره. شاید در نگاه اول خیلی جذاب باشه چون دیگه برای Session لازم نیست به دیتابیس یا Redis مراجعه کنید، ولی محدودیت مهمی وجود داره: Cookieها ظرفیت محدودی دارن و همراه Requestها بین مرورگر و سرور جابهجا میشن.
یعنی هرچقدر Cookie بزرگتر باشه، حجم Request و Response هم بیشتر میشه. تازه اطلاعات Cookie سمت کاربر قرار داره، پس باید حواستون باشه چه دادهای رو داخلش قرار میدید.
Cookie-based Session برای دادههای کمحجم مناسبه، نه اینکه یه JSON چندصد کیلوبایتی رو بندازیم توش و انتظار داشته باشیم همهچیز عالی بمونه.
Sessionهای قدیمی رو هم فراموش نکنید
یکی دیگه از مشکلاتی که ممکنه تو پروژههای قدیمی دیده بشه، جمع شدن Sessionهای منقضیشدهست. اگر از Database Session استفاده میکنید، رکوردهای قدیمی ممکنه داخل جدول باقی بمونن تا زمانی که پاکسازی بشن.
وقتی پروژه کاربر زیاد داشته باشه، این جدول میتونه حسابی بزرگ بشه. برای همین پاکسازی Sessionهای منقضیشده باید بخشی از نگهداری معمول پروژه باشه.
قرار نیست یه کاربر شش ماه پیش وارد سایت شده باشه و Session مردهش هنوز یه گوشه دیتابیس خاک بخوره!
اطلاعات حساس چی؟
Session جای مناسبی برای نگهداری Password، اطلاعات بانکی یا Secretهای حساس نیست. حتی اگه Backend Session سمت سرور باشه، بهتره فقط اطلاعاتی رو ذخیره کنید که واقعاً برای مدیریت State کاربر لازمه.
مثلاً به جای ذخیره کل اطلاعات User، معمولاً یه ID کافیه. هر وقت اطلاعات جدید لازم شد میتونید از دیتابیس دریافتش کنید و مطمئن باشید آخرین نسخه اطلاعات رو دارید.
هرچقدر داده کمتری داخل Session باشه، هم مدیریت سادهتر میشه، هم احتمال اطلاعات قدیمی یا رفتارهای عجیب کمتر میشه.
چه Backendای بهتره؟
جواب ثابت نداریم.
برای پروژههای کوچک، Database Session میتونه کاملاً کافی باشه. برای پروژههای پرترافیک، Cacheهایی مثل Redis معمولاً انتخاب سریعتری هستن. بعضی پروژهها هم از Cached Database Session استفاده میکنن تا ترکیبی از Cache و ذخیره پایدار داشته باشن.
ولی Backend هرچی باشه، یه اصل تغییر نمیکنه: Session باید سبک بمونه.
اگه هر Session فقط چند مقدار کوچک داشته باشه، تفاوت زیادی ایجاد نمیشه؛ ولی اگه هر کاربر صدها کیلوبایت یا چند مگابایت داده داشته باشه، دیر یا زود هزینهش رو توی RAM، دیتابیس یا Network میبینید.
جمع بندی
Session در Django ابزار فوقالعادهای برای نگه داشتن State موقت کاربره، ولی نباید به انبار اطلاعات پروژه تبدیل بشه. ذخیره Objectهای بزرگ، اطلاعات تکراری دیتابیس یا دادههایی که مرتب تغییر میکنن میتونه هم Sessionها رو سنگین کنه و هم باعث ایجاد اطلاعات قدیمی و رفتارهای غیرمنتظره بشه.
تا جای ممکن فقط اطلاعات ضروری مثل IDها، تعدادها یا وضعیتهای موقت رو داخل Session نگه دارید و اطلاعات اصلی رو از دیتابیس یا سرویس مربوطه دریافت کنید.
Session باید حافظه کوتاهمدت پروژه باشه، نه هارد اکسترنال!
نظرات کاربران (0)