PDA

View Full Version : سوال: آیا می شه به سیستم های مربوط به کش کوئری ها اعتماد کرد؟ (لطفا مثال رو بخونید)



idocsidocs
یک شنبه 06 شهریور 1390, 18:27 عصر
من از کلاس زیر برای کش کردن کوئری های صفحه اول سایت استفاده می کنم.
توی این کلاس و کلاسهای مشابهی که دیدم، وقتی یه کاربر درخواست می ده، این کلاس اول تست می کنه که آیا فایل کش وجود داره یا نه، اگر وجود داشت محتویات فایل رو نمایش می ده ولی اگه وجود نداشت از دیتابیس اطلاعات رو می گیره و نمایش می ده.

هر وقت اطلاعات فایل کش آپدیت می شه، اول فایل کش دلیت می شه و بعد مجددا یه فایل کش جدید ایجاد می شه.

حالا مشکل اصلی: فرض کنید چندتا کاربر بصورت همزمان برای نمایش سایت درخواست بدن و کلاس کش چک کنه و ببینه فایل وجود داره، در همین لحظه هم اطلاعات فایل آپدیت بشه و فایل کش دلیت بشه، در این صورت پی اچ پی درخواستها رو چطور رسیدگی می کنه؟

لطفا توضیح بدید.


// آدرس فولدر برای ذخیره فایل های کش
$cacheDir = dirname(__FILE__) . '/cache/';
$file = $cacheDir . 'index.html';

// یک دستور شرطی که وجود فایل را تشخیص می دهد
if (file_exists($file))
{
// خواندن محتوای فایل و نشان دادن آن در مرورگر
header("Content-Type: text/html");
readfile($file);
}
else
{
// شروع کش
ob_start();

// استخراج اطلاعاتی از دیتابیس
$query = mysql_query("select * from table ORDER BY id");
while ($row = mysql_fetch_array($query)) {
echo $row['id'].' | '.$row['content']. '<br />';
}

// ذخیره سازی اطلاعات در یک متغییر
$buffer = ob_get_contents();

// پایان ذخیره اطلاعات در کش
ob_end_flush();

// اطلاعات ذخیره شده در متغیر در یک فایل ذخیره می شود
$fp = fopen($file, "w");
fwrite($fp, $buffer);
fclose($fp);
}

A B C D
یک شنبه 06 شهریور 1390, 19:38 عصر
هر وقت اطلاعات فایل کش آپدیت می شهاطلاعات فایل کش چطوری آپدیت میشه؟
در کجا، بر چه اساسی؟


فرض کنید چندتا کاربر بصورت همزمان برای نمایش سایت درخواست بدن و کلاس کش چک کنه و ببینه فایل وجود داره، در همین لحظه هم اطلاعات فایل آپدیت بشه و فایل کش دلیت بشه، در این صورت پی اچ پی درخواستها رو چطور رسیدگی می کنه؟داری راه میفتیا!

خب... میتونیم از یک فایل واسطه دیگه بعنوان قفل استفاده کنیم. فایل قفل میتونه همنام فایل کش باشه با یک پسوند lock. بطور مثال index.html.lock

برنامه ای که میخواد فایل کش رو آپدیت کنه باید قبل از انجام عملیات خود، فایل واسطه رو قفل کنه (قفل انحصاری) و بعد از اینکه فایل کش رو مجددا ایجاد کرد، قفل رو آزاد کنه.

برنامه ای که میخواد فایل کش رو بخونه باید قبل از انجام عملیات خودش (قبل از file_exists) فایل واسطه رو قفل کنه (قفل اشتراکی) و بعد از انجام عملیات خودش (خواندن تمام محتوای فایل کش) قفل رو آزاد کنه.

--------------------------------------------------

ضمنا این برنامهء شما که نمونه کدش رو گذاشتید، موقعی که میخواد اطلاعات واکشی شده از دیتابیس رو در فایل کش ذخیره کنه هم نیاز داره فایل واسطه رو قفل کنه (در این هنگام قفل انحصاری).

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

راستی این کد رو خودت نوشتی؟

idocsidocs
یک شنبه 06 شهریور 1390, 23:12 عصر
راستی این کد رو خودت نوشتی؟
1- نه ولی اسکریپت ساده ای هست و چیز خاصی نداره. 2- در مورد نحوه پاک شدن و آپدیت شدن فایل کش باید بگم که وقتی مدیران سایت از طریق کنترل پنل یه مطلب اضافه کنن، فایل کش قبلی باید حذف بشه. 3- فرض کنید 100 نفرمی خوان به سایت دسترسی داشته باشن، با تابع file_exist چک کنن و ببینن که فایل وجود داره، در همین لحظه کش آپدیت بشه و فایل کش حذف بشه، در این صورت فایل حذف شده و اسکریپت این صد نفر بهشون گفته که فایل وجود داره ! درنتیجه در ادامه اجرای اسکریپت، اسکریپت برای دریافت فایل درخواست می ده ولی فایل حذف شده ! حالا چه از فایل قفل شده میانی استفاده بکنیم یا استفاده نکنیم. برای این مواقع چه باید کرد؟

A B C D
دوشنبه 07 شهریور 1390, 08:44 صبح
فرض کنید 100 نفرمی خوان به سایت دسترسی داشته باشن، با تابع file_exist چک کنن و ببینن که فایل وجود داره، در همین لحظه کش آپدیت بشه و فایل کش حذف بشه، در این صورت فایل حذف شده و اسکریپت این صد نفر بهشون گفته که فایل وجود داره ! درنتیجه در ادامه اجرای اسکریپت، اسکریپت برای دریافت فایل درخواست می ده ولی فایل حذف شده ! حالا چه از فایل قفل شده میانی استفاده بکنیم یا استفاده نکنیم. برای این مواقع چه باید کرد؟ روش قفلی که گفتم واسه چی بود پس؟!!
اون روش جلوی چنین حالتی رو میگیره.
تا وقتی درخواست اون 100 نفر حتی یکیشون درحال اجرا هست، فایل واسطه قفله و برنامهء ادمین که میخواد فایل رو آپدیت/حذف کنه هم موظف است قبل از اون عملیات قفل فایل واسط رو بدست بیاره که چون قفل قبلا دست برنامهء دیگری هست، تا زمانیکه قفل آزاد بشه بلاک میشه (برنامه پشت دستور flock باقی میمونه).
زمانی هم که قفل آزاد بشه یعنی خواننده ها کارشون تموم شده و مشکلی در آپدیت یا حذف فایل وجود نداره.

-------------------

ویرایش:

البته این روش به تنهایی در بعضی شرایط ناقص محسوب میشه و مشکلی ایجاد میکنه.
اون مشکل مشکل Starvation هست درمورد عملیات Write.
فرض کن سایت ترافیک مدام سنگینی داره، بنابراین مدیر که ویرایش خودش رو سابمیت میکنه و این عملیات برای نوشتن نیاز به قفل انحصاری داره، ممکنه برای مدت زیادی یا مدت نامحدود منتظر بدست آوردن قفل انحصاری باقی بمونه. چرا؟ چون قفل خواندن از نوع قفل اشتراکی هست و هر درخواست جدیدی که که از جانب کاربران عادی میاد قفل رو میگیره، و بنابراین ممکنه همیشه درخواست یا درخواستهایی وجود داشته باشن که قفل اشتراکی رو در اختیار دارن و نوبت هیچوقت به درخواستی که نیاز به قفل انحصاری داره نرسه.
برای رفع این مشکل میشه از الگوریتم های خاص خودش استفاده کرد که چندان پیچیده هم نیستن. اما فکر نمیکنم در یه سایت با ترافیک معمولی این مشکل وجود داشته باشه. بهرحال میتونی در عمل تست کنی. و میتونی هم از اول از الگوریتم لازم جهت جلوگیری از شرایط Starvation استفاده کنی.

توضیحات در این مورد و الگوریتم های مخصوصش رو میتونی در مقالهء ویکیپدیا ببینی:
http://en.wikipedia.org/wiki/Readers-writers_problem

idocsidocs
دوشنبه 07 شهریور 1390, 11:27 صبح
روش قفلی که گفتم واسه چی بود پس؟!!
اون روش جلوی چنین حالتی رو میگیره.
تا وقتی درخواست اون 100 نفر حتی یکیشون درحال اجرا هست، فایل واسطه قفله و برنامهء ادمین که میخواد فایل رو آپدیت/حذف کنه هم موظف است قبل از اون عملیات قفل فایل واسط رو بدست بیاره که چون قفل قبلا دست برنامهء دیگری هست، تا زمانیکه قفل آزاد بشه بلاک میشه (برنامه پشت دستور flock باقی میمونه).
زمانی هم که قفل آزاد بشه یعنی خواننده ها کارشون تموم شده و مشکلی در آپدیت یا حذف فایل وجود نداره.

-------------------

ویرایش:

البته این روش به تنهایی در بعضی شرایط ناقص محسوب میشه و مشکلی ایجاد میکنه.
اون مشکل مشکل Starvation هست درمورد عملیات Write.
فرض کن سایت ترافیک مدام سنگینی داره، بنابراین مدیر که ویرایش خودش رو سابمیت میکنه و این عملیات برای نوشتن نیاز به قفل انحصاری داره، ممکنه برای مدت زیادی یا مدت نامحدود منتظر بدست آوردن قفل انحصاری باقی بمونه. چرا؟ چون قفل خواندن از نوع قفل اشتراکی هست و هر درخواست جدیدی که که از جانب کاربران عادی میاد قفل رو میگیره، و بنابراین ممکنه همیشه درخواست یا درخواستهایی وجود داشته باشن که قفل اشتراکی رو در اختیار دارن و نوبت هیچوقت به درخواستی که نیاز به قفل انحصاری داره نرسه.
برای رفع این مشکل میشه از الگوریتم های خاص خودش استفاده کرد که چندان پیچیده هم نیستن. اما فکر نمیکنم در یه سایت با ترافیک معمولی این مشکل وجود داشته باشه. بهرحال میتونی در عمل تست کنی. و میتونی هم از اول از الگوریتم لازم جهت جلوگیری از شرایط Starvation استفاده کنی.

توضیحات در این مورد و الگوریتم های مخصوصش رو میتونی در مقالهء ویکیپدیا ببینی:
http://en.wikipedia.org/wiki/Readers-writers_problem
چندتا از cms های معروف از این روش که توضیح دادید برای کش کردن استفاده می کنن؟

A B C D
دوشنبه 07 شهریور 1390, 11:46 صبح
چندتا از cms های معروف از این روش که توضیح دادید برای کش کردن استفاده می کنن؟ نمیدونم. منکه ندیدم.
شما سوال کردی منم نظر و ایدهء خودم رو گفتم. همش اورجینال اورجیناله :چشمک:

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

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

همین چند روز پیش روی مسئلهء پاکسازی ورودی HTML بحث داشتیم که یک نفر تابعی رو ارائه کرد و گفت مال یک نرم افزار CMS هست و بعد از مطالعهء کدش متوجه شدم که مثل آبکش سوراخه! این مسئله کاملا ثابت شد.

idocsidocs
دوشنبه 07 شهریور 1390, 12:37 عصر
نمیدونم. منکه ندیدم.
شما سوال کردی منم نظر و ایدهء خودم رو گفتم. همش اورجینال اورجیناله :چشمک:

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

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

همین چند روز پیش روی مسئلهء پاکسازی ورودی HTML بحث داشتیم که یک نفر تابعی رو ارائه کرد و گفت مال یک نرم افزار CMS هست و بعد از مطالعهء کدش متوجه شدم که مثل آبکش سوراخه! این مسئله کاملا ثابت شد.
تنها راهی که بنظرم می رسه اینه که کوئری هایی که باید کش بشن رو بجای فایل توی یه جدول مخصوص به کش ذخیره کنیم. اینطوری تعداد کوئری ها کمتر می شه و مشکلات دسترسی همزمان هم پیش نمی یاد.

در این مورد نظرتون چیه؟

اگر امکانش هست توی این بحث که در مورد پایین اومدن سرعت اجرای کوئری هست هم نظر بدید. (http://barnamenevis.org/showthread.php?302535-%DA%86%D8%B1%D8%A7-%D9%88%D9%82%D8%AA%DB%8C-%D8%AA%D8%B9%D8%AF%D8%A7%D8%AF-%D8%B1%DA%A9%D9%88%D8%B1%D8%AF%D9%87%D8%A7%DB%8C-%D8%AC%D8%AF%D9%88%D9%84-%D8%A8%D9%87-%D8%A8%D8%A7%D9%84%D8%A7-100-%D9%87%D8%B2%D8%A7%D8%B1-%D8%AA%D8%A7-%D9%85%DB%8C-%D8%B1%D8%B3%D9%87-%D8%B3%D8%A7%DB%8C%D8%AA%D9%85-%DA%A9%D9%86%D8%AF-%D9%85%DB%8C-%D8%B4%D9%87%D8%9F)

چند دیروز توی یکی از جدولهای دیتابیسم 150 هزارتا ردیف اضافه کردم و دیدم که کوئری ها توی 3 ثانیه انجام می شن ! اطلاعات لازم در مورد کوئری و ساختار جدول توی تاپک هست.