1. 程式人生 > >第十六周微職位:Memcached,haproxy,varnish

第十六周微職位:Memcached,haproxy,varnish

第十六周微職位:memcached varnish haproxy

1、為LNMP架構添加memcached支持,並完成對緩存效果的測試報告;

一、Memcached的簡介:

Memcached是一個自由開源的,高性能,分布式內存對象緩存系統。它是一種基於內存的key-value存儲,用來存儲小塊的任意數據(字符串、對象)。這些數據可以是數據庫調用、API調用或者是頁面渲染的結果。

Memcached簡潔而強大。它的簡潔設計便於快速開發,減輕開發難度,解決了大數據量緩存的很多問題。它的API兼容大部分流行的開發語言。本質上,它是一個簡潔的key-value存儲系統。

一般的使用目的是,通過緩存數據庫查詢結果,減少數據庫訪問次數,以提高動態Web應用的速度、提高可擴展性。

特征:

1)協議簡單;

2)基於libevent的事件處理;

3)內置內存存儲方式;

4)memcached不互相通信的分布式。

Memcached常用選項:

-l <ip_addr>:監聽的地址
-m <num>:緩存空間大小,單位為MB, 默認為64
-c <num>:最大並發連接數,默認為1024
-M:緩存空間耗盡時,向請求者返回錯誤信息,而不是基於LRU算法進行緩存清理
-f <factor>:growth factor, 增長因子
-t <threads>:處理用於請求的線程數

二 基於LNMP架構添加Memcached支持並驗證其結果

1、結構示意圖:

技術分享

2. 實驗環境

IP 功用

192.168.237.129 nginx

192.168.237.131 php-fpm+mariadb+memcached

3. 實驗步驟

Nginx, PHP-FPM和MariaDB安裝在此忽略。

(1) Memcached安裝

#安裝Memcached
yum -y install memcached
#啟動Memcached
memcached -d -m 1024 -u memcached

連接測試

telnet 192.168.237.131 11211

技術分享


查看Memcached信息

技術分享

(2) 安裝PHP的Memcached的擴展

php連接memcached服務的模塊有兩個,php-pecl-memcache和php-pecl-memcached.若要安裝php-pecl-memcached需要依賴libmemcached程序包,可以提供相應操作查看memcached的工具。在這裏為方便演示就直接使用php-pecl-memcache擴展模塊。

#安裝PHP的Memcached擴展模塊
yum -y install php-pecl-memcache

測試PHP是否已支持Memcached, 瀏覽器中輸入http://192.168.237.129/index.php

(3) 測試Memcached緩存

#在nginx根目錄下寫入php測試腳本
vim /usr/share/nginx/html/test.php
<?php
$mem = new Memcache;
$mem->connect("192.168.237.131", 11211); #連接Memcached

$version = $mem->getVersion();
echo "Server‘s version: ".$version."<br/>\n"; #輸出Memcached版本信息

$mem->set(‘testkey‘, ‘Hello World‘, 0, 600); #向Memcached存儲數據‘Hello World‘,時間為600s
echo "Store data in the cache (data will expire in 600 seconds)<br/>\n";

$get_result = $mem->get(‘testkey‘); #獲取testkey的值
echo "$get_result is from memcached server.";
?>

測試Memcached緩存結果,在瀏覽器中輸入192.168.237.129/test.php

技術分享

可以看出緩存已生效,再查看Memcached相應信息

技術分享


2、部署配置haproxy,能夠實現將來自用戶的80端口的http請求轉發至後端8000上的server服務,寫出其配置過程。

Haproxy的安裝:(也可通過源碼安裝)

yum -y install haproxy

修改基本的配置文件如下:

配置文件所在地址: /etc/haproxy/haproxy.cfg

 global   
    maxconn 5120      
    chroot /usr/share/haproxy      
    daemon      
    quiet      
    nbproc 2      
    pidfile /usr/share/haproxy/haproxy.pid      
defaults      
    option  httplog      
    option  dontlognull      
    timeout connect 5s      
    timeout client 50s      
    timeout server 20s      
listen http      
    bind :80      
    timeout client 1h      
    tcp-request inspect-delay 2s       
    tcp-request content accept if is_http      
    server server-http :8080      
backend servers     
    server server1 127.0.0.1:8080 maxconn 32


3、闡述varnish的功能及其應用場景,並通過實際的應用案例來描述配置、測試、調試過程。


先安裝varnish

#yum -y install varnish
配置文件的簡單介紹


NFILES=131072                
MEMLOCK=82000    
NPROCS="unlimited"    
# DAEMON_COREFILE_LIMIT="unlimited"        #內核最大打開的文件數    
RELOAD_VCL=1                               #是否自動加載VCL    
VARNISH_VCL_CONF=/etc/varnish/default.vcl  #默認加載的VCL文件    
VARNISH_LISTEN_PORT=80                     #監聽端口,默認為6081    
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1     #管理的IP地址    
VARNISH_ADMIN_LISTEN_PORT=6082             #管理端口    
VARNISH_SECRET_FILE=/etc/varnish/secret    #密鑰文件    
VARNISH_MIN_THREADS=50                     #最小線程數量    
VARNISH_MAX_THREADS=1000                   #最大線程數量  
VARNISH_THREAD_TIMEOUT=120                 #線程超時時間    
VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin #緩存文件位置    
VARNISH_STORAGE_SIZE=1G                    #設置文件緩存大小變量    
VARNISH_MEMORY_SIZE=64M                    #設置內存緩存大小變量    
#VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}" #默認存儲到文件中,這裏可以修改存儲位置    
VARNISH_STORAGE="malloc,${VARNISH_MEMORY_SIZE}" #設置緩存位置為內存    
VARNISH_TTL=120                    
DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \    
             -f ${VARNISH_VCL_CONF} \    
             -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \    
             -t ${VARNISH_TTL} \    
             -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \    
             -u varnish -g varnish \    
             -S ${VARNISH_SECRET_FILE} \    
             -s ${VARNISH_STORAGE}"    #所有啟動加載選項

啟動服務如下:

# service varnish start

Varnish命令介紹

# varnishd -h    
-a address:port        #表示varnish對httpd的監聽地址及其端口    
-b address:port        #表示後端服務器地址及其端口    
-d                     #表示使用debug調試模式    
-f file                #指定varnish服務器的配置文件    
-p param=value         #指定服務器參數,用來優化varnish性能    
-P file                #Varnish進程PID文件存放路徑    
-n dir                 #指定varnish的工作目錄    
-s kind[,storageoptions] #指定varnish緩存內容的存放方式,常用的方式有:“-s file,<dir_or_file>,<size>”;其中“<dir_or_file>”    
                          指定緩存文件的存放路徑,“<size>”指定緩存文件的大小    
-t                     #指定默認的TTL值    
-T address:port        #設定varnish的telnet管理地址及其端口    
-V                     #顯示varnish版本號和版權信息    
-w int[,int[,int]]     #設定varnish的工作線程數,常用的方式有:  -w min,max    
 -w min,max,timeout    
如:-w3,25600,50       #這裏最小啟動的線程數不能設定過大,設置過大,會導致varnish運行異常緩慢
環境如下:

技術分享

在lamp1、lamp2上分別都安裝服務並啟動
######在Lamp1服務器上安裝Httpd、Php、Mysql,啟動服務    
# yum -y install httpd php mysql-server php-mysql    
# service httpd start    
# service mysqld start    
------------------------------------------------------------------------    
######在Lamp2服務器上安裝Httpd、Php,啟動服務    
# yum -y install httpd php php-mysql    
# service httpd start


lamp上都測試php界面

安裝論壇程序:

# mysql    
mysql> create database bbs;    
mysql> grant all on bbs.* to ‘bbsuser‘@‘172.16.%.%‘ identified by ‘bbspass‘;    
mysql> flush privileges;    
註釋:為論壇創建一個數據庫並授權用戶訪問    
------------------------------------------------------------------------    
######安裝論壇程序    
# unzip Discuz_X3.0_SC_UTF8.zip    
# cp -rf upload/* /var/www/html/    
# chmod -R +w /var/www/html/{config,data,uc_server,uc_client}    #添加可寫權限    
# chown -R apache /var/www/html/*      #修改屬主權限

技術分享

將論壇程序拷貝到lamp2服務器上一份並訪問測試

# scp -rp /var/www/html/* 172.16.14.3:/var/www/html/

# service httpd restart #重啟lamp2服務器的WEB服務

安裝web服務器並測試頁面:

# yum -y install httpd

# service httpd start

# echo "<h1>WEB</h1>" > /var/www/html/index.html #創建測試頁

技術分享

將Lamp1服務器上的論壇程序拷貝到WEB服務器一份,因為需要論壇中的一些靜態文件如:(.jpg|.html)結尾的文件等

# scp -rp /var/www/html/* 172.16.14.3:/var/www/html/


Varnish安裝及配置

在第一部分中我們已經修改過默認監聽端口為"80",接下來為Varnish提供一個VCL配置文件,建議基於默認的配置文件基礎上修改,修改前

備份一下文件。

[[email protected] ~]# cd /etc/varnish/

[[email protected] varnish]# cp default.vcl default.vcl.bak

[[email protected] varnish]# vim default.vcl

######定義ACL

acl purgers { #定義acl,實現IP地址過濾

"127.0.0.1";

"172.16.0.0"/16;

}

######定義健康狀態檢測

probe dynamic { #設置動態網站服務器健康狀態檢測

.url = "/index.html";

.interval = 5s;

.timeout = 1s;

.expected_response = 200;

} #這裏設置了兩個健康狀態檢測主要是為了區分動、靜網站

probe static { #設置動態網站服務器健康狀態檢測

.url = "/index.html"; #定義檢測的頁面

.interval = 5s; #探測請求的發送周期,默認為5秒

.timeout = 1s; #每次探測請求的過期時間

.expected_response = 200;

}

######定義後端服務器

backend app1 { #定義一個後端服務器

.host = "172.16.14.2"; #服務器地址

.port = "80"; #服務器監聽端口

.probe = dynamic; #健康狀態檢測

}

backend app2 {

.host = "172.16.14.3";

.port = "80";

.probe = dynamic;

}

backend web {

.host = "172.16.14.4";

.port = "80";

.probe = static;

}

######定義後端服務器組,實現負載均衡效果

director apps random { #定義一個後端服務器組,實現負載均衡效果

{

.backend = app1; #調用前面已定義過的後端主機

.weight = 2; #設置權重

}

{

.backend = app2;

.weight = 2;

}

}

######定義vcl_recv函數,實現請求到達並成功接收後調用此函數中定義的規則

sub vcl_recv {

######定義動、靜分離,以".php"或".php?後面跟所有文件"結尾的請求都發送到動態服務器,其他請求都發送到靜態服務器

if (req.url ~ "\.php(\?\.*|$)") {

set req.backend = apps;

} else {

set req.backend = web;

}

return(lookup);

######定義允許清除緩存的IP地址,調用的是前面定義的ACL

if (req.request == "PURGE") {

if (!client.ip ~ purgers) {

error 405 "Method not allowed";

}

return(lookup);

}

######重新定義http請求首部,讓後端服務器可以記錄請求客戶端的真實IP地址

if (req.restarts == 0) {

if (req.http.x-forwarded-for) {

set req.http.X-Forwarded-For =

req.http.X-Forwarded-For + ", " + client.ip;

} else {

set req.http.X-Forwarded-For = client.ip;

}

}

######除了定義的請求方法外,其他請求都到後端服務器

if (req.request != "GET" &&

req.request != "HEAD" &&

req.request != "PUT" &&

req.request != "POST" &&

req.request != "TRACE" &&

req.request != "OPTIONS" &&

req.request != "DELETE") {

return (pipe);

}

if (req.request != "GET" && req.request != "HEAD") {

return (pass);

}

######定義不緩存認證與Cookie信息

if (req.http.Authorization || req.http.Cookie) {

return (pass);

}

######定義壓縮功能

if (req.http.Accept-Enconding) {

if (req.url ~ "\.(jpg|jpeg|gif|bmp|png|flv|gz|tgz|tbz|mp3)$") {

remove req.http.Accept-Encoding;

remove req.http.Cookie;

} else if (req.http.Accept-Encoding ~ "gzip") {

set req.http.Accept-Encoding = "gzip";

} else if (req.http.Accept-Encoding ~ "deflate") {

set req.http.Accept-Encoding = "deflate";

} else { remove req.http.Accept-Encoding;

}

}

######定義指定格式結尾的文件去除Cookie信息

if (req.request == "GET" && req.url ~ "\.(jpeg|jpg|gif|png|bmp|swf)$") {

unset req.http.cookie;

}

######定義防盜鏈設置

if (req.http.referer ~ "http://.*") {

if (!(req.http.referer ~ "http://.*\.baidu\.com" || req.http.referer ~"http://.*\.google\.com.*")) {

set req.http.host = "www.allen.com";

set req.url = "http://172.16.14.4/error.html";

}

}

}

######定義vcl_hash函數

sub vcl_hash {

hash_data(req.url);

if (req.http.host) {

hash_data(req.http.host);

} else {

hash_data(server.ip);

}

return(hash);

}

######定義vcl_hit函數

sub vcl_hit {

if (req.request == "PURGE") { #語法方法為"PURGE"

purge; #清除緩存

error 200 "Purged."; #返回錯誤狀態碼為"200"

}

return(deliver);

}

######定義vcl_miss函數

sub vcl_miss {

if (req.request == "PURGE") {

purge;

error 404 "Not In Cache.";

}

return(fetch);

}

######定義vcl_psss函數

sub vcl_pass {

if (req.request == "PURGE") {

error 502 "Purged On A Passed Object.";

}

return(pass);

}

######定義vcl_fetch函數

sub vcl_fetch {

######定義緩存,如果匹配到已定義文件結尾的緩存1天,其他則緩存1小時

if (req.request == "GET" && req.url ~ "\.(html|jpg|png|bmp|jpeg|gif|js|ico|swf|css)$") {

set beresp.ttl = 1d;

set beresp.http.expires = beresp.ttl;

} else {

set beresp.ttl = 1h;

}

return(deliver);

}

######定義在http首部中,如果請求命中顯示"HIT",未命中則顯示"MISS"

sub vcl_deliver {

if (obj.hits > 0) {

set resp.http.X-Cache = "HIT";

} else {

set resp.http.X-Cache = "MISS";

}

}

----------------------------------------------------------------------

[[email protected] ~]# service varnish restart #重啟服務生效,重啟服務器後所有緩存將被清除,當然也可以不用重啟服務使其生效,如下:

----------------------------------------------------------------------

[[email protected] ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082

varnish> help #獲取幫助

varnish> vcl.load acl_1 default.vcl #加載acl文件,acl_1為配置名稱

200

VCL compiled.

varnish> vcl.list #查看加載的acl文件列表

200

active 7 boot

available 0 acl_1

varnish> vcl.use acl_1 #應用acl文件

200

varnish> quit #退出

------------------------------------------------------------------------

註釋: -S:指定varnish的密鑰文件 -T:指定varnish服務器地址及管理端口,默認端口為"6082"

服務驗證:

壓力測試,如下:

######後端服務器不經過緩存測試

[[email protected] ~]# ab -c 100 -n 1000 http://172.16.14.2/index.php

Concurrency Level: 1000

Time taken for tests: 6.812 seconds

Complete requests: 10000

Failed requests: 0

Write errors: 0

Non-2xx responses: 10051

Total transferred: 2281577 bytes

HTML transferred: 0 bytes

Requests per second: 1468.04 [#/sec] (mean) #每秒請求並發

Time per request: 681.179 [ms] (mean)

Time per request: 0.681 [ms] (mean, across all concurrent requests)

Transfer rate: 327.10 [Kbytes/sec] received

----------------------------------------------------------------------

######經過緩存測試

[[email protected] ~]# ab -c 1000 -n 10000 http://172.16.14.1/index.php

Concurrency Level: 1000

Time taken for tests: 2.594 seconds

Complete requests: 10000

Failed requests: 0

Write errors: 0

Non-2xx responses: 10056

Total transferred: 3117360 bytes

HTML transferred: 0 bytes

Requests per second: 3855.05 [#/sec] (mean)

Time per request: 259.400 [ms] (mean)

Time per request: 0.259 [ms] (mean, across all concurrent requests)

Transfer rate: 1173.59 [Kbytes/sec] received

----------------------------------------------------------------------

註釋:從上面數據中可以看出,經過緩存做壓力測試並發量高

測試緩存是否能命中

[[email protected] ~]# curl -I http://172.16.14.1/index.php

HTTP/1.1 301 Moved Permanently

Server: Apache/2.2.15 (CentOS)

X-Powered-By: PHP/5.3.3

location: forum.php

Content-Type: text/html; charset=UTF-8

Content-Length: 0

Accept-Ranges: bytes

Date: Thu, 05 Oct 2017 09:48:01 GMT

X-Varnish: 2142028839

Age: 0

Via: 1.1 varnish

Connection: keep-alive

X-Cache: MISS #第一次請求,未命中顯示"MISS"

------------------------------------------------------------------------

[[email protected] ~]# curl -I http://172.16.14.1/index.php

HTTP/1.1 301 Moved Permanently

Server: Apache/2.2.15 (CentOS)

X-Powered-By: PHP/5.3.3

location: forum.php

Content-Type: text/html; charset=UTF-8

Content-Length: 0

Accept-Ranges: bytes

Date: Thu, 05 Oct 2017 09:48:15 GMT

X-Varnish: 2142028841 2142028839

Age: 7

Via: 1.1 varnish

Connection: keep-alive

X-Cache: HIT #第二次請求,命中則顯示"HIT"


驗證動、靜分離的效果:

技術分享

從上圖中可以看出,提供靜態頁面的服務停止後,所有圖片都不能顯示,當然把服務再啟動起來就可以訪問正常了,這裏就不在測試了…

驗證健康狀態檢測

技術分享


查看緩存命中率狀態;命中率的高低

技術分享


本文出自 “11822904” 博客,請務必保留此出處http://11832904.blog.51cto.com/11822904/1970415

第十六周微職位:Memcached,haproxy,varnish