您好,登錄后才能下訂單哦!
博主QQ:819594300
博客地址:http://zpf666.blog.51cto.com/
有什么疑問的朋友可以聯系博主,博主會幫你們解答,謝謝支持!
一、MemCache簡述
session
MemCache是一個自由、源碼開放、高性能、分布式的分布式內存對象緩存系統,用于動態Web應用以減輕數據庫的負載。它通過在內存中緩存數據和對象來減少讀取數據庫的次數,從而提高了網站訪問的速度。 MemCaChe是一個存儲鍵值對的HashMap,在內存中對任意的數據(比如字符串、對象等)所使用的key-value存儲,數據可以來自數據庫調用、API調用,或者頁面渲染的結果。MemCache設計理念就是小而強大,它簡單的設計促進了快速部署、易于開發并解決面對大規模的數據緩存的許多難題,而所開放的API使得MemCache能用于Java、C/C++/C#、Perl、Python、PHP、Ruby等大部分流行的程序語言。
另外,說一下為什么會有Memcache和memcached兩種名稱?其實Memcache是這個項目的名稱,而memcached是它服務器端的主程序文件名
MemCache的官方網站為http://memcached.org/
MemCache訪問模型
為了加深對memcache的理解,以memcache為代表的分布式緩存,訪問模型如下:
特別澄清一個問題,MemCache雖然被稱為”分布式緩存”,但是MemCache本身完全不具備分布式的功能,MemCache集群之間不會相互通信(與之形成對比的,比如JBoss Cache,某臺服務器有緩存數據更新時,會通知集群中其他機器更新緩存或清除緩存數據),所謂的”分布式”,完全依賴于客戶端程序的實現,就像上面這張圖的流程一樣。
同時基于這張圖,理一下MemCache一次寫緩存的流程:
1、應用程序輸入需要寫緩存的數據
2、API將Key輸入路由算法模塊,路由算法根據Key和MemCache集群服務器列表得到一臺服務器編號
3、由服務器編號得到MemCache及其的ip地址和端口號
4、API調用通信模塊和指定編號的服務器通信,將數據寫入該服務器,完成一次分布式緩存的寫操作
讀緩存和寫緩存一樣,只要使用相同的路由算法和服務器列表,只要應用程序查詢的是相同的Key,MemCache客戶端總是訪問相同的客戶端去讀取數據,只要服務器中還緩存著該數據,就能保證緩存命中。
這種MemCache集群的方式也是從分區容錯性的方面考慮的,假如Node2宕機了,那么Node2上面存儲的數據都不可用了,此時由于集群中Node0和Node1還存在,下一次請求Node2中存儲的Key值的時候,肯定是沒有命中的,這時先從數據庫中拿到要緩存的數據,然后路由算法模塊根據Key值在Node0和Node1中選取一個節點,把對應的數據放進去,這樣下一次就又可以走緩存了,這種集群的做法很好,但是缺點是成本比較大。
一致性Hash算法
從上面的圖中,可以看出一個很重要的問題,就是對服務器集群的管理,路由算法至關重要,就和負載均衡算法一樣,路由算法決定著究竟該訪問集群中的哪臺服務器,先看一個簡單的路由算法。
1、余數Hash
簡單的路由算法可以使用余數Hash:用服務器數目和緩存數據KEY的hash值相除,余數為服務器列表下標編號,假如某個str對應的HashCode是52、服務器的數目是3,取余數得到1,str對應節點Node1,所以路由算法把str路由到Node1服務器上。由于HashCode隨機性比較強,所以使用余數Hash路由算法就可以保證緩存數據在整個MemCache服務器集群中有比較均衡的分布。
如果不考慮服務器集群的伸縮性,那么余數Hash算法幾乎可以滿足絕大多數的緩存路由需求,但是當分布式緩存集群需要擴容的時候,就難辦了。
就假設MemCache服務器集群由3臺變為4臺吧,更改服務器列表,仍然使用余數Hash,52對4的余數是0,對應Node0,但是str原來是存在Node1上的,這就導致了緩存沒有命中。再舉個例子,原來有HashCode為0~19的20個數據,那么:
那么不妨舉個例子,原來有HashCode為0~19的20個數據,那么:
現在擴容到4臺,加粗標紅的表示命中:
如果擴容到20+的臺數,只有前三個HashCode對應的Key是命中的,也就是15%。當然現實情況肯定比這個復雜得多,不過足以說明,使用余數Hash的路由算法,在擴容的時候會造成大量的數據無法正確命中(其實不僅僅是無法命中,那些大量的無法命中的數據還在原緩存中在被移除前占據著內存)。在網站業務中,大部分的業務數據度操作請求上事實上是通過緩存獲取的,只有少量讀操作會訪問數據庫,因此數據庫的負載能力是以有緩存為前提而設計的。當大部分被緩存了的數據因為服務器擴容而不能正確讀取時,這些數據訪問的壓力就落在了數據庫的身上,這將大大超過數據庫的負載能力,嚴重的可能會導致數據庫宕機。
這個問題有解決方案,解決步驟為:
(1)在網站訪問量低谷,通常是深夜,技術團隊加班,擴容、重啟服務器
(2)通過模擬請求的方式逐漸預熱緩存,使緩存服務器中的數據重新分布
2、一致性Hash算法
一致性Hash算法通過一個叫做一致性Hash環的數據結構實現Key到緩存服務器的Hash映射。簡單地說,一致性哈希將整個哈希值空間組織成一個虛擬的圓環(這個環被稱為一致性Hash環),如假設某空間哈希函數H的值空間是0~2^32-1(即哈希值是一個32位無符號×××),整個哈希空間如下:
下一步將各個服務器使用H進行一個哈希計算,具體可以使用服務器的IP地址或者主機名作為關鍵字,這樣每臺機器能確定其在上面的哈希環上的位置了,并且是按照順時針排列,這里我們假設三臺節點memcache經計算后位置如下:
接下來使用相同算法計算出數據的哈希值h,并由此確定數據在此哈希環上的位置
假如我們有數據A、B、C、D、4個對象,經過哈希計算后位置如下:
根據一致性哈希算法,數據A就被綁定到了server01上,D被綁定到了server02上,B、C在server03上,是按照順時針找最近服務節點方法
這樣得到的哈希環調度方法,有很高的容錯性和可擴展性:
假設server03宕機:
可以看到此時C、B會受到影響,將B、C被重定位到Server01。一般的,在一致性哈希算法中,如果一臺服務器不可用,則受影響的數據僅僅是此服務器到其環空間中前一臺服務器(即順著逆時針方向行走遇到的第一臺服務器)之間數據,其它不會受到影響。
考慮另外一種情況,如果我們在系統中增加一臺服務器Memcached Server 04:
此時A、D、C不受影響,只有B需要重定位到新的Server04。一般的,在一致性哈希算法中,如果增加一臺服務器,則受影響的數據僅僅是新服務器到其環空間中前一臺服務器(即順著逆時針方向行走遇到的第一臺服務器)之間數據,其它不會受到影響。
綜上所述,一致性哈希算法對于節點的增減都只需重定位環空間中的一小部分數據,具有較好的容錯性和可擴展性。
一致性哈希的缺點:在服務節點太少時,容易因為節點分部不均勻而造成數據傾斜問題。我們可以采用增加虛擬節點的方式解決。
更重要的是,集群中緩存服務器節點越多,增加/減少節點帶來的影響越小,很好理解。換句話說,隨著集群規模的增大,繼續命中原有緩存數據的概率會越來越大,雖然仍然有小部分數據緩存在服務器中不能被讀到,但是這個比例足夠小,即使訪問數據庫,也不會對數據庫造成致命的負載壓力。
MemCache實現原理
首先要說明一點,MemCache的數據存放在內存中
1、訪問數據的速度比傳統的關系型數據庫要快,因為Oracle、MySQL這些傳統的關系型數據庫為了保持數據的持久性,數據存放在硬盤中,IO操作速度慢
2、MemCache的數據存放在內存中同時意味著只要MemCache重啟了,數據就會消失
3、既然MemCache的數據存放在內存中,那么勢必受到機器位數的限制,32位機器最多只能使用2GB的內存空間,64位機器可以認為沒有上限
然后我們來看一下MemCache的原理,MemCache最重要的是內存如何分配的,MemCache采用的內存分配方式是固定空間分配,如下圖所示:
這張圖片里面涉及了slab_class、slab、page、chunk四個概念,它們之間的關系是:
1、MemCache將內存空間分為一組slab
2、每個slab下又有若干個page,每個page默認是1M,如果一個slab占用100M內存的話,那么這個slab下應該有100個page
3、每個page里面包含一組chunk,chunk是真正存放數據的地方,同一個slab里面的chunk的大小是固定的
4、有相同大小chunk的slab被組織在一起,稱為slab_class
MemCache內存分配的方式稱為allocator(分配運算),slab的數量是有限的,幾個、十幾個或者幾十個,這個和啟動參數的配置相關。
MemCache中的value存放的地方是由value的大小決定的,value總是會被存放到與chunk大小最接近的一個slab中,比如slab[1]的chunk大小為80字節、slab[2]的chunk大小為100字節、slab[3]的chunk大小為125字節(相鄰slab內的chunk基本以1.25為比例進行增長,MemCache啟動時可以用-f指定這個比例),那么過來一個88字節的value,這個value將被放到2號slab中。放slab的時候,首先slab要申請內存,申請內存是以page為單位的,所以在放入第一個數據的時候,無論大小為多少,都會有1M大小的page被分配給該slab。申請到page后,slab會將這個page的內存按chunk的大小進行切分,這樣就變成了一個chunk數組,最后從這個chunk數組中選擇一個用于存儲數據。
如果這個slab中沒有chunk可以分配了怎么辦,如果MemCache啟動沒有追加-M(禁止LRU,這種情況下內存不夠會報Out Of Memory錯誤),那么MemCache會把這個slab中最近最少使用的chunk中的數據清理掉,然后放上最新的數據。
Memcache的工作流程:
1、檢查客戶端的請求數據是否在memcached中,如果有,直接把請求數據返回,不再對數據庫進行任何操作,路徑操作為①②③⑦。
2、如果請求的數據不在memcached中,就去查數據庫,把從數據庫中獲取的數據返回給客戶端,同時把數據緩存一份到memcached中(memcached客戶端不負責,需要程序明確實現),路徑操作為①②④⑤⑦⑥。
3、每次更新數據庫的同時更新memcached中的數據,保證一致性。
4、當分配給memcached內存空間用完之后,會使用LRU(Least Recently Used,最近最少使用)策略加上到期失效策略,失效數據首先被替換,然后再替換掉最近未使用的數據。
Memcached特征:
協議簡單:
它是基于文本行的協議,直接通過telnet在memcached服務器上可進行存取數據操作
注:文本行的協議:指的是信息以文本傳送,一個信息單元傳遞完畢后要傳送換行。比如對于HTTP的GET請求來說,GET/index.html HTTP/1.1是一行,接下去每個頭部信息各占一行。一個空行表示整個請求結束
基于libevent事件處理:
Libevent是一套利用C開發的程序庫,它將BSD系統的kqueue,Linux系統的epoll等事件處理功能封裝成一個接口,與傳統的select相比,提高了性能。
內置的內存管理方式:
所有數據都保存在內存中,存取數據比硬盤快,當內存滿后,通過LRU算法自動刪除不使用的緩存,但沒有考慮數據的容災問題,重啟服務,所有數據會丟失。
分布式
各個memcached服務器之間互不通信,各自獨立存取數據,不共享任何信息。服務器并不具有分布式功能,分布式部署取決于memcache客戶端。
Memcache的安裝
分為兩個過程:memcache服務器端的安裝和memcached客戶端的安裝。
所謂服務器端的安裝就是在服務器(一般都是linux系統)上安裝Memcache實現數據的存儲。
所謂客戶端的安裝就是指php(或者其他程序,Memcache還有其他不錯的api接口提供)去使用服務器端的Memcache提供的數據,需要php添加擴展。
PHP的Memcache
二、centos7.2+nginx+php+memcache+mysql
環境描述:
nginx和php:
所需軟件:nginx-1.10.2.tar.gz
php-5.6.27.tar.gz
ip地址:192.168.1.8
mysql:
所需軟件:mysql-5.7.13.tar.gz
ip地址:192.168.1.9
memcache:
所需軟件:memcached-1.4.33.tar.gz
ip地址:192.168.1.10
虛擬機環境如下:
下面開始正式的實驗操作:
1)安裝nginx
①解壓縮zlib
注意:不需要編譯,只需要解壓就行。
②解壓縮pcre
注意:不需要編譯,只需要解壓就行。
③yum安裝nginx依賴包
④下載安裝nginx源碼包
下載nginx的源碼包:http://nginx.org/download
解壓縮、編譯及安裝nginx源碼包:
圖中配置、編譯安裝部分如下所示:
./configure--prefix=/usr/local/nginx1.10 --with-http_dav_module--with-http_stub_status_module --with-http_addition_module--with-http_sub_module --with-http_flv_module --with-http_mp4_module--with-pcre=/root/pcre-8.39 --with-zlib=/root/zlib-1.2.8 --with-http_ssl_module--with-http_gzip_static_module --user=www --group=www && make&& make install
說明:--with-pcre:用來設置pcre的源碼目錄。
--with-zlib:用來設置zlib的源碼目錄。
因為編譯nginx需要用到這兩個庫的源碼。
⑤做軟鏈接
⑥nginx配置文件語法檢測
⑦啟動nginx
⑧防火墻開啟80端口例外
⑨在一臺客戶機瀏覽器上瀏覽nginx網頁,測試一下nginx
2)安裝php
①安裝libmcrypt
②yum安裝php依賴包
③解壓縮、編譯及安裝php源碼包
圖中配置、編譯安裝部分如下所示:
./configure--prefix=/usr/local/php5.6 --with-mysql=mysqlnd --with-pdo-mysql=mysqlnd--with-mysqli=mysqlnd --with-openssl --enable-fpm --enable-sockets--enable-sysvshm --enable-mbstring --with-freetype-dir --with-jpeg-dir--with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --with-mhash--with-mcrypt=/usr/local/libmcrypt --with-config-file-path=/etc--with-config-file-scan-dir=/etc/php.d --with-bz2 --enable-maintainer-zts&& make && make install
④拷貝php.ini樣例文件
修改/etc/php.ini文件,將short_open_tag修改為on,修改后的內容如下:
//支持php短標簽
⑤創建php-fpm服務啟動腳本并啟動服務
提供php-fpm配置文件并編輯:
說明:如果是nginx和php分離部署,這里需要改成php真實的ip,然后php服務器還要開始9000端口例外。除此之外都和本博文一樣即可。
啟動php-fpm服務:
3)安裝mysql
(在192.168.1.9主機上操作)
因為centos7.2默認安裝了mariadb-libs,所以先要卸載掉
查看是否安裝mariadb
#rpm-qa | grep mariadb
卸載mariadb
rpm-e --nodeps mariadb-libs
然后具體的mysql安裝請參考我的mysql5.7.13的安裝,博文地址:
http://zpf666.blog.51cto.com/11248677/1908988
這里我的mysql是安裝好的,我們看一下服務是否啟動:
防火墻開啟3306端口例外:
4、安裝memcached服務端
(在192.168.1.10主機操作)
memcached是基于libevent的事件處理。libevent是個程序庫,它將Linux的epoll、BSD類操作系統的kqueue等事件處理功能封裝成統一的接口。即使對服務器的連接數增加,也能發揮I/O的性能。 memcached使用這個libevent庫,因此能在Linux、BSD、Solaris等操作系統上發揮其高性能。
①安裝memcached依賴庫libevent
②安裝memcached
③檢測memcache是否安裝成功
通過以上操作就很簡單的把memcached服務端編譯好了。這時候就可以打開服務端進行工作了。
④配置環境變量
進入用戶宿主目錄,編輯.bash_profile,為系統環境變量LD_LIBRARY_PATH增加新的目錄,需要增加的內容如下:
圖片中具體內容如下:
MEMCACHED_HOME=/usr/local/memcached
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MEMCACHED_HOME/lib
⑤啟動memcache服務
注意:-m后面跟的是分配給memcache的內存,不能大于等于本主機內存。我的主機是2048M內存,我給了1024M。
啟動參數說明:
-d 選項是啟動一個守護進程。
-m 分配給Memcache使用的內存數量,單位是MB,默認64MB。
-l 監聽的IP地址。(默認:INADDR_ANY,所有地址)
-p 設置Memcache的TCP監聽的端口,最好是1024以上的端口。
-u 運行Memcache的用戶,如果當前為root的話,需要使用此參數指定用戶。
-c 選項是最大運行的并發連接數,默認是1024。
-P 設置保存Memcache的pid文件。
-M 內存耗盡時返回錯誤,而不是刪除項
-f 塊大小增長因子,默認是1.25
-n 最小分配空間,key+value+flags默認是48
-h 顯示幫助
⑥防火墻開啟11211端口例外
⑦刷新用戶環境變量
刷新環境變量的時候報了一個錯誤,讓執行那條命令,你就執行以下即可。
然后再次刷新環境變量:
⑧編寫memcached服務啟停腳本
腳本內容如下:
#!/bin/sh
#
# pidfile:/usr/local/memcached/memcached.pid
# memcached_home: /usr/local/memcached
# chkconfig: 35 21 79
# description: Start and stop memcachedService
# Source function library
. /etc/rc.d/init.d/functions
RETVAL=0
prog="memcached"
basedir=/usr/local/memcached
cmd=${basedir}/bin/memcached
pidfile="$basedir/${prog}.pid"
#interface to listen on (default:INADDR_ANY, all addresses)
ipaddr="192.168.1.10"
#listen port
port=11211
#username for memcached
username="root"
#max memory for memcached,default is 64M
max_memory=1024
#max connections for memcached
max_simul_conn=10240
start() {
echo -n $"Starting service:$prog"
$cmd -d -m $max_memory -u $username -l$ipaddr -p $port -c $max_simul_conn -P $pidfile
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch/var/lock/subsys/$prog
}
stop() {
echo -n $"Stopping service:$prog "
run_user=$(whoami)
pidlist=$(ps -ef | grep $run_user | grepmemcached | grep -v grep | awk '{print($2)}')
for pid in $pidlist
do
kill -9 $pid
if [ $? -ne 0 ]; then
return 1
fi
done
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f/var/lock/subsys/$prog
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Usage: $0{start|stop|restart|status}"
exit 1
esac
exit $RETVAL
設置腳本可被執行:
說明:
shell腳本中return的作用
1)終止一個函數.
2)return命令允許帶一個整型參數, 這個整數將作為函數的"退出狀態
碼"返回給調用這個函數的腳本, 并且這個整數也被賦值給變量$?.
3)命令格式:returnvalue
先別急著閃,memcache服務腳本是配置好了,但是有個問題:
從上圖可以看出,重啟不了memcache,這是因為當前memcache服務是運行著的,這個服務是開始的時候第⑤步啟動的,所以咱們現在用服務腳本是重啟不了的,解決辦法如下:
就是殺死正在運行的memcache服務的進程。
然后開始再重啟服務:
至此就可以用服務腳本控制memcache服務了。
5、配置nginx.conf文件(在nginx&&php主機上操作)
①配置成如下的nginx.conf文件
把原有的東西全部刪除,配置成如下內容:
說明一下:我這里nginx&&php主機用的是4核,如果你的不是4核,請修改worker_cpu_affinity,如果是4核,請忽略該問題,全部復制我寫好的內容即可。
user www www;
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid logs/nginx.pid;
events {
use epoll;
worker_connections 65535;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local]"$request" '
# '$status$body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
tcp_nodelay on;
client_header_buffer_size 4k;
open_file_cache max=102400 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 1;
client_header_timeout 15;
client_body_timeout 15;
reset_timedout_connection on;
send_timeout 15;
server_tokens off;
client_max_body_size 10m;
fastcgi_connect_timeout 600;
fastcgi_send_timeout 600;
fastcgi_read_timeout 600;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
fastcgi_temp_path /usr/local/nginx1.10/nginx_tmp;
fastcgi_intercept_errors on;
fastcgi_cache_path /usr/local/nginx1.10/fastcgi_cache levels=1:2keys_zone=cache_fastcgi:128m inactive=1d max_size=10g;
gzip on;
gzip_min_length 2k;
gzip_buffers 4 32k;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_types text/plain text/csstext/javascript application/json application/javascriptapplication/x-javascript application/xml;
gzip_vary on;
gzip_proxied any;
server {
listen 80;
server_name www.benet.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location ~*^.+\.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$ {
valid_referers none blocked www.benet.com benet.com;
if ($invalid_referer) {
#return 302 http://www.benet.com/img/nolink.jpg;
return 404;
break;
}
access_log off;
}
location / {
root html;
index index.php index.html index.htm;
}
location ~*\.(ico|jpe?g|gif|png|bmp|swf|flv)$ {
expires 30d;
#log_not_found off;
access_log off;
}
location ~* \.(js|css)$ {
expires 7d;
log_not_found off;
access_log off;
}
location = /(favicon.ico|roboots.txt) {
access_log off;
log_not_found off;
}
location /status {
stub_status on;
}
location ~ .*\.(php|php5)?$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
fastcgi_cache cache_fastcgi;
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
fastcgi_cache_min_uses 1;
fastcgi_cache_use_stale error timeoutinvalid_header http_500;
fastcgi_cache_keyhttp://$host$request_uri;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
②重啟nginx服務
③編寫一個php測試頁
④在客戶端使用瀏覽器訪問test1.php測試頁
6、memcache客戶端(在nginx&&php主機上操作)
說明:memcache分為服務端和客戶端。服務端用來存放緩存,客戶端用來操作緩存。
安裝php擴展庫(phpmemcache)
說明:安裝PHP Memcache擴展:
可以使用php自帶的pecl安裝程序
#/usr/local/php5.6/bin/pecl install memcache
也可以從源碼安裝,他是生成php的擴展庫文件memcache.so。
①安裝memcache擴展庫
圖片中內容如下:
./configure--enable-memcache --with-php-config=/usr/local/php5.6/bin/php-config &&make && make install
記住安裝完畢后,最后一行你的這個路徑。
/usr/local/php5.6/lib/php/extensions/no-debug-zts-20131226/
②修改php.ini
添加如下一行內容:
圖片中內容如下:
extension=/usr/local/php5.6/lib/php/extensions/no-debug-zts-20131226/memcache.so
③重啟php-fpm服務
④測試
說明:檢查php擴展是否正確安裝。
主要是看查詢結果中是否有memcache項。
⑤在客戶機瀏覽器上再次訪問test1.php
則看到不到memcache和在session會話里面看不到memcache。
這是因為,nginx配置文件里配置了fast-cgi緩存,如果不注釋點這一行,客戶端訪問的test1.php的數據,是fast-cgi緩存的,因為有緩存,memcache就起不到作用了。
解決辦法如下:
再次刷新test1.php頁面,就可以看見如下的兩個截圖:
⑥編寫test2.php測試頁
說明:這個測試頁測試的是往memcache服務器寫/讀數據測試
具體內容如下:
<?php
$memcache = new Memcache;
$memcache->connect('192.168.1.10',11211) or die ("Could not connect");
$version = $memcache->getVersion();
echo "Server's version:".$version."<br/>";
$tmp_object = new stdClass;
$tmp_object->str_attr = 'test';
$tmp_object->int_attr = 123;
$memcache->set('key', $tmp_object,false, 10) or die ("Failed to save data at the server");
echo "Store data in the cache (datawill expire in 10 seconds)<br/>";
$get_result = $memcache->get('key');
echo "Data from thecache:<br/>";
var_dump($get_result);
?>
在客戶機上訪問test2.php
⑦使用memcache實現session共享
配置php.ini中的Session為memcache方式。
說明:1394行是修改
1424行是添加
兩行的文字內容如下:
session.save_handler = memcache
session.save_path = "tcp://192.168.1.10:11211?persistent=1&weight=1&timeout=1&retry_interval=15"
注:
ession.save_handler:設置session的儲存方式為memcache 。默認以文件方式存取session數據,如果想要使用自定義的處理來存取session數據,比如memcache方式則修為session.save_handler = memcache
session.save_path:設置session儲存的位置,多臺memcache用逗號隔開
使用多個 memcached server 時用逗號”,”隔開,可以帶額外的參數”persistent”、”weight”、”timeout”、”retry_interval”等等,
類似這樣的:
"tcp://host:port?persistent=1&weight=2,tcp://host2:port2"。
memcache實現session共享也可以在某個一個應用中設置:
ini_set("session.save_handler","memcache");
ini_set("session.save_path","tcp://192.168.0.9:11211");
ini_set()只對當前php頁面有效,并且不會去修改php.ini文件本身,也不會影響其他php頁面。
⑧測試memcache可用性
重啟php-fpm:
在nginx&&php
服務器上新建//usr/local/nginx1.10/html/memcache.php文件。內容如下:
<?php
session_start();
if (!isset($_SESSION['session_time']))
{
$_SESSION['session_time'] = time();
}
echo "session_time:".$_SESSION['session_time']."<br/>";
echo"now_time:".time()."<br />";
echo"session_id:".session_id()."<br />";
?>
這個memcache.php的測試頁面主要測試的是:
當客戶機訪問時,給客戶機生成一個session信息,這個session就是記錄在什么時間點緩存到memcache的數據。
刷新一下頁面,再看:
每刷一次頁面,now_time的值就一直在漲,而session_time一直不會變的,因為是session會話保持嘛。
訪問網址http://192.168.1.8/memcache.php可以查看session_time是否都是為memcache中的Session,同時可以在不同的服務器上修改不同的標識查看是否為不同的服務器上的。
可以直接用sessionid 去 memcached 里查詢一下:
說明:得到session_time|i:1493893966;這樣的結果,說明session 正常工作。
默認memcache會監聽11221端口,如果想清空服務器上memecache的緩存,一般使用的是:
或者
說明:使用flush_all 后并不是刪除memcache上的key,而是置為過期。
memcache安全配置:
因為memcache不進行權限控制,因此需要通過iptables將memcache僅開放個web服務器。
7、測試memcache緩存數據庫數據
①先在Mysql服務器上創建測試表
②編寫測試腳本
作用:用于測試memcache是否緩存數據成功。
先需要為這個腳本添加一個只讀的數據庫用戶,命令格式:
在web服務器上創建測試腳本內容如下:
<?php
$memcachehost = '192.168.1.10';
$memcacheport =11211;
$memcachelife = 60;
$memcache = new Memcache;
$memcache->connect($memcachehost,$memcacheport)or die ("Could not connect");
$query="select * from test1 limit 10";
$key=md5($query);
if(!$memcache->get($key))
{
$conn=mysql_connect("192.168.1.9","user","123456");
mysql_select_db(testdb1);
$result=mysql_query($query);
while ($row=mysql_fetch_assoc($result))
{
$arr[]=$row;
}
$f = 'mysql';
$memcache->add($key,serialize($arr),0,30);
$data = $arr ;
}
else{
$f = 'memcache';
$data_mem=$memcache->get($key);
$data = unserialize($data_mem);
}
echo $f;
echo "<br>";
echo "$key";
echo "<br>";
//print_r($data);
foreach($data as $a)
{
echo "number is <b><fontcolor=#FF0000>$a[id]</font></b>";
echo "<br>";
echo "name is <b><font color=#FF0000>$a[name]</font></b>";
echo "<br>";
}
?>
③訪問頁面測試
說明:如果出現mysql表示memcached中沒有內容,需要memcached從數據庫中取得
再刷新頁面,如果有memcache標志表示這次的數據是從memcached中取得的。
memcached有個緩存時間默認是1分鐘,過了一分鐘后,memcached需要重新從數據庫中取得數據。
④查看 Memcached 緩存情況
我們需要使用 telnet 命令查看。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。