¸ß²¢·¢ÏÂmemcache³¬Ê±Öظ´Ð´ÈëµÄÎÊÌâ
ÎÊÌâÃèÊö
memcached×÷Ϊ»¥ÁªÍø¾³£Ê¹ÓõĻº´æ¹¤¾ß£¬´ó´ó¼õÉÙÁËÊý¾Ý¿âµÄѹÁ¦¡£µ«Êǵ±²¢·¢¶È½Ï¸ßʱ£¬¿ÉÄÜ»áÓжà¸öÇëÇ󶼼ì²âµ½expire£¬´Ó¶ø·¢ÆðÊý¾Ý¿âÇëÇó£¬ÓÚÊÇ»á¶ÔÊý¾Ý¿âÔì³É³å»÷¡£
ÎÊÌâÖØÏÖ
µ±²ÉÓô«Í³µÄÉèÖÃexpire timeʱ£¬Ê¹ÓÃhttpload¹¤¾ß²¢·¢100£¬ÔÚÊý¾Ý¿âÇëÇóº¯ÊýÀïsleep 1ÃëÖÓ¡£memcache·â×°Àï´òÓ¡ÊÇ´Ómc¶ÁÈ¡»¹ÊÇdb¶ÁÈ¡¡£expire timeÉèÖÃΪ2Ãë¡£¿ÉÒÔ¿´µ½ÓÐÖظ´µÄÊý¾Ý¿âÇëÇó£º
[2016-03-26 10:17:13] NOTICE [1]: mc(127.0.0.1,/test.php) [2016-03-26 10:17:14] NOTICE [1]: mc(127.0.0.1,/test.php) [2016-03-26 10:17:14] NOTICE [1]: db(127.0.0.1,/test.php) [2016-03-26 10:17:14] NOTICE [1]: db(127.0.0.1,/test.php) [2016-03-26 10:17:15] NOTICE [1]: mc(127.0.0.1,/test.php) [2016-03-26 10:17:15] NOTICE [1]: mc(127.0.0.1,/test.php)
½â¾ö·½·¨
function call_high($func, $args, $expire=60){/*{{{*/ // Calulate key $key = md5(json_encode($func).json_encode($args)); // Get from memcached return $this->get_high($key, $func, $args, $expire); }/*}}}*/ // lock_expire should longer than db_func running time function get_high($key/* string or array*/, $db_func/*mixed*/, $db_args/*mixed*/, $expire, $lock_expire=10){/*{{{*/ if (!$this->mem){ return false; } $val = $this->get($key); // if(!$val){ // Maybe empty when FIRST get, otherwise, must something wrong, like the lock&work thread haven't refresh item before expire time. So we use a short lock expire time to allow more thread trying to refresh. } if ( $val && (!isset($val['t']) || !isset($val['i'])) ){ // don't have expire index? must be wrong. For logic layer to process. #Core_Log::get_instance()->notice("mc, no expire index"); return $val; } if ($val && ($val['t'] - $this->get_high_cal_time($expire) > time())){ // not expired #Core_Log::get_instance()->notice("mc"); return $val['i']; } // expired, allowed one process to refresh it if (!($this->get_high_lock($key, $lock_expire))){ // other process has refreshing it, so we quit with old data(or may be empty) #Core_Log::get_instance()->notice("other lock, we quit"); return $val?$val['i']:false; } #Core_Log::get_instance()->notice("db"); // get from user func, and set into memcache $db_info = call_user_func_array($db_func, $db_args); // may be empty, we also set into mc $this->set_high($key, $db_info, MEMCACHE_COMPRESSED, $expire, $this->get_more_expire_time($expire)); $this->free_high_lock($key); #Core_Log::get_instance()->notice("save and free lock"); return $db_info; } // These two functions should guarantee the refresh thread can do all work before realy expired. // So the work_time < cal_time + more_time protected function get_high_cal_time($expire){ return intval(min(10, max(0, $expire/5))); // [0, 10] } protected function get_more_expire_time($expire){ return intval(max(100, $expire*0.1)); // [100, ...) } function get_high_lock($key, $expire=100){ return $this->mem->add($key.self::HIGH_MC_LOCK_TAIL, 1, 0, $expire); // return true when not exists already, otherwise return false, use as mutex //return $this->mem->increment($key.self::HIGH_MC_LOCK_TAIL, 1); //can't, because increment will return false, if elem not exists already } function free_high_lock($key){ return $this->del($key.self::HIGH_MC_LOCK_TAIL); //return $this->mem->decrement ($key.self::HIGH_MC_LOCK_TAIL, 1); } function set_high($key, $val, $flag, $expire/*second*/, $more_expire=100){ if (!$this->mem){ return false; } // save expire time $expire_time = time()+$expire; $val = array('t'=>$expire_time, 'i'=>$val); $expire += $more_expire; // need more expire time, because we don't want return null when get_high return $this->set($key, $val, $flag, $expire); }/*}}}*/
»ù±¾Ë¼Ïë¾ÍÊÇÀûÓÃmutexËø£¬±£Ö¤½öÓÐÒ»¸ö½ø³Ì¸üиÃitem¡£
Óм¸¸öµã˵Ã÷һϣº
Ê×´ÎÇëÇóʱ£¬·ÇrefreshÏ̻߳᷵»ØΪ¿Õ£¬ÔÚÒµÎñÂß¼ÉÏÊÇ·ñ¿É½ÓÊÜ£¿½â¾ö·½·¨¿ÉÒÔÊǵȴýÒ»¶¨Ê±¼äºóÔٴλñÈ¡
Èç¹ûrefreshÏ̹߳¤×÷Ì«¾Ã£¬µ¼ÖÂmemcachedÖÐÏàÓ¦itemÒѾexpireÁË£¬ÄÇôÆäËûÏß³Ìget from mc¼´Îª¿Õ£¬ÔòÒ²»á³¢ÊÔ»ñÈ¡lockºó´Ódb¶ÁÈ¡¡£ÕâÀïͨ¹ýÉèÖÃlock time¡¢cal timeºÍmore expire timeÒѽâ¾ö£¬ÔÊÐíÆäËûÏß³ÌÒ²ÇëÇódb£¬ÕâÖÖÇé¿öÒ»°ãÊÇÊý¾Ý¿â×èÈûµ¼Öµģ¬ÔÊÐíÖظ´¶ÁÈ¡¿ÉÄÜ»á¼Ó´óÊý¾Ý¿âѹÁ¦£¬ËùÒÔ´æÒÉ¡£
Èç¹ûmemcachedÄÚ´æ²»×㣬µ¼ÖÂitem expire£¬ÔòÕý³£Çé¿öÏÂÒ²Ö»ÓÐÒ»¸örefreshÏ̴߳Ódb¶ÁÈ¡
Èç¹ûmemcachedÄÚ´æ²»×㣬µ¼ÖÂlock expire£¬Ôò»áÓжà¸örefreshÏ̴߳Ódb¶ÁÈ¡£¨Ò»°ã²»»áÉèÖÃÕâôСµÄmemcached°É£¿£©
ÍƼöÐÅÏ¢
- linuxÃüÁîѧϰ±Ê¼Ç£¨11£©£ºnlÃüÁî
- linuxÃüÁîѧϰ±Ê¼Ç£¨5£©£ºrmÃüÁî
- linuxÃüÁîѧϰ±Ê¼Ç£¨4£©£ºmkdirÃüÁî
- linuxÃüÁîѧϰ±Ê¼Ç£¨1£©£ºlsÃüÁî
- ½«CentosµÄyumÔ´¸ü»»Îª¹úÄڵİ¢ÀïÔÆÔ´
- ʹÓÃNginxÌí¼Óheader·ÀÖ¹ÍøÒ³±»frame
- linuxϼÓËÙscp´«Êä´óÎļþµÄËÙ¶È
- linuxϵͳÉ϶ÔnginxÈÕÖ¾·Ö¸î´¦Àí
- lnmp/nginxϵͳÕæÕýÓÐЧµÄͼƬ·ÀµÁÁ´ÍêÕûÉèÖÃÏê½â
- Í»ÆÆÊ®Íò²¢·¢µÄNginxµÄÅäÖü°ÓÅ»¯
ÈÈÃÅÐÅÏ¢
- nohup: redirecting stderr to stdou....
- ʹÓÃlog_formatΪNginx·þÎñÆ÷ÉèÖøüÏêϸµÄÈÕÖ¾¸ñʽ
- jquery easyUI--dataGrid-Json
- [Ô´´]·ÂGoogle Reader¡¢ÐÂÀË΢²©¡¢ÌÚѶ΢²©µ....
- ÀûÓÃKeepalived+mysql¹¹½¨¸ß¿ÉÓÃMySQLË«Ö÷×Ô¶....
- Nginx+keepalivedʵÏÖ¸ºÔؾùºâºÍË«»úÈȱ¸¸ß¿ÉÓÃ
- jqueryʵÏÖÒ³Ãæ¼ÓÔؽø¶ÈÌõ
- Rolling cURL: PHP²¢·¢×î¼Ñʵ¼ù
- codeigniter ·ÓÉÖÕ¼«ÓÅ»¯(url rewrite)
- linuxÏÂÉèÖÃsshÎÞÃÜÂëµÇ¼
×î½ü¸üÐÂ
- ²éÕÒ²¢É¾³ý.svnĿ¼Îļþ
- redis ÆßÖÖÊý¾ÝÀàÐ͵ÄʹÓó¡¾°
- linux ÏÂÎļþ¸´ÖƵ½windowsÏÂÂÒÂëµÄ½â¾ö°ì·¨
- nginx³öÏÖ502 upstream sent too big he....
- linuxÏÂsudoÅäÖÃÏê½â
- linuxÃüÁîѧϰ±Ê¼Ç£¨15£©£ºtailÃüÁî
- linuxÃüÁîѧϰ±Ê¼Ç£¨14£©£ºheadÃüÁî
- linuxÃüÁîѧϰ±Ê¼Ç£¨13£©£ºlessÃüÁî
- linuxÃüÁîѧϰ±Ê¼Ç£¨12£©£ºmoreÃüÁî
- ¼ÓÃÜËã·¨±È½Ï3DES AES RSA ECC MD5 SHA1µÈ
ÆÀÂÛ