PDA

View Full Version : سوال: نحوه کش کردن و بازیابی خودکار کوِِئری ها توسط Memcached



shell32
چهارشنبه 27 آبان 1394, 15:16 عصر
سلام به همه برنامه نویسای خوب کشورمون.
یه مشکلی دارم در خصوص کار با ممکش.خودم کد نویسی کردم.php رو خیلی ابتدایی بلدم در حد فقط کوئری گرفتن و نمایش اطلاعات.کدی که نوشتم همش کارش با mysql هست فقط نوشتن و خواندن اطلاعات.میخوام از ممکش استفاده کنم واسه کش کردن کوئری ها چون فشار میارن به سرور.ولی نمیخوام کل کد نویسیو تغییر بدم یعنی هر جا بخوام از mysql کوئری بگیرم ممکش رو بررسی کنم اگر اطلاعات نبود بره سراغ mysql .اینطور کل برنامه باید عوض بشه.میخوام اگه بشه فقط با فعال سازی پلاگین یا تنظیم خاصی اگه هست خودکار کوئری ها کش بشن و در دفعه بعد خودکار لود بشن از کش.ضمنا سرور مجازی استفاده میکنم دستم بازه.کسی راه حلی داره؟

us1234
چهارشنبه 27 آبان 1394, 15:38 عصر
من خیلی با ممکش حال میکنم :)

در استفاده از کش باید چند نکته را همیشه توجه داشته باشید

اول اینکه کش از رم سرور استفاده می کند و زیاده روی نتیجه کامل برعکس دارد ( رم سرور پر شد میرد سراغ swap و paging که از هارد استفاده میشود و سرعت را نابود میکند ! )
دوم ممکش مثل سشن نیست ، یعنی برای هر کاربر اندکس منحصر ندارد ، وقتی شما یک چیز را داخل ممکش میذارید به هر میزان که پروسه برای php باز شود به آن اندکس اصلی دسترسی دارد .
سوم ممکش قابلیت ذخیره آرایه ندارد و فقط کلرتکس ذخیره میشود ، پس باید آرایه ها را serialize کنید .

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

نحوه new کردن کش و ساخت سرور جدید


$memcache = new Memcache();
$memcache->addServer('127.0.0.1',11211);

پورت هنگام نصب ممکش قابل تنظیم است و در فایل /etc/sysconfig/memcached قرار دارد . آی پی هم ، آی پی سروری است که ممکش روی آن قرار دارد که چون ما روی همان سرور خودمان ران کردیم آی پی لوکال میشود .

اینم یک نمونه که یک کوئری لود شده و داخل ممکش ذخیره شده ، در دفعات بعد دیگه از کوئری استفاده نمیشود و از ممکش لود میشود تا مدت زمان کش تمام شود و دوباره کوئری اجرا میشود :


$res = unserialize($memcache->get("keyname"));
if(!$res) {
$res = //mySql query ;
$memcache->set("keyname", serialize($res),MEMCACHE_COMPRESSED, "30");//30sec
}

shell32
چهارشنبه 27 آبان 1394, 16:06 عصر
با تشکر از شما.
این روشی که فرمودید باید در هر بار اجرای دستور query بازنوسی بشه کد های برنامه.درسته؟
روش دیگری هست که بشه ممکش رو سر راه connection قرار داد یعنی جایی که کانکشن ایجاد میشه از ممکش استفاده کرد که خودکار کش رو انجام بده؟

us1234
چهارشنبه 27 آبان 1394, 17:39 عصر
با تشکر از شما.
این روشی که فرمودید باید در هر بار اجرای دستور query بازنوسی بشه کد های برنامه.درسته؟
روش دیگری هست که بشه ممکش رو سر راه connection قرار داد یعنی جایی که کانکشن ایجاد میشه از ممکش استفاده کرد که خودکار کش رو انجام بده؟

برای تشکر کردن باید از کلید « تشکر کردن » که سمت راست پایین هر پست قرار دارد استفاده کنید .

نه باز نویسی نمیشه ، اگر قرار باشه که هر بار باز نویسی شود که دلیل استفاده از کش چی می تونه باشه ؟
این کوئری در مدت زمان ست شده ( که در مثلا بالا 30 ثانیه است ) از کش لود میشود .

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

shell32
چهارشنبه 27 آبان 1394, 18:02 عصر
الان در کدی که شما ارسال کردین



$res = unserialize($memcache->get("keyname")); if(!$res) { $res = //mySql query ; $memcache->set("keyname", serialize($res),MEMCACHE_COMPRESSED, "30");//30sec }

چک میشه اگر اون مقدار کلید در کش بود اونو از کش لود کنه در غیر این صورت کوئری انجام بشه و جواب کوئری به عنوان مقدار جدید وارد کش بشه.
پس اگر ما 100 دستور اجرای کوئری در برنامه داشته باشیم برای هر 100 دستور باید این روال بررسی شود یا به صورت یک تابع این عملیات انجام شود که بازم باید کل کد تغییر کند

us1234
چهارشنبه 27 آبان 1394, 19:02 عصر
الان در کدی که شما ارسال کردین



$res = unserialize($memcache->get("keyname")); if(!$res) { $res = //mySql query ; $memcache->set("keyname", serialize($res),MEMCACHE_COMPRESSED, "30");//30sec }

چک میشه اگر اون مقدار کلید در کش بود اونو از کش لود کنه در غیر این صورت کوئری انجام بشه و جواب کوئری به عنوان مقدار جدید وارد کش بشه.
پس اگر ما 100 دستور اجرای کوئری در برنامه داشته باشیم برای هر 100 دستور باید این روال بررسی شود یا به صورت یک تابع این عملیات انجام شود که بازم باید کل کد تغییر کند

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

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

shell32
چهارشنبه 27 آبان 1394, 22:34 عصر
این راه حلتون رو میشه بفرمایید شاید مشکل بنده حل بشه