溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

搭建Memcache服務(wù)詳解

發(fā)布時(shí)間:2020-09-19 19:41:08 來源:網(wǎng)絡(luò) 閱讀:741 作者:筱振 欄目:系統(tǒng)運(yùn)維

博文大綱:
一、Memcache簡介
二、Memcache工作流程
三、Memcache調(diào)度算法
四、Memcache實(shí)現(xiàn)原理
五、安裝Memcache
(1)安裝nginx服務(wù)器
(2)安裝PHP服務(wù)器
(3)安裝MySQL數(shù)據(jù)庫
(4)測試PHP與Nginx、MySQL的連通性
(5)安裝Memcache服務(wù)器
(6)PHP服務(wù)器安裝Memcache客戶端
(7)使用 memcache 實(shí)現(xiàn) session 共享
(8)測試Memcache緩存數(shù)據(jù)庫

一、Memcache簡介

Memcache是一套自由、開源、高性能、分布式的高速緩存系統(tǒng)。由于Memcache通過在內(nèi)存中緩存數(shù)據(jù)和對(duì)象來減少讀取數(shù)據(jù)庫的次數(shù)。目前被許多網(wǎng)站使用以提升網(wǎng)站的訪問速度,尤其對(duì)于一些大型的、需要頻繁訪問數(shù)據(jù)庫的網(wǎng)站訪問速度提升效果十分顯著。

Memcache是一個(gè)存儲(chǔ)鍵值對(duì)的HashMap,在內(nèi)存中對(duì)任意的數(shù)據(jù)都可以使用key-value的方式存儲(chǔ),數(shù)據(jù)庫可以來自數(shù)據(jù)庫調(diào)用或API調(diào)用。Memcache設(shè)計(jì)理念就是小而強(qiáng)大,她簡單的設(shè)計(jì)促進(jìn)了快速部署、易于開發(fā)并解決大規(guī)模的數(shù)據(jù)緩存的許多難題,而其所開放的API使得Memcache能用于Java、C/C++/C#、Perl、Python等大部分流行的程序語言。

二、Memcache工作流程

注意Memcache雖然被稱為“分布式緩存”,但是Memcache本身完全不具備分布式的功能,Memcache集群之間不會(huì)相互通信,所謂的“分布式”,完全依賴于客戶端程序來實(shí)現(xiàn),如圖:
搭建Memcache服務(wù)詳解

Memcahe工作流程:
(1)應(yīng)用程序輸入需要寫入緩存的數(shù)據(jù);
(2)API將Key輸入路由算法模塊,理由算法根據(jù)Key和Memcache集群服務(wù)器列表得到服務(wù)器的編號(hào);
(3)由服務(wù)器編號(hào)得到Memcache及其IP地址和端口號(hào);
(4)API調(diào)用通信模塊和指定編號(hào)的服務(wù)器通信,講數(shù)據(jù)寫入該服務(wù)器,完成一次分布式緩存的寫操作;

不管是讀取緩存還是寫入緩存,只要使用相同的路由算法和服務(wù)器列表、應(yīng)用程序查詢的是相同的key,Memcache客戶端總是訪問相同的客戶端去讀取數(shù)據(jù),只要服務(wù)器緩存中還有該數(shù)據(jù)的緩存,就能保證緩存命中。

這種Memcache集群的方式也是從分區(qū)容錯(cuò)性的方面考慮的,假設(shè)Node2宕機(jī)了,那么Node2上存儲(chǔ)的數(shù)據(jù)都不可用了,此時(shí)由于集群中Node0和Node2還存在,下一次請(qǐng)求獲取Node2的緩存數(shù)據(jù),肯定是沒有命中的。這時(shí)首先會(huì)從數(shù)據(jù)庫中獲取到緩存的數(shù)據(jù),通過路由算法根據(jù)將緩存的數(shù)據(jù)存儲(chǔ)在Node0或Node1上,這種集群的做法很好,但是缺點(diǎn)是成本太大。

三、Memcache調(diào)度算法

Memcache共有兩種路由調(diào)度算法,分別是:余數(shù)Hash與一致性Hash。

(1)余數(shù)Hash

簡單的路由算法可以使用余數(shù)Hash:用服務(wù)器數(shù)目和緩存數(shù)據(jù)Key的hash值相除,余數(shù)為服務(wù)器列表中的服務(wù)器編號(hào)。由于HashCode隨機(jī)性比較強(qiáng),所以使用余數(shù)Hash路由算法就可以保證緩存數(shù)據(jù)在整個(gè)Memcache服務(wù)器集群中有比較均衡的分布。

如果不考慮服務(wù)器集群的伸縮性,那么余數(shù)Hash算法幾乎可以滿足絕大數(shù)的緩存路由器需求你,但是當(dāng)分布式緩存集群需要擴(kuò)容時(shí),就會(huì)出現(xiàn)很大的問題。

比如Memcache服務(wù)器集群由3臺(tái)變成4臺(tái),假設(shè)有HashCode為0~19的20個(gè)數(shù)據(jù),如圖:
3臺(tái)Memcache服務(wù)器環(huán)境:
搭建Memcache服務(wù)詳解
現(xiàn)在擴(kuò)容到4臺(tái)Memcache服務(wù)器:
搭建Memcache服務(wù)詳解
僅僅是擴(kuò)展到4臺(tái),原本緩存的數(shù)據(jù)就只可以命中6次,那么如果擴(kuò)容到20臺(tái)一行,只有前三個(gè)緩存中對(duì)應(yīng)的數(shù)據(jù)可以命中。通過以上舉例就可以說明:
使用余數(shù)Hash的路由算法,在擴(kuò)容的時(shí)候會(huì)造成大量的數(shù)據(jù)無法正確命中緩存。

在網(wǎng)站業(yè)務(wù)中,大部分的業(yè)務(wù)數(shù)據(jù)操作請(qǐng)求都會(huì)通過緩存來獲取的,只有少量的數(shù)據(jù)操作才會(huì)訪問數(shù)據(jù)庫,因此數(shù)據(jù)庫的負(fù)載能力是在有緩存為前提的情況下設(shè)計(jì)的。當(dāng)大部分緩存的數(shù)據(jù)因?yàn)镸emcache服務(wù)器的擴(kuò)容而不能正確讀取時(shí),這些數(shù)據(jù)訪問的壓力就落到了數(shù)據(jù)庫的身上,這將大大超過數(shù)據(jù)庫的負(fù)載能力,嚴(yán)重的情況還會(huì)造成數(shù)據(jù)庫宕機(jī)。

對(duì)于使用余數(shù)Hash算法的Memcache集群環(huán)境,需要擴(kuò)容時(shí),解決方案:

  • 在網(wǎng)站訪問量低谷,通常是深夜,技術(shù)團(tuán)隊(duì)加班、擴(kuò)容、重啟服務(wù)器;
  • 通過模擬請(qǐng)求的方式逐漸預(yù)熱緩存,使緩存服務(wù)器中的數(shù)據(jù)重新分布;

(2)一致性Hash

一致性Hash算法通過一個(gè)叫做一致性Hash環(huán)的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)key到緩存服務(wù)器的Hash映射,簡單來說,一致性Hash將整個(gè)Hash空間組織成一個(gè)虛擬的圓環(huán),假設(shè)某空間哈希函數(shù)H的值空間是0~2^32-1,那么整個(gè)Hash空間如圖:
搭建Memcache服務(wù)詳解

將各個(gè)服務(wù)器使用H進(jìn)行一個(gè)Hash計(jì)算,具體可以使用服務(wù)器的IP地址或主機(jī)名作為關(guān)鍵字,這樣每臺(tái)服務(wù)器都能確定其在上面的Hash環(huán)上的位置了,并且是按照順時(shí)針排序。

假設(shè)三臺(tái)Memcache經(jīng)計(jì)算后位置如下:
搭建Memcache服務(wù)詳解
接下來使用相同的算法計(jì)算出數(shù)據(jù)的哈希值,并由此確定數(shù)據(jù)在此哈希環(huán)上的位置,比如有四個(gè)數(shù)據(jù),經(jīng)過哈希計(jì)算后位置如下:
搭建Memcache服務(wù)詳解
根據(jù)一致性Hash算法,按照順時(shí)針找最近服務(wù)節(jié)點(diǎn)方法,這樣得到的Hash環(huán)調(diào)度方法,有很高的容錯(cuò)性和可擴(kuò)展性。

假設(shè)server03宕機(jī),就會(huì)出現(xiàn)以下情況:
搭建Memcache服務(wù)詳解
可以但看到此時(shí)C、B會(huì)收到影響,將B、C節(jié)點(diǎn)重定向到server01上。

在一致性Hash算法中,如果一臺(tái)服務(wù)器不可用時(shí),則受到影響的僅僅是此服務(wù)器按照順時(shí)針方向的第一臺(tái)服務(wù)器,其他服務(wù)器并不會(huì)受到影響。

假設(shè)在原本的環(huán)境中,再添加一臺(tái)服務(wù)器server04,就會(huì)出現(xiàn)以下情況:
搭建Memcache服務(wù)詳解
此時(shí),A、D、C都不會(huì)受到影響,只有B需要重定向到新的Server04。

在一致性Hash算法中,如果增加一臺(tái)服務(wù)器,則受影響的數(shù)據(jù)僅僅是新服務(wù)器按照順時(shí)針方向的第一臺(tái)服務(wù)器,其他并不會(huì)受到影響。

綜上所述,一致性Hash算法的優(yōu)缺點(diǎn):

  • 優(yōu)點(diǎn):對(duì)于節(jié)點(diǎn)的增減都只需重定位環(huán)空間的一部分?jǐn)?shù)據(jù),具有較好的容錯(cuò)行和可擴(kuò)展性;
  • 缺點(diǎn):在服務(wù)節(jié)點(diǎn)太少是,容器因?yàn)楣?jié)點(diǎn)分布均勻而造成數(shù)據(jù)傾斜問題。

當(dāng)然對(duì)于其缺點(diǎn),我們可以通過增加虛擬節(jié)點(diǎn)的方式來解決。

總之就是:集群中的緩存服務(wù)器節(jié)點(diǎn)越多,增加、減少節(jié)點(diǎn)的影響越??;隨著集群規(guī)模的增大,繼續(xù)命中原有緩存數(shù)據(jù)的概率會(huì)越來越大,雖然仍有小部分?jǐn)?shù)據(jù)緩存服務(wù)器中不能被讀取,但是比例相對(duì)來說,較小。即使訪問數(shù)據(jù)庫,也不會(huì)對(duì)數(shù)據(jù)庫產(chǎn)生致命的負(fù)載壓力。

四、Memcache實(shí)現(xiàn)原理

Memcache的特點(diǎn):

  • 訪問數(shù)據(jù)庫的速度比傳統(tǒng)的關(guān)系型數(shù)據(jù)庫要快(因?yàn)镸emcache是存放在內(nèi)存中的,而傳統(tǒng)的關(guān)系型數(shù)據(jù)庫是存放在磁盤中);
  • Memcache的數(shù)據(jù)存放在內(nèi)存中,就意味著只要Memcache重啟,數(shù)據(jù)便會(huì)丟失。
  • 由于現(xiàn)在大部分都是64位操作系統(tǒng),這里就不介紹內(nèi)存對(duì)32位系統(tǒng)的影響了;

Memcache的原理:最重要的就是內(nèi)存如何分配,Memcache采用的內(nèi)存分配方式是固定空間分配的,如圖:
搭建Memcache服務(wù)詳解
圖中主要設(shè)計(jì)到了stab_class、slab、page、chunk四個(gè)概念,四者的關(guān)系:
(1)Memcache將內(nèi)存空間分為一組slab;
(2)每個(gè)slab下又有若干個(gè)page,每個(gè)page默認(rèn)是1M,如果一個(gè)slab占用100M內(nèi)存的話,那么這個(gè)slab下應(yīng)該有100個(gè)page;
(3)每個(gè)page里面包含一組chunk,chunk是真正存放數(shù)據(jù)的地方,同一個(gè)slab里面的chunk的大小是固定的;
(4)有相同大小chunk的slab被組織在一起,稱為slab_class;

Memcache內(nèi)存分配的方式稱為allocator(分配運(yùn)算),slab的數(shù)量是有限的,幾個(gè)、十幾個(gè)或者幾十個(gè),這個(gè)和啟動(dòng)參數(shù)的配置相關(guān);

Memcache中的value存放的地方是由value的大小決定的,value總是會(huì)存放到與chunk大小最接近的一個(gè)slab中。

如果這個(gè)slab中沒有chunk可以分配了怎么辦?如果Memcache啟動(dòng)沒有追加“-M”,那么Memcache會(huì)把這個(gè)slab中最近最少使用的chunk中的數(shù)據(jù)清理掉,然后放上最新的數(shù)據(jù)。

1.Memcache的工作流程

如圖:
搭建Memcache服務(wù)詳解
1、檢查客戶端的請(qǐng)求數(shù)據(jù)是否在 memcached 中,如果有,直接把請(qǐng)求數(shù)據(jù)返回,不再對(duì)數(shù)據(jù)庫進(jìn)行任何操作,路徑操作為①②③⑦;
2、如果請(qǐng)求的數(shù)據(jù)不在 memcached 中,就去查數(shù)據(jù)庫,把從數(shù)據(jù)庫中獲取的數(shù)據(jù)返回給客戶端,同時(shí)把數(shù)據(jù)緩存一份到 memcached 中(memcached 客戶端不負(fù)責(zé),需要程序明確實(shí)現(xiàn)),路徑操作為①②④⑤⑦⑥;
3、每次更新數(shù)據(jù)庫的同時(shí)更新 memcached 中的數(shù)據(jù),保證一致性;
4、當(dāng)分配給 memcached 內(nèi)存空間用完之后,會(huì)使用 LRU(Least Recently Used,最近最少使用)策略加上到期失效策略,失效數(shù)據(jù)首先被替換,然后再替換掉最近未使用的數(shù)據(jù);

2.Memcached的特征

協(xié)議簡單:

  • 基于文本行的協(xié)議,直接通過 telnet 在 memcached 服務(wù)器上可進(jìn)行存取數(shù)據(jù)操作;
  • 基于 libevent 事件處理;
  • 所有數(shù)據(jù)都保存在內(nèi)存中,存取數(shù)據(jù)比硬盤快,當(dāng)內(nèi)存滿后,通過 LRU 算法自動(dòng)刪除不使用的緩存,但沒有考慮數(shù)據(jù)的容災(zāi)問題,重啟服務(wù),所有數(shù)據(jù)會(huì)丟失;
    分布式:
  • 各個(gè) memcached 服務(wù)器之間互不通信,各自獨(dú)立存取數(shù)據(jù),不共享任何信息。服務(wù)器并不具有分布式功能,分布式部署取決于 memcache 客戶端。

五、安裝Memcache

Memcache 的安裝分為兩個(gè)過程:memcache 服務(wù)器端的安裝和 memcached 客戶端的安裝。所謂服務(wù)器端的安裝就是在服務(wù)器(一般都是 linux 系統(tǒng))上安裝 Memcache 實(shí)現(xiàn)數(shù)據(jù)的存儲(chǔ)。

所謂客戶端的安裝就是指 php(或者其他程序,Memcache 還有其他不錯(cuò)的 api 接口提供)去使用服務(wù)器端的 Memcache 提供的函數(shù),需要 php 添加擴(kuò)展。

由此可以看出Memcache的搭建需要借助于LAMP或LNMP,本篇博文采用LNMP結(jié)構(gòu)。

安裝環(huán)境:
搭建Memcache服務(wù)詳解

(1)安裝nginx服務(wù)器

下載Nginx軟件包

關(guān)于安裝Nginx的詳細(xì)介紹可以參考Nginx深度優(yōu)化(二),那么這里就不多做解釋了!

[root@Nginx ~]# useradd -M -s /sbin/nologin nginx
[root@Nginx ~]# yum -y install openssl-devel
[root@Nginx ~]# tar zxf pcre-8.39.tar.gz -C /usr/src
[root@Nginx ~]# tar zxf zlib-1.2.8.tar.gz -C /usr/src
[root@Nginx ~]# tar zxf nginx-1.14.0.tar.gz -C /usr/src
[root@Nginx ~]# cd /usr/src/nginx-1.14.0/
[root@Nginx nginx-1.14.0]# ./configure --prefix=/usr/local/nginx \
--user=nginx --group=nginx --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=/usr/src/pcre-8.39 --with-zlib=/usr/src/zlib-1.2.8 \
--with-http_ssl_module --with-http_gzip_static_module && make && make install
[root@Nginx ~]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin
[root@Nginx ~]# nginx
[root@Nginx ~]# netstat -anpt | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      8460/nginx: master  

(2)安裝PHP服務(wù)器

下載PHP軟件包

關(guān)于PHP的安裝詳細(xì)介紹可以參考部署LAMP動(dòng)靜分離以及部署Discuz論壇這里就不多做解釋了!

[root@PHP ~]# yum -y install openssl-devel libxml2-devel bzip2-devel libcurl-devel
[root@PHP ~]# tar zxf libmcrypt-2.5.7.tar.gz -C /usr/src
[root@PHP ~]# cd /usr/src/libmcrypt-2.5.7/
[root@PHP libmcrypt-2.5.7]# ./configure --prefix=/usr/local/libmcrypt && make && make install
[root@PHP ~]# tar zxf php-5.6.27.tar.gz -C /usr/src
[root@PHP ~]# cd /usr/src/php-5.6.27/
[root@PHP php-5.6.27]# ./configure --prefix=/usr/local/php \
--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-libxml-dir=/usr --enable-xml --with-mhash --with-zlib \
--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
[root@PHP ~]# cp /usr/src/php-5.6.27/php.ini-production /etc/php.ini
[root@PHP ~]# cp /usr/src/php-5.6.27/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
[root@PHP ~]# chmod +x /etc/init.d/php-fpm 
[root@PHP ~]# chkconfig --add php-fpm
[root@PHP ~]# cd /usr/local/php/etc/
[root@PHP etc]# cp php-fpm.conf.default php-fpm.conf
[root@PHP etc]# sed -i 's#;pid = run/php-fpm.pid#pid = run/php-fpm.pid#g' php-fpm.conf
[root@PHP etc]# sed -i 's/listen = 127.0.0.1:9000/listen = 0.0.0.0:9000/g' php-fpm.conf
[root@PHP etc]# sed -i 's/pm.max_children = 5/pm.max_children = 50/g' php-fpm.conf
[root@PHP etc]# sed -i 's/pm.start_servers = 2/pm.start_servers = 5/g' php-fpm.conf
[root@PHP etc]# sed -i 's/pm.min_spare_servers = 1/pm.min_spare_servers = 5/g' php-fpm.conf
[root@PHP etc]# sed -i 's/pm.max_spare_servers = 3/pm.max_spare_servers = 35/g' php-fpm.conf
[root@PHP ~]# systemctl start php-fpm  
[root@PHP ~]# netstat -anpt | grep 9000  
tcp        0      0 0.0.0.0:9000            0.0.0.0:*               LISTEN      118146/php-fpm: mas 

(3)安裝MySQL數(shù)據(jù)庫

提供一鍵安裝MySQL軟件及腳本

[root@Mysql ~]# ls
anaconda-ks.cfg  initial-setup-ks.cfg  mysql-5.7.22-linux-glibc2.12-x86_64.tar.gz  mysql.sh
[root@Mysql ~]# sh mysql.sh 
Starting MySQL.. SUCCESS! 
[root@Mysql ~]# mysql -u root -p123
mysql> create database testdb1;
mysql> use testdb1;
mysql> grant all on *.* to lzj@'192.168.1.%' identified by '123456';
mysql> create table test1(id int not null auto_increment,name varchar(20) default null,primary  key (id)) engine=innodb auto_increment=1 default charset=utf8;
mysql> insert into test1(name) values ('tom1'),('tom2'),('tom3'),('tom4'),('tom5');
mysql> select * from test1;
+----+------+
| id | name |
+----+------+
|  1 | tom1 |
|  2 | tom2 |
|  3 | tom3 |
|  4 | tom4 |
|  5 | tom5 |
+----+------+
//創(chuàng)建數(shù)據(jù)庫,及添加數(shù)據(jù)并創(chuàng)建授權(quán)用戶

(4)測試PHP與Nginx、MySQL的連通性

Nginx服務(wù)器的操作:

[root@Nginx ~]# vim /usr/local/nginx/conf/nginx.conf

        location / {
            root   html;
            index  index.php index.html index.htm;
        }

        location ~ \.php$ {
            root           /var/www/html;
            fastcgi_pass   192.168.1.6:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            include        fastcgi.conf;
        }
[root@Nginx ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@Nginx ~]# nginx -s reload

PHP服務(wù)器的操作:

[root@PHP ~]# mkdir -p /var/www/html
[root@PHP ~]# vim /var/www/html/test.php
<?php
phpinfo();
?>
[root@PHP ~]# vim /var/www/html/test1.php
<?php
$link=mysqli_connect('192.168.1.8','lzj','123456');
if($link) echo "恭喜你,數(shù)據(jù)庫連接成功?。?!"; else echo "connect shibai";
mysqli_close($link);
?>

客戶端訪問測試:

搭建Memcache服務(wù)詳解
搭建Memcache服務(wù)詳解

客戶端訪問測試,確保沒有問題!

(5)安裝Memcache服務(wù)器

下載Memcache軟件包

[root@Memcache ~]# tar zxf libevent-2.0.22-stable.tar.gz -C /usr/src
[root@Memcache ~]# cd /usr/src/libevent-2.0.22-stable/
[root@Memcache libevent-2.0.22-stable]# ./configure && make && make install
//安裝Memcache依賴軟件包
[root@Memcache ~]# tar zxf memcached-1.4.33.tar.gz -C /usr/src
[root@Memcache ~]# cd /usr/src/memcached-1.4.33/
[root@Memcache memcached-1.4.33]# ./configure --prefix=/usr/local/memcached \
--with-libevent=/usr/local/ && make && make install
[root@Memcache ~]# ln -s /usr/local/memcached/bin/memcached /usr/local/bin
[root@Memcache ~]# memcached -d -m 2048 -l 192.168.1.7 -p 11211 -c 10240 -P /usr/local/memcached/memcached.pid -u root
[root@Memcache ~]# netstat -anpt | grep 11211
tcp        0      0 192.168.1.7:11211       0.0.0.0:*               LISTEN      10886/memcached   

啟動(dòng)Memcache常用參數(shù)說明如下:

  • -d:啟動(dòng)一個(gè)守護(hù)進(jìn)程;
  • -m:分配給 Memcache 使用的內(nèi)存數(shù)量,單位是 MB,默認(rèn) 64MB;
  • -l:監(jiān)聽的 IP 地址;(默認(rèn):INADDR_ANY,所有地址)
  • -p:設(shè)置 Memcache 的 TCP 監(jiān)聽的端口,最好是 1024 以上的端口;
  • -u:運(yùn)行 Memcache 的用戶,如果當(dāng)前為 root 的話,需要使用此參數(shù)指定用戶;
  • -c:最大運(yùn)行的并發(fā)連接數(shù),默認(rèn)是 1024;
  • -P:設(shè)置保存 Memcache 的 pid 文件路徑;
  • -M:內(nèi)存耗盡時(shí)返回錯(cuò)誤,而不是刪除項(xiàng);
  • -f:塊大小增長因子,默認(rèn)是 1.25;
  • -n:最小分配空間,key+value+flags 默認(rèn)是 48;
  • -h:顯示幫助;

(6)PHP服務(wù)器安裝Memcache客戶端

[root@PHP ~]# scp 192.168.1.7:/root/memcache-3.0.8.tgz .
[root@PHP ~]# tar zxf memcache-3.0.8.tgz -C /usr/src
[root@PHP ~]# cd /usr/src/memcache-3.0.8/
[root@PHP memcache-3.0.8]# /usr/local/php/bin/phpize
//生成configure文件
//若在執(zhí)行上述命令時(shí)報(bào)錯(cuò),則需要執(zhí)行“yun -y install autoconf "安裝提示的autoconf包
[root@PHP memcache-3.0.8]# ./configure --enable-memcache \
--with-php-config=/usr/local/php/bin/php-config && make && make install
//執(zhí)行后會(huì)顯示memcache.so存放的路徑
[root@PHP ~]# echo "extension = /usr/local/php/lib/php/extensions/no-debug-zts-20131226/memcache.so" >> /etc/php.ini
//在PHP主配置文件中填寫memcache.so模塊存放的路徑
[root@PHP ~]# systemctl restart php-fpm
[root@PHP ~]# vim /var/www/html/test2.php
<?php
$memcache = new Memcache;
$memcache->connect('192.168.1.7', 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, 600) or die ("Failed to save data at the server");
echo "Store data in the cache (data will expire in 600 seconds)<br/>";
$get_result = $memcache->get('key');
echo "Data from the cache:<br/>";
var_dump($get_result);
?>
//此測試腳本是顯示memcached的版本
//并且向里面插入了一個(gè)緩存時(shí)間為600秒的鍵值對(duì)“test=123”,其ID為“key”

客戶段訪問如下:
搭建Memcache服務(wù)詳解

在PHP服務(wù)器上安裝telnet工具測試

[root@PHP ~]# yum -y install telnet
[root@PHP ~]# telnet 192.168.1.7 11211           //登陸到memcached的11211端口
Trying 192.168.1.7...
Connected to 192.168.1.7.
Escape character is '^]'.
get key              //查詢ID為“key”的鍵值對(duì),可以看到我們測試腳本寫入的“test=123”
VALUE key 1 66
O:8:"stdClass":2:{s:8:"str_attr";s:4:"test";s:8:"int_attr";i:123;}
END
//在進(jìn)行上面的get驗(yàn)證時(shí),需要將test2.php文件中插入的鍵值對(duì)的保存時(shí)間值改大一些
//或者重新訪問一下,以免緩存失效,查詢不到
quit                     //退出當(dāng)前環(huán)境
Connection closed by foreign host.
[root@PHP ~]# 

(7)使用 memcache 實(shí)現(xiàn) session 共享

在PHP服務(wù)器上進(jìn)行以下操作:

[root@PHP ~]# vim /etc/php.ini 
//編寫PHP主配置文件,并在末尾添加以下內(nèi)容
session.save_handler = memcache
session.save_path = "tcp://192.168.1.7:11211?persistent=1&weight=1&timeout=1&retry_interval=15"
[root@PHP ~]# systemctl restart php-fpm
[root@PHP ~]# vim /var/www/html/test3.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 />";
?>

PHP配置文件中寫入的內(nèi)容解釋如下:

  • session.save_handler:設(shè)置 session 的儲(chǔ)存方式為 memcache ;
  • 默認(rèn)以文件方式存取 session數(shù)據(jù);
  • session.save_path: 設(shè)置 session 儲(chǔ)存的位置;
  • 使用多個(gè) memcached server 時(shí)用逗號(hào)”,”隔開,可以帶額外的參數(shù)”persistent”、”weight”、”timeout”、”retry_interval”等等;
  • 類似這樣的:"tcp://host:port?persistent=1&weight=2,tcp://host2:port2";

客戶端訪問如下:
搭建Memcache服務(wù)詳解
搭建Memcache服務(wù)詳解
搭建Memcache服務(wù)詳解

[root@PHP ~]# telnet 192.168.1.7 11211
Trying 192.168.1.7...
Connected to 192.168.1.7.
Escape character is '^]'.
get a8aujbnie16p29rj4pf9ltfjp3                   //使用網(wǎng)頁出現(xiàn)的server_id號(hào),來獲取其對(duì)應(yīng)的值
VALUE a8aujbnie16p29rj4pf9ltfjp3 0 26
session_time|i:1576329213;
END
quit
Connection closed by foreign host.
[root@PHP ~]# 

(8)測試Memcache緩存數(shù)據(jù)庫

由于步驟3創(chuàng)建數(shù)據(jù)庫時(shí),就已經(jīng)在數(shù)據(jù)庫中寫入了測試所用的值,接下來就是創(chuàng)建測試腳本就可以了!

PHP服務(wù)器的操作:

[root@PHP ~]# vim /var/www/html/test4.php 
<?php
$memcachehost = '192.168.1.7';                      //指定Memcache服務(wù)器地址
$memcacheport = 11211;                                 //指定其開放的端口號(hào)
$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.8","lzj","123456");                        //指定數(shù)據(jù)庫服務(wù)器的IP地址、用戶及密碼
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><font color=#FF0000>$a[id]</font></b>";
echo "<br>";
echo "name is <b><font color=#FF0000>$a[name]</font></b>";                    //突出顯示信息的字體顏色
echo "<br>";
}
?>
//經(jīng)常需要修改的地方已經(jīng)標(biāo)注了!而且這個(gè)測試腳本在Memcache軟件中也有

客戶端進(jìn)行測試:
第一次進(jìn)行訪問
搭建Memcache服務(wù)詳解
第二次進(jìn)行訪問(刷新之后)
搭建Memcache服務(wù)詳解

在緩存過期之前,也可使用get來獲取緩存所對(duì)應(yīng)的值:

[root@PHP ~]# telnet 192.168.1.7 11211
Trying 192.168.1.7...
Connected to 192.168.1.7.
Escape character is '^]'.
get d8c961e9895ba4b463841924dbcefc2b
VALUE d8c961e9895ba4b463841924dbcefc2b 0 251
a:5:{i:0;a:2:{s:2:"id";s:1:"1";s:4:"name";s:4:"tom1";}i:1;a:2:{s:2:"id";s:1:"2";s:4:"name";s:4:"tom2";}i:2;a:2:{s:2:"id";s:1:"3";s:4:"name";s:4:"tom3";}i:3;a:2:{s:2:"id";s:1:"4";s:4:"name";s:4:"tom4";}i:4;a:2:{s:2:"id";s:1:"5";s:4:"name";s:4:"tom5";}}
END

—————————本文到此結(jié)束,感謝觀看——————————

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI