基本介紹
memcached是一種緩存技術,他可以把你的數據放入內存,從而通過內存訪問提速,因為內存是最快的,memcached的主要目的是提速。
在memcached中維護了一張大的hashtable表,該表在內存中,表的結構是key和value
memcached的key一般是字串,不能重復
memcached的value可以放入(字符串,數值,數組,對象,布爾,二進制數據,圖片和視頻)
面對一個請求,有如下選擇:
可以直接查詢數據庫(慢)
使用真靜態(一般)
直接操作內存(快)
安裝使用
下載 memcached
安裝
進入cmd,切換到memcached.exe所在目錄,memcached.exe -d install啟動 memcached
第一種:可以到服務點擊啟動
第二種:命令行,memcached.exe -d start
如果你在win7下啟動不成功,則可以使用如下方法:
????memcached.exe -p 端口號(不要關閉控制臺)
端口號的范圍是0 ~ 65535,因為端口號是用兩個字節來表示的
有名端口:0 ~ 1024端口,已經有程序使用了,一般不要占用
apache 80 mysql 3306 ftp 21 ssh 22 oracle 1521 smtp 25
使用netstat -an 如果看到11211端口在監聽,說明啟動ok
netstat -anb 是哪個程序監聽,這個指令還可以看到有哪些用戶連接到我們的服務器
如果沒有安裝好,原因可能是
a. 如果是win7,win7對安全性要求較高,所以必須以administrator身份安裝,須切換成administrator去安裝,再啟動。
b. 你的memcached.exe目錄有中文,或特殊字符,保證路徑沒有中文或特殊字符即可
Telnet操作Memcached
-
登錄到telnet連接到memcached服務
telnet 127.0.0.1 11211
如果你們不能使用telnet是因為系統不存在telnet.exe,就可以到其他機器上拷貝telnet.exe放在C:\windows\system32即可
-
增加語法
add key 名 0 存放時間(秒) 數據大小(字符)
add key1 0 30
-
獲取語法
get key 值
get key1
-
修改語法
set key 名 0 存放時間 數據大小 (如果key不存在,相當于添加一個新的,如果存在,則相當與替換)
set key1 0 45 5
replace key 名 存放時間 數據大小 (如果key不存在,則失敗,這個指令要求key必須存在)
replace key1 0 40 5
-
刪除語法
delete key 名
delete key100
flush_all(可以統一把數據清空)
-
查看狀態
stats
這里可以根據cmd_hits/cmd_gets計算出命中率,越高越好。
PHP程序操作Memcached
把php_memcache.dll文件拷貝到php的ext下
不同版本的php所使用的php_memcache.dll的版本不一樣修改php.ini文件,加載php_memcache.dll(該文件就是封裝了一堆函數)
extension=php_memcache.dll重新啟動apache
編寫程序來完成curd操作
使用php memcache擴展操作memcached服務實例
<?php
//創建一個mem對象實例
$mem = new Memcache;
if(!$mem->connect("127.0.0.1",11211)) {
die('連接失敗!');
}
//1.增加字串
$mem->add("key1", "北京", MEMCACHE_COMPRESSED, 60);
//2.添加數值
$mem->set("key1", 100, MEMCACHE_COMPRESSED, 60);
//3.添加數組
//在添加數組時,根據需要,需要序列化再放入也可以
//serialize() <=> unserialize(),根據需要,也可以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);
//在另外文件中取出對象時,有一個注意的地方,對應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("連接數據庫失敗");
}
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()側重于數據的保存和傳輸,會保存數據類型,json_encode()側重于數據的處理,不會保存數據類型
在我們添加數據的時候,如果把expire設為0表示永不過期,只要memcache不重新啟動,就永遠在memcache中
expire直接給的秒數,則最大30 * 3600 * 24
如果希望時間超過30天,則time()+30 * 3600 * 24
使用PHP socket擴展操作memcached服務實例
如果管理員不讓我們去加載memcache.dll文件,我們可以直接通過源碼操作。這里我們要有一個使用php socket擴展編寫的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架構,協議簡單
c/s架構,此時memcached為服務端,我們可以使用php,c/c++等程序連接memcached服務器
memcached的服務器客戶端通信并不使用xml等格式,而使用簡單的基于文本的協議。因此,功過
telnet也能在memcached上保存數據,取得數據。
2.基于libevent的事件處理
libevent是一套跨平臺的事件處理接口的封裝,能夠兼容包括這些操作系統windows/linux/bsd/solaris等操作系統的事件處理
Memcached使用libevent來進行網絡并發連接的處理,能夠保持在很大并發情況下,仍舊能夠保持迅速的響應能力
3.內置內存存儲方式
為了提高性能,memcached中保存的數據都存儲在memcached內置的內存存儲空間中,由于數據僅存在于內存中,因此重啟memcached和重啟操作系統會導致全部數據消失。
另外,內部容量達到指定值之后,就基于LRU(Least Recent Used)算法自動刪除不使用的緩存。memcached本身是為了緩存而設計的服務器,因此并沒有過多考慮數據的永久性問題。
4.基于客戶端的分布式
memcached盡管是"分布式"緩存服務器,當時服務器并沒有分布式功能,各個memcached不會互相通信以共享信息。那么,怎樣進行分布式完全取決于客戶端的實現
分布式存入數據代碼實例
<?php
//我的電腦上有兩個memcached服務
$mem = new Memcache();
$mem->addServer("127.0.0.1", 11211);
$mem->addServer("127.0.0.1", 9999);
//這里注意把key1放入11211端口還是9999端口是由對象本身維護
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!";
}
?>
分布式取出數據代碼實例
<?php
//如何從多個memcached服務中取出key
$mem = new Memcache;
$mem->addServer("127.0.0.1", 11211);
$mem->addServer("127.0.0.1", 9999);
//如何取出是由對象本身維護的
$val = $mem->get("key1");
echo "程序中取出分布的值 =".$val;
?>
總結
1.memcached服務的數據不同步,數據是分布的
2.把什么數據放入哪個memcached是由客戶端的memcache對象決定的
3.當執行addServer的時候,并不是立即去連接memcached服務,而是通過hash后才去決定連接哪一個memcached服務,因此當你大量加入服務器到連接池時沒有多余開銷。
Memcache的細節討論
1.生命周期
從數據放入memcache開始計時直到時間到就銷毀,如果時間設為0則表示不過期
memcache的數據被銷毀的情況如下:
a.時間到
b.重啟memcached服務
c.重啟memcached服務所在的機器
d.delete/flush銷毀數據
2.把session數據放入到memcached服務中
a.修改php.ini配置文件如下
session.save_handler 有user|files|memcache
session.save_handler = memcache
session.save_path = "tcp://127.0.0.1:11211"
也可以通過php函數ini_set()來在頁面設置
b.重啟apache
<?php
//存入session數據
session_start();
$_SESSION['name'] = '天龍八部';
$_SESSION['city'] = 'beijing';
class Dog {
public $name;
}
$dog1 = new Dog;
$dog1->name = 'abcde';
$_SESSION['dog'] = $dog1;
//如果session數據入memcache,那一定是以session_id為key進行添加的
//取出session數據
$name = $_SESSION['name'];
echo "name=$name";
echo "sessionid=".session_id();
?>
如果管理員不讓我們修改php.ini文件,如何處理session入memcached這個功能
我們通過一個函數可以去修改php.ini的配置
<?php
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "tcp://127.0.0.1:11211");
?>
同時你也可以通過ini_set()去動態的修改對php.ini文件的其他設置,只針對該文件臨時生效不影響其他頁面。
memcached數據和session數據的比較
1.memcached主要目的是提速,因此它是一種無狀態的數據,即數據不和用戶綁定。和memcached相類似的技術有redis技術(key/value數據庫)
2.session數據是和用戶綁定的,是一種有狀態的數據
Memcached的安全性
如何使用memcached才是安全的
在windows下通過啟用防火墻來保護我們的memcached,原理圖如下
在linux下也可以使用防火墻
setup配置
iptables -a input -p tcp -s ip -dport 端口 -j ACCEPT
什么樣的數據適合放入memcached中
變化頻繁,具有不穩定性的數據,不需要實時入庫(比如用戶在線狀態,在線人數)
門戶網站的新聞等,覺得頁面靜態化仍不能滿足需求,可以放入到memcache中(配合jquery的ajax請求)
php的安全模式一旦開啟,fopen,rmdir的對文件的操作被禁用
在PHP中有八種被認為是false的情形:
1.布爾值 FALSE
2.整型值 0
3.浮點型值 0.0
4.空字符串以及字符串"0"
5.不包括任何元素的數組
6.不包括任何成員變量的對象
7.特殊類型NULL
8.從沒有任何標記的XML文檔生成的SingleXML對象