Nginx網絡架構實戰學習筆記(四):nginx鏈接memcached、第三方模塊編譯及一致性哈希應用

nginx鏈接memcached

在這裏插入圖片描述
首先確保nginx能正常鏈接phpphp

location ~ \.php$ {
            root html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            //這裏的document_root是上面定義的root html
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
}

訪問 http://xx.xx.xx.xx/test.php 確保可以正常運行html

cd nginx
vi ../fastphp/lib/php.ini
//搜索memecache,若是沒有就編譯擴展
cd /usr/local/src/
//在php已經安裝好的狀況下,如何添加擴展?
tar xvf memcache-2.2.7.tar
cd memcache-2.2.7
ls
//發現configure都沒有,該如何編譯呢?
//指定想對哪一個php來編譯(fastphp)
/usr/local/fastphp/bin/phpize
ls
//發現有了configure
./configure --help
//指定php config的地址
./configure --with-php-config=/usr/local/fastphp/bin/php-config
make && make install
cd /usr/local/fastoho/
vim lib/php.ini
//搜索.so
//修改以下
extension = /usr/local/fastphp/lib/php/extendions/no-debug-non-zts-10100525/memcache.so

//殺一下php進程 ,pkill 是根據名字殺的意思
pkill -9 php
//啓動php
./sbin/php-fpm
cd /usr/local/nginx/
vim test.php
 	phpinfo();

訪問 http://xx.xx.xx.xx/test.php ,由於會輸出phpinfo,因此在頁面中查看是否有memcache,說明php成功鏈接到了memcachemysql

mysql中建好表nginx

mysql -uroot -p
use test
show tables 
Tables_in_test

select * from user
vim cong/nginx.cong
	locaction /{
		//設置查找memchached的key
		set $memcheched_key "$uri?args"
		//拿到key以後去哪臺服務器找
		memcached_pass 127.0.0.1:11211;
		//若是是404的話,回調
		error_page 404 /callback.php
		
	}

vim html/callback.php
	<?php
	//將請求的基本信息打印出來,發現是有請求的地址信息的
	//print_r($_SERVER);
	//得到uri,用來當key
	$uri = $_SERVER['REQUEST_URI'];
	//分析出user2345.html中的uid
	$uid = substr($uri,5,strpos($uri,'.')-5);
	//echo $uid;
	//鏈接數據庫,查詢並寫入memcached
	$connn=mysql_connect('localhost','root','');
	$sql = 'use test';
	mysql_query($sql,$conn);
	$sql  = 'set names utf8';
	mysql_query($sql,$conn);
	$sql = 'select * from user where uid'.$uid;
	$rs = mysql_query($sql,$conn);
	echo 'from mysql query</br>'
	$user=mysql_fetch——assoc($rs);
	if(empty($user)){
		echo 'no this user';
	}else{
		//print_r($user);
		$html = '<h1>'.$user['uname'].'</h1>';
		echo $html;
		$mem = new memcache();
		$mem->connect('localhost',11211);
		$mem->add($uri,$html,0,300);
		#mem->close();
	}
	
	
./sbin/nginx -s reload
telnet localhost 11211
//注意這裏有/
add /user1.html 0 0 7 
iamlisi

訪問http://xx.xx.xx.xx/user1.html ,會輸出iamlisi
訪問 http://xx.xx.xx.xx/user2.html , 由於沒有這個頁面,本應該輸出404,可是上面設置若是請求404,就回調PHP,輸出from mysql quesry no thos usergit

第一次訪問 http://xx.xx.xx.xx/user2.html 的時候,若是數據庫已經有了
from mysql query
Array([ui]=>2 [uname]=>zhangsan )
而後儲存到memceched
再次訪問
獲得
zhangsangithub

若是有多態memcached,某個key去請求哪一個memcached?PHP又幫nginx把內容存儲到哪一個mem?
以.user2.html爲例 a b c d e 5 臺server,請求誰?web

第三方模塊編譯及一致性哈希應用

若是有多態memcached,某個key去請求哪一個memcached?PHP又幫nginx把內容存儲到哪一個mem?
以.user2.html爲例 a b c d e 5 臺server,請求誰?算法

整體思路:
請求的時候經過hash(uri),存儲的時候也經過hash(uri)sql

下載 第三方模塊ngx_httpo_consistent_hash(github上直接下載)數據庫

cd /usr/local/src
wget xxxxxxxx(模塊地址)
unzip xxxxxxxx
cd /usr/local/src/nginx-1.4.2
./conffigure --help | grep with
./conffigure --help | grep moudle
./configure --prefix=/usr/local/nginx/ --add-module=usr/local/src/ngx_http_consistent_hash-master
Make && make instal

以ngx_http_php_memcache_standard_balancer-master爲例
1:解壓 到 path/ngx_module
配置:
./configure --prefix=/xxx/xxx --add_module=/path/ngx_module
編譯 安裝
Make && make instal
配置memcache集羣

安裝了memcached模塊就能夠在nginx裏面用了

upstream memserver {  把用到的memcached節點,聲明在一個組裏
        hash_key $request_uri;  // hash計算時的依據,以uri作依據來hash
        //這裏不寫localhost用具體的ip 
        server 192.168.xx.xx:11211;
        server 192.168.xx.xx:11212;
}
Location裏
location / {
           # root   html;
           set $memcached_key $uri;
           memcached_pass memserver;  // memserver爲上面的memcache節點的名稱
           error_page 404 /writemem.php;
           index  index.php index.html index.htm;
 }

啓動memcached

/usr/local/memcached/bin/memcached -u nodody -vv -p 11211
/usr/local/memcached/bin/memcached -u nodody -vv -p 11212

這個時候訪問 xx.xx.xx.xx/user4.html
經過查看memcached日誌,發現會規定的去一個memcached訪問,假如是11211但是第一次沒有查到結果,將請求傳給上節中的callback.php,php往11212中存儲,修改callback.php

<?php
	//將請求的基本信息打印出來,發現是有請求的地址信息的
	//print_r($_SERVER);
	//得到uri,用來當key
	$uri = $_SERVER['REQUEST_URI'];
	//分析出user2345.html中的uid
	$uid = substr($uri,5,strpos($uri,'.')-5);
	//echo $uid;

	//添加多臺服務器
	$mem = new memcached();
	//這裏不用localhost用ip
	$mem->addServer('192.168.xx.xx',11211);
	$mem->addServer('192.168.xx.xx',11212);

	//鏈接數據庫,查詢並寫入memcached
	$connn=mysql_connect('localhost','root','');
	$sql = 'use test';
	mysql_query($sql,$conn);
	$sql  = 'set names utf8';
	mysql_query($sql,$conn);
	$sql = 'select * from user where uid'.$uid;
	$rs = mysql_query($sql,$conn);
	echo 'from mysql query</br>'
	$user=mysql_fetch——assoc($rs);
	if(empty($user)){
		echo 'no this user';
	}else{
		//print_r($user);
		$html = '<h1>'.$user['uname'].'</h1>';
		echo $html;
		//$mem = new memcache();
		//$mem->connect('localhost',11211);
		$mem->add($uri,$html,0,300);
		#mem->close();
	}

但是仍是有問題的,memcached請求的和經過php存儲的不是一個,由於nginx用的是一致性hash,php是用的簡單的算數法,取模法

經過查閱資料 memcached_hash_strategy (memcached hash策略)=========》standard 默認就是取模法 ,能夠改爲consistant,改爲以後php對memcached就會使用一致性hash

修改:

vi /usr/local/fastphp/lib/php.ini
//添加下面這句話
memcached_hash_strategy=consistent
//重啓nginx
pkill -9 php -fpm
/usr/local/fastphp/sbin/php-fpm

經過查看memcached日誌,11211 是get(第一次查的時候),11211也是add(經過php往裏面加的時候),以前是11211 是get(第一次查的時候),11212是add(經過php往裏面加的時候)

注意上面的nginx的配置和callback.php中的ip寫成ip,不要寫成localhost

至此達到了一致性。

總結


在nginx中作集羣與負載均衡,步驟都是同樣的
Upstream {}模塊 把多臺服務器加入到一個組
而後 memcached_pass, fastcgi_pass, proxy_pass ==> upstream組

默認的負載均衡的算法:
是設置計數器,輪流請求N臺服務器.
能夠安裝第3方模式,來利用uri作hash等等.

如http://wiki.nginx.org/NginxHttpUpstreamConsistentHash
這個模塊就是用一致性hash來請求後端結節,而且其算法,與PHP中的memcache模塊的一致性hash算法,兼容.

安裝該模塊後:
Nginx.conf中

upstream memserver {
   	//將傳遞過來的uri當作hash的參數,經過hash算法,判斷請求落在下面那個服務器上
        consistent_hash $request_uri;
        server localhost:11211;
        server localhost:11212;
    }

在PHP.ini中,以下配置

memcache.hash_strategy = consistent

這樣: nginx與PHP便可完成對memcached的集羣與負載均衡算法.

相關文章
相關標籤/搜索