基本介紹
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ù),圖片和視頻)
面對一個請求幕袱,有如下選擇:
可以直接查詢數(shù)據(jù)庫(慢)
使用真靜態(tài)(一般)
直接操作內(nèi)存(快)
安裝使用
下載 memcached
安裝
進(jìn)入cmd暴备,切換到memcached.exe所在目錄,memcached.exe -d install啟動 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
-
登錄到telnet連接到memcached服務(wù)
telnet 127.0.0.1 11211
如果你們不能使用telnet是因為系統(tǒng)不存在telnet.exe,就可以到其他機(jī)器上拷貝telnet.exe放在C:\windows\system32即可
-
增加語法
add key 名 0 存放時間(秒) 數(shù)據(jù)大小(字符)
add key1 0 30
-
獲取語法
get key 值
get key1
-
修改語法
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
-
刪除語法
delete key 名
delete key100
flush_all(可以統(tǒng)一把數(shù)據(jù)清空)
-
查看狀態(tài)
stats
這里可以根據(jù)cmd_hits/cmd_gets計算出命中率,越高越好添坊。
PHP程序操作Memcached
把php_memcache.dll文件拷貝到php的ext下
不同版本的php所使用的php_memcache.dll的版本不一樣修改php.ini文件剿另,加載php_memcache.dll(該文件就是封裝了一堆函數(shù))
extension=php_memcache.dll重新啟動apache
編寫程序來完成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中
變化頻繁翼虫,具有不穩(wěn)定性的數(shù)據(jù)屑柔,不需要實時入庫(比如用戶在線狀態(tài),在線人數(shù))
門戶網(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對象