Memcached 緩存技術(shù)

基本介紹

memcached是一種緩存技術(shù)绎谦,他可以把你的數(shù)據(jù)放入內(nèi)存,從而通過內(nèi)存訪問提速遏考,因為內(nèi)存是最快的翩腐,memcached的主要目的是提速鸟款。

在memcached中維護(hù)了一張大的hashtable表,該表在內(nèi)存中栗菜,表的結(jié)構(gòu)是key和value

memcached的key一般是字串欠雌,不能重復(fù)

memcached的value可以放入(字符串,數(shù)值疙筹,數(shù)組,對象禁炒,布爾而咆,二進(jìn)制數(shù)據(jù),圖片和視頻)

面對一個請求幕袱,有如下選擇:

  1. 可以直接查詢數(shù)據(jù)庫(慢)

  2. 使用真靜態(tài)(一般)

  3. 直接操作內(nèi)存(快)

安裝使用

  1. 下載 memcached

  2. 安裝
    進(jìn)入cmd暴备,切換到memcached.exe所在目錄,memcached.exe -d install

  3. 啟動 memcached
    第一種:可以到服務(wù)點擊啟動
    第二種:命令行们豌,memcached.exe -d start

如果你在win7下啟動不成功涯捻,則可以使用如下方法:
????memcached.exe -p 端口號(不要關(guān)閉控制臺)

端口號的范圍是0 ~ 65535浅妆,因為端口號是用兩個字節(jié)來表示的
有名端口:0 ~ 1024端口,已經(jīng)有程序使用了障癌,一般不要占用
apache 80 mysql 3306 ftp 21 ssh 22 oracle 1521 smtp 25
使用netstat -an 如果看到11211端口在監(jiān)聽凌外,說明啟動ok

netstat -anb 是哪個程序監(jiān)聽,這個指令還可以看到有哪些用戶連接到我們的服務(wù)器

如果沒有安裝好涛浙,原因可能是

a. 如果是win7康辑,win7對安全性要求較高,所以必須以administrator身份安裝轿亮,須切換成administrator去安裝疮薇,再啟動。

b. 你的memcached.exe目錄有中文我注,或特殊字符按咒,保證路徑?jīng)]有中文或特殊字符即可

Telnet操作Memcached

  1. 登錄到telnet連接到memcached服務(wù)

    telnet 127.0.0.1 11211

    如果你們不能使用telnet是因為系統(tǒng)不存在telnet.exe,就可以到其他機(jī)器上拷貝telnet.exe放在C:\windows\system32即可

  2. 增加語法

    add key 名 0 存放時間(秒) 數(shù)據(jù)大小(字符)

     add key1 0 30
    
  3. 獲取語法

    get key 值

     get key1
    
  4. 修改語法

    set key 名 0 存放時間 數(shù)據(jù)大小 (如果key不存在但骨,相當(dāng)于添加一個新的胖齐,如果存在,則相當(dāng)與替換)

     set key1 0 45 5
    

    replace key 名 存放時間 數(shù)據(jù)大小 (如果key不存在嗽冒,則失敗呀伙,這個指令要求key必須存在)

     replace key1 0 40 5
    
  5. 刪除語法

    delete key 名

     delete key100
    

    flush_all(可以統(tǒng)一把數(shù)據(jù)清空)

  6. 查看狀態(tài)

    stats
    

    這里可以根據(jù)cmd_hits/cmd_gets計算出命中率,越高越好添坊。

PHP程序操作Memcached

  1. 把php_memcache.dll文件拷貝到php的ext下
    不同版本的php所使用的php_memcache.dll的版本不一樣

  2. 修改php.ini文件剿另,加載php_memcache.dll(該文件就是封裝了一堆函數(shù))
    extension=php_memcache.dll

  3. 重新啟動apache

  4. 編寫程序來完成curd操作

使用php memcache擴(kuò)展操作memcached服務(wù)實例

<?php
   //創(chuàng)建一個mem對象實例
    $mem = new Memcache;
    if(!$mem->connect("127.0.0.1",11211)) {
       die('連接失敗!');
    }

   //1.增加字串
   $mem->add("key1", "北京", MEMCACHE_COMPRESSED, 60);
   //2.添加數(shù)值
   $mem->set("key1", 100, MEMCACHE_COMPRESSED, 60);
   //3.添加數(shù)組
   //在添加數(shù)組時,根據(jù)需要贬蛙,需要序列化再放入也可以 
   //serialize() <=> unserialize()雨女,根據(jù)需要,也可以json_encode() <=> json_decode()再放入   
   $arr = array("北京", "天津");
   $mem->set("key1", $arr, MEMCACHE_COMPRESSED, 60);
   //4. 添加對象
   class Dog {
        public $name;
        public $age;
          public function __construct($name, $age) {
            $this->name=$name;
            $this->age=$age;
        }
   }        
   $dog1 = new Dog("小狗", 50);
   $mem->set("key1", $dog1, MEMCACHE_COMPRESSED, 60);

   //在另外文件中取出對象時阳准,有一個注意的地方氛堕,對應(yīng)5.2這個版本會提示錯誤
   //對于php5.3這個版本會提示incomplete信息,解決方法是聲明類定義即可
   class Dog {
        public $name;
        public $age;
        public function __construct($name, $age) {
            $this->name=$name;
            $this->age=$age;
        }
    }       
    $dog = $mem->get('key1');
    var_dump($dog);

   //5.添加null
   $mem->set("key1", null, MEMCACHE_COMPRESSED, 50);

   //6. 添加bool
   $mem->set("key1", false, MEMCACHE_COMPRESSED, 50);

   //7. 資源類型放入
   $con = mysql_connect("127.0.0.1", "root", "root");
   if(!con) {
         die("連接數(shù)據(jù)庫失敗");
   }
   if($mem->set("key1", false, MEMCACHE_COMPRESSED, 60)){
     echo "添加資源ok";
   }

   //查詢
   $val = $mem->get('key1');
   echo '<br/>val='.$val;   

   //修改
   //可以使用replace()
   if($mem->replace("key1", "hello", MEMCACHE_COMPRESSED, 60)){
       echo "replace ok!";
   }

    //刪除
    if($mem->delete("key1")){
       echo "delete ok!";   
    }
?>

對象序列化和json編碼實例

<?php
    class Dog {
        public $name;
        public $age;
        public function __construct($name, $age) {
            $this->name=$name;
            $this->age=$age;
        }
    }       

    $dog2 = new Dog("小黃", 40);
    file_puts_contents("d:/my.log", serialize($dog2));
    echo "save ok!";    
    $dog = unserialize(file_get_contents("d:/my.log"));
    var_dump($dog);

    $arr = array("北京", "天津");
    file_put_contents("d:/my.log", json_encode($arr));
    echo "save ok!";
    $arr = json_decode(file_get_contents("d:/my.log"));
    var_dump($arr); 
?>

serialize()側(cè)重于數(shù)據(jù)的保存和傳輸野蝇,會保存數(shù)據(jù)類型讼稚,json_encode()側(cè)重于數(shù)據(jù)的處理,不會保存數(shù)據(jù)類型

在我們添加數(shù)據(jù)的時候绕沈,如果把expire設(shè)為0表示永不過期锐想,只要memcache不重新啟動,就永遠(yuǎn)在memcache中

expire直接給的秒數(shù)乍狐,則最大30 * 3600 * 24

如果希望時間超過30天赠摇,則time()+30 * 3600 * 24

使用PHP socket擴(kuò)展操作memcached服務(wù)實例

如果管理員不讓我們?nèi)ゼ虞dmemcache.dll文件,我們可以直接通過源碼操作。這里我們要有一個使用php socket擴(kuò)展編寫的memcache類memcached-client.php

<?php
    require_once("memcached-client.php");
    $mc = new memcached(array(
        'servers' => array("127.0.0.1:11211"),
        'debug'   => false,
        'compress_threshold' => 10240,
        'persistant' => true));
    $mc->add("key1", arrray('some', 'array'));

    $val = $mc->get('key1');
     var_dump($val);    

    $mc->set("key1", "北京");
    $val = $mc->get("key1");
     var_dump($val);

    $mc->delete("key1");
    $val = $mc->get("key1");
     var_dump($val);
?>

Memcached的深入理解

1.基于c/s架構(gòu)藕帜,協(xié)議簡單

c/s架構(gòu)烫罩,此時memcached為服務(wù)端,我們可以使用php,c/c++等程序連接memcached服務(wù)器

memcached的服務(wù)器客戶端通信并不使用xml等格式洽故,而使用簡單的基于文本的協(xié)議贝攒。因此,功過

telnet也能在memcached上保存數(shù)據(jù)收津,取得數(shù)據(jù)饿这。

2.基于libevent的事件處理

libevent是一套跨平臺的事件處理接口的封裝,能夠兼容包括這些操作系統(tǒng)windows/linux/bsd/solaris等操作系統(tǒng)的事件處理

Memcached使用libevent來進(jìn)行網(wǎng)絡(luò)并發(fā)連接的處理撞秋,能夠保持在很大并發(fā)情況下长捧,仍舊能夠保持迅速的響應(yīng)能力

3.內(nèi)置內(nèi)存存儲方式

為了提高性能,memcached中保存的數(shù)據(jù)都存儲在memcached內(nèi)置的內(nèi)存存儲空間中吻贿,由于數(shù)據(jù)僅存在于內(nèi)存中串结,因此重啟memcached和重啟操作系統(tǒng)會導(dǎo)致全部數(shù)據(jù)消失。

另外舅列,內(nèi)部容量達(dá)到指定值之后肌割,就基于LRU(Least Recent Used)算法自動刪除不使用的緩存。memcached本身是為了緩存而設(shè)計的服務(wù)器帐要,因此并沒有過多考慮數(shù)據(jù)的永久性問題把敞。

4.基于客戶端的分布式

memcached盡管是"分布式"緩存服務(wù)器,當(dāng)時服務(wù)器并沒有分布式功能榨惠,各個memcached不會互相通信以共享信息奋早。那么,怎樣進(jìn)行分布式完全取決于客戶端的實現(xiàn)

分布式存入數(shù)據(jù)代碼實例

<?php
    //我的電腦上有兩個memcached服務(wù)
    $mem = new Memcache();
    $mem->addServer("127.0.0.1", 11211);
    $mem->addServer("127.0.0.1", 9999);
    //這里注意把key1放入11211端口還是9999端口是由對象本身維護(hù)
    if($mem->add("key1", "hello", MEMCACHE_COMPRESSED, 300)){
         echo "add ok!";
    }
    if($mem->add("key2", "hello", MEMCACHE_COMPRESSED, 300)){
         echo "add ok!";
    } 
    if($mem->add("key3", "hello", MEMCACHE_COMPRESSED, 300)){
         echo "add ok!";
    }
?>

分布式取出數(shù)據(jù)代碼實例

<?php
    //如何從多個memcached服務(wù)中取出key
    $mem = new Memcache;
    $mem->addServer("127.0.0.1", 11211);
    $mem->addServer("127.0.0.1", 9999);
    //如何取出是由對象本身維護(hù)的
    $val = $mem->get("key1");
    echo "程序中取出分布的值 =".$val;
?>

總結(jié)

1.memcached服務(wù)的數(shù)據(jù)不同步赠橙,數(shù)據(jù)是分布的

2.把什么數(shù)據(jù)放入哪個memcached是由客戶端的memcache對象決定的

3.當(dāng)執(zhí)行addServer的時候耽装,并不是立即去連接memcached服務(wù),而是通過hash后才去決定連接哪一個memcached服務(wù)期揪,因此當(dāng)你大量加入服務(wù)器到連接池時沒有多余開銷掉奄。

Memcache的細(xì)節(jié)討論

1.生命周期

從數(shù)據(jù)放入memcache開始計時直到時間到就銷毀,如果時間設(shè)為0則表示不過期

memcache的數(shù)據(jù)被銷毀的情況如下:

a.時間到

b.重啟memcached服務(wù)

c.重啟memcached服務(wù)所在的機(jī)器

d.delete/flush銷毀數(shù)據(jù)

2.把session數(shù)據(jù)放入到memcached服務(wù)中

a.修改php.ini配置文件如下

session.save_handler 有user|files|memcache

session.save_handler = memcache

session.save_path = "tcp://127.0.0.1:11211"

也可以通過php函數(shù)ini_set()來在頁面設(shè)置

b.重啟apache

<?php
    //存入session數(shù)據(jù)
    session_start();
    $_SESSION['name'] = '天龍八部';
    $_SESSION['city'] = 'beijing';

    class Dog {
        public $name;
    }
    $dog1 = new Dog;
    $dog1->name = 'abcde';
    $_SESSION['dog'] = $dog1;

    //如果session數(shù)據(jù)入memcache凤薛,那一定是以session_id為key進(jìn)行添加的
    //取出session數(shù)據(jù)
    $name = $_SESSION['name'];
    echo "name=$name";
    echo "sessionid=".session_id();
?>

如果管理員不讓我們修改php.ini文件姓建,如何處理session入memcached這個功能

我們通過一個函數(shù)可以去修改php.ini的配置

<?php
    ini_set("session.save_handler", "memcache");
    ini_set("session.save_path", "tcp://127.0.0.1:11211");
?>

同時你也可以通過ini_set()去動態(tài)的修改對php.ini文件的其他設(shè)置,只針對該文件臨時生效不影響其他頁面枉侧。

memcached數(shù)據(jù)和session數(shù)據(jù)的比較

1.memcached主要目的是提速引瀑,因此它是一種無狀態(tài)的數(shù)據(jù),即數(shù)據(jù)不和用戶綁定榨馁。和memcached相類似的技術(shù)有redis技術(shù)(key/value數(shù)據(jù)庫)

2.session數(shù)據(jù)是和用戶綁定的,是一種有狀態(tài)的數(shù)據(jù)

Memcached的安全性

如何使用memcached才是安全的

在windows下通過啟用防火墻來保護(hù)我們的memcached帜矾,原理圖如下

在linux下也可以使用防火墻

setup配置

iptables -a input -p tcp -s ip -dport 端口 -j ACCEPT

什么樣的數(shù)據(jù)適合放入memcached中

  1. 變化頻繁翼虫,具有不穩(wěn)定性的數(shù)據(jù)屑柔,不需要實時入庫(比如用戶在線狀態(tài),在線人數(shù))

  2. 門戶網(wǎng)站的新聞等珍剑,覺得頁面靜態(tài)化仍不能滿足需求掸宛,可以放入到memcache中(配合jquery的ajax請求)

php的安全模式一旦開啟,fopen,rmdir的對文件的操作被禁用

在PHP中有八種被認(rèn)為是false的情形:

1.布爾值 FALSE

2.整型值 0

3.浮點型值 0.0

4.空字符串以及字符串"0"

5.不包括任何元素的數(shù)組

6.不包括任何成員變量的對象

7.特殊類型NULL

8.從沒有任何標(biāo)記的XML文檔生成的SingleXML對象

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末招拙,一起剝皮案震驚了整個濱河市唧瘾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌别凤,老刑警劉巖饰序,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異规哪,居然都是意外死亡求豫,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門诉稍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蝠嘉,“玉大人,你說我怎么就攤上這事杯巨≡楦妫” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵服爷,是天一觀的道長杜恰。 經(jīng)常有香客問我,道長层扶,這世上最難降的妖魔是什么箫章? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮镜会,結(jié)果婚禮上檬寂,老公的妹妹穿的比我還像新娘。我一直安慰自己戳表,他們只是感情好桶至,可當(dāng)我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著匾旭,像睡著了一般镣屹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上价涝,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天女蜈,我揣著相機(jī)與錄音,去河邊找鬼。 笑死伪窖,一個胖子當(dāng)著我的面吹牛逸寓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播覆山,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼竹伸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了簇宽?” 一聲冷哼從身側(cè)響起勋篓,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎魏割,沒想到半個月后譬嚣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡见妒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年孤荣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片须揣。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡盐股,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耻卡,到底是詐尸還是另有隱情疯汁,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布卵酪,位于F島的核電站幌蚊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏溃卡。R本人自食惡果不足惜溢豆,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瘸羡。 院中可真熱鬧漩仙,春花似錦、人聲如沸犹赖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽峻村。三九已至麸折,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間粘昨,已是汗流浹背垢啼。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工窜锯, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人膊夹。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓衬浑,卻偏偏與公主長得像捌浩,于是被迫代替她去往敵國和親放刨。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容