PDA

View Full Version : زمانبدی برای به روز رسانی



pswin.pooya
یک شنبه 08 دی 1392, 10:42 صبح
سلام

دوستان چه شکلی میتونم یه زمانبند درست کنم که مثلا هر 5 دقیقه یک اسکریپت خاص رو اجرا کنه؟

مشکل من اینه که توی دیتابیس بعد از اینکه مشتری خرید کرد اون کالا به مدت ۱۰ دقیقه رزو میشه تا اینکه مشتری از درگاه بانک اون رو پرداخت کنه. حالا اگر مشتری به هر دلیلی درگاه رو ببنده. و از درگاه بازگشت نشه اون کالا توی حالت روزو باقی میمونه.

ایده اولی که به ذهنم رسید این بود که توی هربار چک مشتری برای اون کالا زمان سفارش چک بشه اگر برای یشتر از ۱۰ دقیقه بود. اون کالا با به update از حالت روزو خارج بشه. اما کم کم با اضافه شدن رکورد ها. این کوپری update هی داره سنگین تر میشه. حالا میخوام یه زمانبند داشته باشم که هر ۵ دقیقه یکبار این چک آپ رو انجام بده.

دوستان راه دیگه هم به نظرتون میرسه؟

eshpilen
یک شنبه 08 دی 1392, 11:00 صبح
پسر تو هنوز دچار وسواس در بهینه سازی هستی؟ :لبخند:

بهرحال میتونی از cron استفاده کنی.
ولی من خودم ترجیح میدم از روشهای مستقل تری که نیاز به امکانات برونی و setup دستی ندارن استفاده کنم.


توی هربار چک مشتری برای اون کالا زمان سفارش چک بشه اگر برای یشتر از ۱۰ دقیقه بود. اون کالا با به update از حالت روزو خارج بشه. اما کم کم با اضافه شدن رکورد ها. این کوپری update هی داره سنگین تر میشه. دقیقا متوجه نشدم چی گفتی، اما من خودم از یک کد cleanup در جدولهای پروژم استفاده کردم.
این کد cleanup بصورت رندوم در هر چند درخواست، با میزان احتمال خاصی که قابل تنظیم هست، اجرا میشه و رکوردهای اکسپایر شده رو از جدول پاک میکنه. مثلا اگر احتمال اجرای کد cleanup یک بر 10 باشه، بطور متوسط در هر 10 درخواست (یا درواقع درخواستهایی که در جدول مورد نظر کوئری درج میکنن) یک بار این کد cleanup اجرا میشه.

این نمونهء ساده شده ای از یکی از این کدها:


if(mt_rand(1, floor(1/$cleanup_probability))==1) require $index_dir.'include/code/cleanup/cleanup/code_account_block_log_expired_cleanup.php';

و محتویات code_account_block_log_expired_cleanup.php:


$expired=$req_time-$account_block_period;

if($keep_expired_block_log_records_for!=-1) $expired-=$keep_expired_block_log_records_for;

$query="delete from `account_block_log` where `first_attempt` < $expired";

$reg8log_db->query($query);

شما باید اون کد اجرای رندوم رو در درخواستها و بخشهایی بذاری که خودشون رکوردی رو در اون جدول درج میکنن. اینطوری یک تعادلی بین رکوردهای درج شده و رکوردهای اکسپایر شده ایجاد میشه، نه اینکه همینطوری الکی و زیادی این چک و حذف رکوردهای اکسپایر شده بخواد صورت بگیره یا اینکه کمتر از میزان بهینه صورت بگیره.

ضمنا اگر میترسی که تعداد رکوردهای درگیر خیلی زیاد باشه و این کار روی پرفورمنس تاثیر بذاره، مثلا از هر 10 تا درخواست یکیش به علت اجرا شدن کدهای cleanup به طرز مشهودی کند بشه، میتونی اجرای کدهای cleanup رو در پایان اسکریپت بذاری و وقتی که تمام کارهای درخواست جاری اجرا شدن و خروجی ها به مرورگر کاربر ارسال شدن (میتونی با خالی کردن کش خروجی و یکسری ترفندهای وابسته، از نمایش خروجی در مرورگر کاربر هم مطمئن بشی).
ولی بطور کلی مشکل خاصی نباید باشه. DBMS رو دست کم نگیره! اگر درست جدول طراحی بشه و روی فیلدهای معیار جستجو ایندکس و این حرفا باشه نباید مشکل خاصی پیش بیاد مگر در شرایط خاص و موقعی که ترافیک خیلی سنگین باشه و/یا تعداد رکوردها خیلی زیاد باشه (نمیدونم مثلا شاید بیش از چند میلیون).

abolfazl-z
یک شنبه 08 دی 1392, 11:02 صبح
از گفته هاتون معلومه که از هر کالا یکی بیشتر وجود ندارد !

ولی فکر نکنم کوئری سنگین بشه ها ؟

به نظر من یک بار آپدیت بشه بهتره اینکه هر 5 دقیقه چک بشه !

ممکن یک محصولتون اصلا فروش نرورد ! اون وقت چی برای این هم باید query بگیرید و سنگین میشه دیگه.

pswin.pooya
یک شنبه 08 دی 1392, 12:14 عصر
از گفته هاتون معلومه که از هر کالا یکی بیشتر وجود ندارد !
دقیقا این شکلیه


به نظر من یک بار آپدیت بشه بهتره اینکه هر 5 دقیقه چک بشه !
من که با یکبار آپدیت موافقم. اما مساله اینه که اگر هربار که یوزر میخواد صفحه رو ببینه یه آپدیت برای مطمئن شدن صورت بگیره. که اوضاء سایت بهم میریزه. یعنی کلی رکورد بیخودی باید سرچ بشن.

من برای هر محصول یک فیلد وضعیت گذاشتم. که نشون میده فروش رفته یا روزو شده یا اینکه در دسترس است؟. حالا یه چیزی حدود ۷۰ هزار رکورد دارم. این تازه هفته اول کاره. فکر کنم تا عید چند برابر شه. نگرانی من اینه که خیلی زود DBMS کم میاره. برای همین تصمیم دارم اینکار رو هر پنج دقیقه یا ۱۰ دقیقه یکبار انجام بدم.


ممکن یک محصولتون اصلا فروش نرورد ! اون وقت چی برای این هم باید query بگیرید و سنگین میشه دیگه.
اولش این ذهنیت رو داشتم که محصولات فروش رفته رو بیارم تو یه جدول جدا. اما از اونجا که کاربر باید محصولات فروش رفته رو هم میدید. باعث میشد که تعداد joinها زیاد بشن و ... . پس دیدم بهتره تو یه جدول بمونن. فقط یه فلگ برای وضعیت اونها بذارم. این محصولها بعد یکسال کلا از جدول حذف میشن.

arta.nasiri
یک شنبه 08 دی 1392, 14:21 عصر
من که با یکبار آپدیت موافقم. اما مساله اینه که اگر هربار که یوزر میخواد صفحه رو ببینه یه آپدیت برای مطمئن شدن صورت بگیره. که اوضاء سایت بهم میریزه. یعنی کلی رکورد بیخودی باید سرچ بشن.


چرا از Flag استفاده نمیکنید؟ مثلا میتونید وقتی محصولی lock شد Flag رو True کنید ( تو یک جدول جداگانه ) و یک time براش در نظر بگیرید به این صورت که اگر اختلاف تایم الان با تایم Flag بیشتر از 10 دقیقه بود فقط رکورد مربوط به محصول رو آپدیت کنید سپس Flag رو حذف کنید. اینجوری دیگه مجبور نیستید با هر بار مراجعه کاربر چند هزار تا رکورد رو بررسی کنید!!

fcsooti
یک شنبه 08 دی 1392, 14:37 عصر
چرا از Flag استفاده نمیکنید؟ مثلا میتونید وقتی محصولی lock شد Flag رو True کنید ( تو یک جدول جداگانه ) و یک time براش در نظر بگیرید به این صورت که اگر اختلاف تایم الان با تایم Flag بیشتر از 10 دقیقه بود فقط رکورد مربوط به محصول رو آپدیت کنید سپس Flag رو حذف کنید. اینجوری دیگه مجبور نیستید با هر بار مراجعه کاربر چند هزار تا رکورد رو بررسی کنید!!
یا اینکه به جای یک فیلد وضعیت برای نشان دادن رزرو شدن یا نشدن یک فیلد اضافه بشه و تایمی که تا اون موقع محصول رزرو هست رو نگه داره و با یک کوئری مثل این محصولاتی که رزرو نیستن رو بکشه بیرون
SELECT * FROM `products` WHERE `reserve_time` < "'.(time()-600).'";

MMSHFE
یک شنبه 08 دی 1392, 14:38 عصر
چرا از Triggerهای خود MySQL استفاده نمیکنید؟ بگین وقتی رکوردی توی جدول Reserve درج شد، بعد از 10 دقیقه خودش Delete کنه. تو این فاصله هم اگه کالا واقعاً خریداری شد، خودتون از جدول حذف کنید.

abolfazl-z
یک شنبه 08 دی 1392, 22:31 عصر
چرا از Triggerهای خود MySQL استفاده نمیکنید؟ بگین وقتی رکوردی توی جدول Reserve درج شد، بعد از 10 دقیقه خودش Delete کنه. تو این فاصله هم اگه کالا واقعاً خریداری شد، خودتون از جدول حذف کنید.

این روش خیلی میتونه کمک کند.

ولی دیگه ایشون دارن میگن حجم داده هاشون میره بالا. خوب دیگه اینجا هر کوئری بخواهی بگیری به سرور فشار میاد در نتیجه باید سرور ارتقا پیدا کند.

یک Database Server داشته باشید که مخصوص mysql باشد خیلی عالی میشه.

قبلا از انتخاب سرور DB SV حتما به سایت ذیل یک سر بزن :
http://mysqldump.azundris.com/archives/98-How-large-can-a-MySQL-database-become.html

pswin.pooya
یک شنبه 08 دی 1392, 22:49 عصر
دوستان الان هیچ تغییری توی دیتابیس نمی تونم بدم. فعلا راهی هست که من زمانیدی کنم؟. مثلا هر پنیج دقیقه یکبار یک اسکریپت خواص اجرا بشه؟

engmmrj
یک شنبه 08 دی 1392, 23:14 عصر
با cron jobs میشه ، مثلا میگی این اسکریپت را هر پنج دقیقه اجرا کن !

pswin.pooya
سه شنبه 10 دی 1392, 01:44 صبح
با cron jobs میشه ، مثلا میگی این اسکریپت را هر پنج دقیقه اجرا کن !

دقیقا آخرش با همین حلش کردم. لازمه کد زیر رو بدید بهش:


wget http://www.domin.com/test.php