
nginx连接memcached
首先确保nginx能正常连接php
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 确保能够正常运行
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成功连接到了memcache
mysql中建好表
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 user
第一次访问 http://xx.xx.xx.xx/user2.html 的时候,如果数据库已经有了
from mysql query
Array([ui]=>2 [uname]=>zhangsan )
然后储存到memceched
再次访问
得到
zhangsan
如果有多态memcached,某个key去请求哪个memcached?PHP又帮nginx把内容存储到哪个mem?
以.user2.html为例 a b c d e 5 台server,请求谁?
第三方模块编译及一致性哈希应用
如果有多态memcached,某个key去请求哪个memcached?PHP又帮nginx把内容存储到哪个mem?
以.user2.html为例 a b c d e 5 台server,请求谁?
总体思路:
请求的时候通过hash(uri),存储的时候也通过hash(uri)
下载 第三方模块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的集群与负载均衡算法.