1. 程式人生 > >php操作memcache的單例模式並測試其機制

php操作memcache的單例模式並測試其機制

<?php

class MemcacheOpr extends Memcached
{
    
    private static $instance = null;
    private static $host = '127.0.0.1';
    private static $port = 11211;


    public static function getInstance()
    {
        if (!(self::$instance instanceof Memcached)) {
            self::$instance = new Memcached();
            self::$instance->addServer(self::$host, self::$port);
        }
        return self::$instance;
    }
}
ini_set('memory_limit','1024M');//這裡要注意,當前頁面的最大使用記憶體預設是128M,超過的話就必須重新設定
ini_set('max_execution_time',60);   //php頁面的最大執行時間,這裡預設值是30s,如果超過也需要重新設定

$mcache = MemcacheOpr::getInstance();//單例模式呼叫
$mcache->flush();               //先全部清除
$mcache->delete('string1m');
$mcache->delete('string2m');
$mcache->delete('string3m');
$mcache->delete('string4m');
$mcache->delete('string5m');
for($i=0;$i<8521;++$i) {
    $mcache->delete('string'.$i);
}

/*$mcache->set('somewords','have you learned some thing?');
$output = $mcache->get('somewords');
echo "output=[$output]<br/>";*/

$begintime = microtime(TRUE);
$input = str_repeat('what',1024*1024*16*2*1.5);  //192M
$input = substr($input,0,-512);
$mcache->set('string1m',$input);//192M 為什麼存入192M的5條內容都能成功呢?就是因為memcached對存入記憶體的東西開啟了壓縮

$mcache->set('string2m',$input.'areyou2');
$mcache->set('string3m',$input.'areyou3');
$mcache->set('string4m',$input.'areyou4');
$mcache->set('string5m',$input.'areyou5');
/*for($i=0;$i<10000;++$i) {
    $mcache->set('string'.$i, $input);
}*/


$input = str_repeat('what',1048576); //這裡實際上存入了4M的東西,因為memcached開啟了壓縮,所以實際存入的內容很少才會沒有問題。
for($i=0;$i<8521;++$i) {
    $mcache->set('string'.$i,$input);
}
$mcache->delete('somewords');

$during = microtime(TRUE) - $begintime;
echo 'total time:'.$during.'s<br/>';

file_put_contents('/tmp/string5m.log',$mcache->get('string1m'));
//echo 'length of $output is:'.strlen($output).",output=[$output]<br/>";

/*$allKeys = $mcache->getAllKeys();
var_dump($allKeys);


print_r($mcache->getStats());*/

其實從phpinfo()中我們可以看到針對儲存內容超過2000位元組的內容,memcached會開啟壓縮

針對php陣列,memcache會序列化,所以儲存的內容長度可以與實際內容長度不相同。

如果想看伺服器上的memcache使用狀態,可以通過 telnet 127.0.0.1 11211命令來檢視

獲取實際儲存的值: get string1m

通過 stats命令來顯示其中的一些狀態,比如記憶體命中情況

通過 stats slabs 來顯示不同的slab塊的實際情況

實際上預設每頁(page)儲存1m的內容,然後這1m的內容可以按照chunksize的大小等分成很多塊,這些塊就是slab塊

當儲存的內容長度相同時,一般會使用相同大小的塊,超過該長度1.25倍(預設的遞增倍數)的時候,會啟用新的slab塊。

遞增倍數越大,記憶體浪費的越厲害,如果8k的slab塊已經用完了,你又想繼續儲存8k的資料,那就會使用10k的資料(預設情況下),實際上已經浪費了2k的記憶體資料了;

如果遞增倍數為2,那將浪費8k的記憶體。