Memcached的安裝配置及將PHP的session保存在Memcached中

Memcached是一款開源、高性能、分佈式內存對象緩存系統,可應用各種需要緩存的場景,其主要目的是通過降低對Database的訪問來加速web應用程序。它是一個基於內存的“鍵值對”存儲,用於存儲數據庫調用、API調用或頁面引用結果的直接數據,如字符串、對象等。


Memcached現已成爲mixi、hatena、Facebook、Vox、LiveJournal等衆多服務中提高Web應用擴展性的重要因素。


Memcached有以特點

1. 簡單key/value存儲:服務器不關心數據本身的意義及結構,只要是可序列化數據即可。存儲項由“鍵、過期時間、可選的標誌及數據”四個部分組成;

2. 功能的實現一半依賴於客戶端,一半基於服務器端:客戶負責發送存儲項至服務器端、從服務端獲取數據以及無法連接至服務器時採用相應的動作;服務端負責接收、存儲數據,並負責數據項的超時過期;

3. 各服務器間彼此無視:不在服務器間進行數據同步;

4. O(1)的執行效率

5. 清理超期數據:默認情況下,Memcached工作在Lazy模式下,是一個LRU(最近最少使用)緩存,同時,它按事先預訂的時長清理超期數據;但事實上,memcached不會刪除任何已緩存數據,只是在其過期之後不再爲客戶所見;而且,memcached也不會真正按期限清理緩存,而僅是當get命令到達時檢查其時長;但是鍵一旦過期,則再次查詢不會返回結果


Memcached雖然是一個鍵值存儲server,但是它本身無法決定緩存那些數據,而是由客戶端決定的鍵名,鍵值,緩存時長,標誌位等


Memcached可以基於文本或者二進制上傳和下載數據


Memcached將所有數據緩存再自己的內存中,並不會進行持久存儲,且它認爲自己也僅僅是一個緩存server,其上的數據丟失並不影響原數據,僅僅對服務有所影響


不同的memcached服務器之間不能進行通信,也不監控對方心跳信息,client端可以根據調度器如Nginx、haproxy、lvs等基於持久連接將數據緩存在多臺memcached上(爲了能夠保證始終能夠在同一個memcached找到同一個鍵,就需要對鍵做哈希運算,如將鍵做一定運算後/memcached的個數,再取餘,根據餘數將其存儲在固定memcached服務器上,這樣只要知道鍵一計算,就可以知道它在哪個server上存着;但這個取餘法有個致命缺陷就是,萬一掛掉或多了一個memcached服務器,其同一個鍵取餘結果就會改變,就再也不能根據原來計算方法找到其對應的鍵值,即所有memcached上的緩存都失效)


這時就可以使用一致性哈希運算:1到2^32之間取幾個對應區間對應每臺服務器,然後對鍵/2^32取餘,然後根據餘數順時針找最近服務器進行緩存,這樣一旦掛了或加了一個memcached其結果也只讓一臺服務器上的緩存失效


Memcached有兩個很重要組件:

1:buddy system(夥伴系統)爲了保證內存中的空間連續可用buddy system會將臨近的空間碎片合併爲一個大的連續空間,避免了內存碎片的產生

2:slab allocator:當要存儲小於內存頁面大小(4K)數據時如存儲一個128字節的數據,爲了節省空間,slab allocator會將一個4K的內存頁提前劃分爲許多128字節的塊,將其存在裏面,然後標記此塊已近使用,而數據釋放後也不會銷燬這個128字節的塊,會提供給以後的數據存儲使用。並且slab allocator slab爲不同大小的數據結構提前準備各種不同大小的內存塊,存儲時選擇與它大小最近,且比它大的塊進行存儲,這樣就提高了內存的利用效率


memcached依賴於libevent API,因此要事先安裝之,項目主頁:http://libevent.org/,且memcached是基於Event_Driven(事件驅動)的I/O機制,而event_driven是由libevent這個庫提供的

[root@node1 libevent-2.0.22-stable]# ./configure --prefix=/usr/local/libevent

[root@node1 libevent-2.0.22-stable]# make && make install

[root@node1 local]# echo "/usr/local/libevent/lib/" > /etc/ld.so.conf.d/libevent.conf

[root@node1 local]# ldconfig -v

[root@node1 ~]# yum install -y cyrus-sasl-devel


裝memcached的服務端memcached memcached官網www.memcached,org 

[root@node1 tool]# tar memcached-1.4.33.tar.gz 

[root@node1 tool]# cd memcached-1.4.33

[root@node1 memcached-1.4.33]# ./configure --enable-sasl --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent

[root@node1 memcached-1.4.33]# make && make install


-l <ip_addr>:指定進程監聽的地址;

-d: 以服務模式運行;

-u <username>:以指定的用戶身份運行memcached進程;

-m <num>:用於緩存數據的最大內存空間,單位爲MB,默認爲64MB;

-c <num>:最大支持的併發連接數,默認爲1024;

-p <num>: 指定監聽的TCP端口,默認爲11211;

-U <num>:指定監聽的UDP端口,默認爲11211,0表示關閉UDP端口;

-t <threads>:用於處理入站請求的最大線程數,僅在memcached編譯時開啓了支持線程纔有效;

-f <num>:設定Slab Allocator定義預先分配內存空間大小固定的塊時使用的增長因子;

-M:當內存空間不夠使用時返回錯誤信息,而不是按LRU算法利用空間;

-n: 指定最小的slab chunk大小;單位是字節;

-S: 啓用sasl進行用戶認證;


建立一個內存空間大小128M,slab chunk大小從20字節開始、增長因子爲1.25、以nobody身份運行的memcache緩存空間,且顯示詳細過程

[root@node1 init.d]# /usr/local/memcached/bin/memcached -m 128 -n 20 -f 1.25 -vv -u nobody

slab class   1: chunk size        72 perslab   14563

slab class   2: chunk size        96 perslab   10922

slab class   3: chunk size       120 perslab    8738

slab class   4: chunk size       152 perslab    6898

slab class   5: chunk size       192 perslab    5461

slab class   6: chunk size       240 perslab    4369

slab class   7: chunk size       304 perslab    3449

slab class   8: chunk size       384 perslab    2730

slab class   9: chunk size       480 perslab    2184

slab class  10: chunk size       600 perslab    1747

slab class  11: chunk size       752 perslab    1394

slab class  12: chunk size       944 perslab    1110

slab class  13: chunk size      1184 perslab     885

slab class  14: chunk size      1480 perslab     708

slab class  15: chunk size      1856 perslab     564

slab class  16: chunk size      2320 perslab     451

slab class  17: chunk size      2904 perslab     361

slab class  18: chunk size      3632 perslab     288

slab class  19: chunk size      4544 perslab     230

slab class  20: chunk size      5680 perslab     184

slab class  21: chunk size      7104 perslab     147

slab class  22: chunk size      8880 perslab     118

slab class  23: chunk size     11104 perslab      94

slab class  24: chunk size     13880 perslab      75

slab class  25: chunk size     17352 perslab      60

slab class  26: chunk size     21696 perslab      48

slab class  27: chunk size     27120 perslab      38

slab class  28: chunk size     33904 perslab      30

slab class  29: chunk size     42384 perslab      24

slab class  30: chunk size     52984 perslab      19

slab class  31: chunk size     66232 perslab      15

slab class  32: chunk size     82792 perslab      12

slab class  33: chunk size    103496 perslab      10

slab class  34: chunk size    129376 perslab       8

slab class  35: chunk size    161720 perslab       6

slab class  36: chunk size    202152 perslab       5

slab class  37: chunk size    252696 perslab       4

slab class  38: chunk size    315872 perslab       3

slab class  39: chunk size    394840 perslab       2

slab class  40: chunk size    493552 perslab       2

slab class  41: chunk size    616944 perslab       1

slab class  42: chunk size    771184 perslab       1

slab class  43: chunk size   1048576 perslab       1


從顯示的信息可以看到slab chunk的最小值系統默認爲72個字節,按1.25倍增長到了1048576大小


[root@node1 init.d]# netstat -tunlp |grep memcached 

tcp     0      0 0.0.0.0:11211    0.0.0.0:*      LISTEN      9268/memcached      

tcp     0      0 :::11211        :::*         LISTEN      9268/memcached      

udp     0      0 0.0.0.0:11211    0.0.0.0:*                  9268/memcached      

udp     0      0 :::11211        :::*                     9268/memcached      

可以看到監聽在tcp和udp的11211端口


[root@node1 xinetd.d]# telnet localhost 11211

Trying ::1...

Connected to localhost.

Escape character is '^]'.

stats

STAT pid 9268

STAT uptime 1483

STAT time 1482739946

STAT version 1.4.33

STAT libevent 1.4.13-stable

STAT pointer_size 64

STAT rusage_user 0.209968

STAT rusage_system 1.007846

STAT curr_connections 10

STAT total_connections 12

STAT connection_structures 11

STAT reserved_fds 20

STAT cmd_get 0

STAT crawler_reclaimed 0

STAT crawler_items_checked 0

STAT lrutail_reflocked 0

END

add mykey 0 30 5 ##添加一個鍵,鍵名爲mykey,flag爲0,鍵的有效期爲30秒,大小爲5個字符

hello   ##鍵值爲hello

STORED  ##顯示已近%STORED

get mykey ##獲取保存的鍵

VALUE mykey 0 5

hello  ##鍵值爲hello

END

get mykey   

END

     ##30秒過去後,鍵值失效(雖然memcached爲lazy模型,但過期後就不返回查詢值)

quit

Connection closed by foreign host.


此外memcached還有以下常用命令:


replace:僅當鍵已經存在時,replace 命令纔會替換緩存中的鍵。如果緩存中不存在鍵,那麼您將從        memcached 服務器接受到一條 NOT_STORED 響應。

append:將數據追加到當前緩存數據的之後,當緩存數據存在時才存儲。

prepend:將數據追加到當前緩存數據的之前,當緩存數據存在時才存儲

incr:  讓已近存在的鍵自動加一

derc:  讓已近存在的鍵自動減一

get :  key 可以一個或多個,用空格格開

gets:與 get 一樣,但會返回多一個數字,這個數字用來檢查數據是否被修改過,如修改過,這個       數字回改變。

flash_all:清除所有鍵

flash_all 900:在900秒內清空所有鍵

delete: 刪除緩存數據,數據存在返回DELETED,數據不存在返回NOT_FOUND


stats 查看memcached運行狀態

pid                     Memcached 進程ID    

    

uptime                  Memcached 運行時間,單位:秒    

    

time                    Memcached 當前的UNIX時間    

    

version                 Memcached 的版本號    

    

rusage_user             該進程累計的用戶時間,單位:秒    

    

rusage_system           該進程累計的系統時間,單位:秒    

    

curr_items            Memcached 當前存儲的內容數量    

    

total_items           Memcached 啓動以來存儲過的內容總數    

    

bytes               Memcached 當前存儲內容所佔用的字節數(*/1024/1024=mb)    

    

curr_connections        當前連接數量    

    

total_connections       Memcached 運行以來接受的連接總數    

    

connection_structures    Memcached 分配的連接結構的數量    

    

cmd_get               查詢請求總數    

    

cmd_set                存儲(添加/更新)請求總數    

    

get_hits                查詢成功獲取數據的總次數    

    

get_misses              查詢成功未獲取到數據的總次數    

    

bytes_read              Memcached 從網絡讀取到的總字節數    

    

bytes_written           Memcached 向網絡發送的總字節數    

    

limit_maxbytes          Memcached 在存儲時被允許使用的字節總數 


更詳細的memcached命令請參考下面網友寫的文章

http://blog.csdn.net/fdipzone/article/details/8655681

http://www.cnblogs.com/wayne173/p/5652034.html


如何讓PHP使用memcached?(裝memcached的客戶端)


PHP要結合memcached必須依賴memcached的客戶端庫(也稱爲擴展),對於PHP來說其客戶端庫有兩種,memcache和memcached,其中memcached功能更強大。而對Perl來說其所依賴的客戶端庫爲cache:memcached模塊。


簡單來說memcached爲memcached的服務器端,要讓php在memcached服務器端緩存數據,就必須在在php所在server上裝一個memcached的客戶端(擴展),而這客戶端有兩種,一個叫memcache,另一個叫memcached(比較高級)

對於C/C++來說其必須依賴libmemcached


下面將演示PHP擴展memcached擴展(要先安裝libmemcached),如果安裝memcache擴展則不用裝libmemcached

如果你要用memcache擴展下載可以點這個鏈接http://pecl.php.net/package/memcache


這個鏈接可以下載memcached http://pecl.php.net/package/memcached 



   [root@node1 tool]#wget  https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz

   [root@node1 tool]# tar -xf libmemcached-1.0.18.tar.gz 

   [root@node1 tool]# cd libmemcached-1.0.18

   [root@node1 libmemcached-1.0.18]# ./configure --prefix=/usr/local/libmemcached --with-memcached

   [root@node1 libmemcached-1.0.18]#make && make install


    

   [root@node1 tool]#tar -xf memcached-2.2.0.tgz 


   [root@node1 tool]#cd memcached-2.2.0

   [root@node1 memcached-2.2.0]#/usr/local/php/bin/phpize 

   [root@node1 memcached-2.2.0]#./configure --with-php-config=/usr/local/php/bin/php-config --enable-memcached --with-libmemcached-dir=/usr/local/libmemcached 


   [root@node1 memcached-2.2.0]#make && make install


   [root@node1 memcached-2.2.0]#vim /etc/php.d/memcache.ini

    extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/memcached.so

   [root@node1 memcached-2.2.0]#service php-fpm restart

    啓用Nginx轉發php功能

      [root@node1 ~]# vi /etc/nginx/nginx.conf

     location ~ \.php$ {

            root           /web/read;

            fastcgi_pass   127.0.0.1:9000;

            fastcgi_index  index.php;

            fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;

            include        fastcgi_params;

          }

      [root@node1 ~]# service nginx reload


wKiom1hhzO3BKE_YAABmLx0D4gw217.png

可以看到memcached擴展已近完成


Nginx結合memcached


[root@node1 ~]# vim /etc/nginx/nginx.conf


server {

        listen       80;

        server_name  www.magedu.com;


     location / {

              set $memcached_key $uri;#set 鍵名$memcached_key 鍵$uri;

              memcached_pass  127.0.0.1:11211; #memcached服務器IP:port

              default_type    text/html; #默認緩存純文本的內容

              error_page     404 @fallback; #如果返回404錯誤(即memcached中沒有相                                     應的緩存),則轉發給fallback

        }


        location @fallback {

                proxy_pass http://172.16.0.1; #反向代理到後端172.16.0.1處理請求

        }

}


配置php將它的會話(session)保存至memcached中


前提:

1、配置各php支持使用memcache;

2、安裝配置好memcached服務器,這裏假設其地址爲172.16.200.11,端口爲11211;


編輯php.ini文件,確保如下兩個參數的值分別如下所示:

  [root@node1 ~]# vim /etc/php.ini

session.save_handler = memcache

session.save_path = "tcp://192.168.139.2:11211?persistent=1&weight=1&timeout=1&retry_interval=15"


tcp://172.16.200.11:11211?是你的memcached服務器端的IP:port

?persistent=1 ?傳遞參數,persistent表示持久連接

timeout=1 超時時間爲1秒

retry_interval=15 重視時間爲15秒


新建php頁面setsess.php,爲客戶端設置啓用session:

[root@node1 ~]# vim /web/read/setsess.php 

<?php

session_start();

if (!isset($_SESSION['www.zxl.com'])) {

  $_SESSION['www.zxl.com'] = time();

}

print $_SESSION['www.zxl.com'];

print "<br><br>";

print "Session ID: " . session_id();

?>


新建php頁面showsess.php,獲取當前用戶的會話ID:

[root@node1 ~]# vim /web/read/showsess.php

<?php

session_start();

$memcache_obj = new Memcache;

$memcache_obj->connect('192.168.139.2', 11211);

$mysess=session_id();

var_dump($memcache_obj->get($mysess));

$memcache_obj->close();

?>


然後用瀏覽器分別訪問setsess.php和showsess.php

會看到session信息已近保存在了memcached中


安裝memcached的web界面管理工具memadmin

[root@node1 tool]#tar -xf memadmin-1.0.12.tar.gz 

[root@node1 tool]#mv memadmin /web/read/

[root@node1 tool]#cd /web/read/

  配置文件如下,可以修改用戶和密碼 

[root@node1 read]# vim memadmin/config.php 


<?php

if (!defined('IN_MADM')) exit();


$config['user'] = "admin"; // your username

$config['passwd'] = "admin"; // your password


然後你用瀏覽器就行web界面訪問http://192.18.139.2/memadmin


wKioL1hh1LDTxy2MAACgK3xdw5U965.png


wKioL1hh1QLDQ8nPAADI1K4PT0I139.png

wKiom1hh1R7Bm498AABa1T6CvjI291.png

wKioL1hh1TLRQXD_AAFNDoPUFvk626.png

可以看到memadmin已近安裝完成




爲編譯安裝的Memcached配置啓動腳本,Memcached SysV的startup腳本代碼如下所示,將其建立爲/etc/init.d/memcached文件:


[root@node1 ~]# vim /etc/init.d/memcached 

#!/bin/bash

#

# Init file for memcached

#

# chkconfig: - 86 14

# description: Distributed memory caching daemon

#

# processname: memcached

# config: /etc/sysconfig/memcached


. /etc/rc.d/init.d/functions


## Default variables

PORT="11211"

USER="nobody"

MAXCONN="1024"

CACHESIZE="64"

OPTIONS=""


RETVAL=0

prog="/usr/local/memcached/bin/memcached"

desc="Distributed memory caching"

lockfile="/var/lock/subsys/memcached"


start() {

        echo -n $"Starting $desc (memcached): "

        daemon $prog -d -p $PORT -u $USER -c $MAXCONN -m $CACHESIZE -o "$OPTIONS"

        RETVAL=$?

        echo

        [ $RETVAL -eq 0 ] && touch $lockfile

        return $RETVAL

}


stop() {

        echo -n $"Shutting down $desc (memcached): "

        killproc $prog

        RETVAL=$?

        echo

        [ $RETVAL -eq 0 ] && rm -f $lockfile

        return $RETVAL

}


restart() {

        stop

        start

}


reload() {

        echo -n $"Reloading $desc ($prog): "

        killproc $prog -HUP

        RETVAL=$?

        echo

        return $RETVAL

}


case "$1" in

  start)

        start

        ;;

  stop)

        stop

        ;;

  restart)

        restart

        ;;

  condrestart)

        [ -e $lockfile ] && restart

        RETVAL=$?

        ;;       

  reload)

        reload

        ;;

  status)

        status $prog

        RETVAL=$?

        ;;

   *)

        echo $"Usage: $0 {start|stop|restart|condrestart|status}"

        RETVAL=1

esac


exit $RETVAL



使用如下命令配置memcached成爲系統服務:

[root@node1 ~]# chmod +x /etc/init.d/memcached

[root@node1 ~]# chkconfig --add memcached

[root@node1 ~]# service memcached start

Starting Distributed memory caching (memcached):           [  OK  ]


本次實驗完成!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章